Skip to content

Commit

Permalink
Don't read scripts without extensions as modules in namespace mode (#…
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
getim committed Jan 10, 2023
1 parent 2475643 commit e965275
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 1 deletion.
6 changes: 5 additions & 1 deletion mypy/modulefinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,11 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult:

# In namespace mode, register a potential namespace package
if self.options and self.options.namespace_packages:
if fscache.exists_case(base_path, dir_prefix) and not has_init:
if (
not has_init
and fscache.exists_case(base_path, dir_prefix)
and not fscache.isfile_case(base_path, dir_prefix)
):
near_misses.append((base_path, dir_prefix))

# No package, look for module.
Expand Down
Empty file.
Empty file.

0 comments on commit e965275

Please sign in to comment.