[red-knot] Module resolver has incorrect behaviour if a single-file module and potential namespace package coexist #12278
Closed
Description
opened on Jul 10, 2024
The following test should pass, but fails:
diff --git a/crates/red_knot_module_resolver/src/resolver.rs b/crates/red_knot_module_resolver/src/resolver.rs
index 71b807871..5decee0c6 100644
--- a/crates/red_knot_module_resolver/src/resolver.rs
+++ b/crates/red_knot_module_resolver/src/resolver.rs
@@ -1140,4 +1140,21 @@ mod tests {
system_path_to_file(&db, stdlib.join("functools.pyi"))
);
}
+
+ #[test]
+ fn single_file_takes_priority_over_namespace_package() {
+ const SRC: &[FileSpec] = &[("foo.py", "x = 1"), ("foo/bar.py", "x = 2")];
+
+ let TestCase { db, src, .. } = TestCaseBuilder::new().with_src_files(SRC).build();
+
+ let foo_module_name = ModuleName::new_static("foo").unwrap();
+ let foo_bar_module_name = ModuleName::new_static("foo.bar").unwrap();
+
+ // `foo.py` takes priority over the `foo` directory;
+ // `foo.bar` isn't recognised as a module:
+ let foo_module = resolve_module(&db, foo_module_name.clone()).unwrap();
+ let foo_path = src.join("foo.py");
+ assert_eq!(&foo_path, foo_module.file().path(&db));
+ assert_eq!(resolve_module(&db, foo_bar_module_name.clone()), None);
+ }
}
At runtime, Python considers that a foo
module exists and considers that a foo.bar
module does not exist (it does not view the foo
module as a package, as the foo.py
file takes priority over the foo
directory). The red-knot module resolver currently has the opposite understanding: it believes that there is no module foo
, and that there is a module foo.bar
.
Activity