Skip to content

Commit e965275

Browse files
authored
Don't read scripts without extensions as modules in namespace mode (#14335)
The `FindModuleCache` currently matches files without an extension when `--namespace_packages` is enabled while [the docs](https://mypy.readthedocs.io/en/stable/running_mypy.html#mapping-file-paths-to-modules) don't mention that this should be the case. The "near-miss" logic collects candidates for modules, which could correctly include a _directory_ `foo/bar/baz` when looking for `foo/bar/baz`. However, the current logic also picks up a _file_ `foo/bar/baz`. This means that, if both a file `foo/bar/baz` and `foo/bar/baz.py` exist, the first one is actually picked, resulting in unexpected behaviour. The condition that checks `exists_case` on `foo/bar/baz` should also check that it is indeed a directory by checking that it is not a file. I'm open to different fixes of course, but this seemed like the most obvious and least impactful change to make. This PR modifies 2 tests: * add `test-data/packages/modulefinder/pkg1/a` to verify that `ModuleFinderSuite.test__no_namespace_packages__find_a_in_pkg1` is indeed working correctly even without the patch because it's not running in namespace mode. * add `test-data/packages/modulefinder/nsx-pkg3/nsx/c/c`, making `ModuleFinderSuite.test__find_nsx_c_c_in_pkg3` fail, which the patch fixes. To give one real-world example of this scenario: Bazel's Python rules construct a wrapper-script with the same name as the main Python-file without the extension for a `py_binary`-target. If some other Python rule depends on this `//foo/bar:baz` `py_binary`-target, it sees both `foo/bar/baz` and `foo/bar/baz.py` in the same directory, incorrectly picking up the wrapper-script instead of the module. Dependencies on a `py_binary` might be a bit of an edge-case, but Python execution of these targets does pick up the right file, so Mypy should probably as well.
1 parent 2475643 commit e965275

File tree

3 files changed

+5
-1
lines changed

3 files changed

+5
-1
lines changed

mypy/modulefinder.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,11 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult:
507507

508508
# In namespace mode, register a potential namespace package
509509
if self.options and self.options.namespace_packages:
510-
if fscache.exists_case(base_path, dir_prefix) and not has_init:
510+
if (
511+
not has_init
512+
and fscache.exists_case(base_path, dir_prefix)
513+
and not fscache.isfile_case(base_path, dir_prefix)
514+
):
511515
near_misses.append((base_path, dir_prefix))
512516

513517
# No package, look for module.

test-data/packages/modulefinder/nsx-pkg3/nsx/c/c

Whitespace-only changes.

test-data/packages/modulefinder/pkg1/a

Whitespace-only changes.

0 commit comments

Comments
 (0)