From bcfc72aec4f86b3b4ae7aa161a6353403e4fc6d7 Mon Sep 17 00:00:00 2001 From: nightcityblade Date: Sun, 11 Oct 2026 00:51:19 +0800 Subject: [PATCH] Fix discovery beside same-named namespace directories --- mypy/find_sources.py | 12 ++++++++---- mypy/test/test_find_sources.py | 12 ++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/mypy/find_sources.py b/mypy/find_sources.py index e1edebe90985b..5afedbb1099a1 100644 --- a/mypy/find_sources.py +++ b/mypy/find_sources.py @@ -110,7 +110,7 @@ def is_explicit_package_base(self, path: str) -> bool: def find_sources_in_dir(self, path: str) -> list[BuildSource]: sources = [] - seen: set[str] = set() + seen_file_stems: set[str] = set() names = sorted(self.fscache.listdir(path), key=keyfunc) for name in names: # Skip certain names altogether @@ -128,12 +128,16 @@ def find_sources_in_dir(self, path: str) -> list[BuildSource]: if self.fscache.isdir(subpath): sub_sources = self.find_sources_in_dir(subpath) if sub_sources: - seen.add(name) + if any( + self.fscache.isfile(os.path.join(subpath, "__init__" + suffix)) + for suffix in PY_EXTENSIONS + ): + seen_file_stems.add(name) sources.extend(sub_sources) else: stem, suffix = os.path.splitext(name) - if stem not in seen and suffix in PY_EXTENSIONS: - seen.add(stem) + if stem not in seen_file_stems and suffix in PY_EXTENSIONS: + seen_file_stems.add(stem) module, base_dir = self.crawl_up(subpath) sources.append(BuildSource(subpath, module, None, base_dir)) diff --git a/mypy/test/test_find_sources.py b/mypy/test/test_find_sources.py index 321f3405e9991..b8eddec884d42 100644 --- a/mypy/test/test_find_sources.py +++ b/mypy/test/test_find_sources.py @@ -220,6 +220,18 @@ def test_find_sources_in_dir_namespace(self) -> None: ("f", "/pkg/a1/b"), ] + def test_find_sources_in_same_named_file_and_namespace_dir(self) -> None: + options = Options() + finder = SourceFinder(FakeFSCache({"/pkg/x.py", "/pkg/x/y.py"}), options) + + assert find_sources_in_dir(finder, "/pkg") == [("x", "/pkg"), ("y", "/pkg/x")] + + def test_find_sources_in_same_named_file_and_package_dir(self) -> None: + options = Options() + finder = SourceFinder(FakeFSCache({"/pkg/x.py", "/pkg/x/__init__.py"}), options) + + assert find_sources_in_dir(finder, "/pkg") == [("x", "/pkg")] + def test_find_sources_in_dir_namespace_explicit_base(self) -> None: options = Options() options.namespace_packages = True