Skip to content

Commit c807277

Browse files
authored
Fix case mismatching modules during namespace package search (#11261)
For example `from a import B` should not find a namespace package `a/b/`. Fix by using case aware isdir on fscache.
1 parent 8749901 commit c807277

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

mypy/fscache.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,14 @@ def isfile_case(self, path: str, prefix: str) -> bool:
220220
res = False
221221
if res:
222222
# Also recursively check the other path components in case sensitive way.
223-
res = self._exists_case(head, prefix)
223+
res = self.exists_case(head, prefix)
224224
self.isfile_case_cache[path] = res
225225
return res
226226

227-
def _exists_case(self, path: str, prefix: str) -> bool:
228-
"""Helper to check path components in case sensitive fashion, up to prefix."""
227+
def exists_case(self, path: str, prefix: str) -> bool:
228+
"""Return whether path exists - checking path components in case sensitive
229+
fashion, up to prefix.
230+
"""
229231
if path in self.exists_case_cache:
230232
return self.exists_case_cache[path]
231233
head, tail = os.path.split(path)
@@ -242,7 +244,7 @@ def _exists_case(self, path: str, prefix: str) -> bool:
242244
res = False
243245
if res:
244246
# Also recursively check other path components.
245-
res = self._exists_case(head, prefix)
247+
res = self.exists_case(head, prefix)
246248
self.exists_case_cache[path] = res
247249
return res
248250

mypy/modulefinder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ def _find_module(self, id: str, use_typeshed: bool) -> ModuleSearchResult:
373373

374374
# In namespace mode, register a potential namespace package
375375
if self.options and self.options.namespace_packages:
376-
if fscache.isdir(base_path) and not has_init:
376+
if fscache.exists_case(base_path, dir_prefix) and not has_init:
377377
near_misses.append((base_path, dir_prefix))
378378

379379
# No package, look for module.

test-data/unit/check-modules-case.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
-- Type checker test cases dealing with modules and imports on case-insensitive filesystems.
22

33
[case testCaseSensitivityDir]
4+
# flags: --no-namespace-packages
5+
from a import B # E: Module "a" has no attribute "B"
6+
7+
[file a/__init__.py]
8+
[file a/b/__init__.py]
9+
10+
[case testCaseSensitivityDirNamespacePackages]
11+
# flags: --namespace-packages
412
from a import B # E: Module "a" has no attribute "B"
513

614
[file a/__init__.py]

0 commit comments

Comments
 (0)