python / python/mypy

Mypy isn't discovering all modules in namespace packages with multiple __path__ components

Offen
#16,683 1 Kommentar 4 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug Report

It seems that mypy isn't considering all parts of namespace package paths, and is only checking the sources corresponding to the first path in its path.

Hopefully the example below clarifies it. I searched quite a bit in the bug tracker/docs, but didn't find anything describing my scenario, so apologies if it's a dupe!

To Reproduce

Consider the following hierarchy

./pkg_a
./pkg_a/foo
./pkg_a/foo/module1.py
./pkg_a/foo/py.typed
./pkg_b
./pkg_b/foo
./pkg_b/foo/py.typed
./pkg_b/foo/module2.py

foo.module1 and foo.module2 simply contain a bit of code to demonstrate mypy error detection:

$ cat ./pkg_a/foo/module1.py
trigger_mypy_error: str = 123
$ cat ./pkg_b/foo/module2.py
trigger_mypy_error: str = 123

Just as expected, we have a namespace package, both modules are imported without issues:

$ PYTHONPATH=pkg_b:pkg_a python3 -c 'import foo; print(foo.__path__); import foo.module1; import foo.module2'
_NamespacePath(['/project/for_mypy_bugtracker/pkg_b/foo', '/project/for_mypy_bugtracker/pkg_a/foo'])

Actual Behavior

When type checking, mypy only detects module2.py and misses module1.py:

$ MYPYPATH=pkg_b:pkg_a mypy --namespace-packages --strict -p foo
pkg_b/foo/module2.py:1: error: Incompatible types in assignment (expression has type "int", variable has type "str")  [assignment]
    trigger_mypy_error: str = 123
                              ^~~
Found 1 error in 1 file (checked 2 source files)

Seems that the only sources detected are from pkg_b:

MYPYPATH=pkg_b:pkg_a mypy --namespace-packages -p foo -v 2>&1 | grep BuildSource
LOG:  Found source:           BuildSource(path='pkg_b/foo', module='foo', has_text=False, base_dir=None, followed=False)
LOG:  Found source:           BuildSource(path='pkg_b/foo/module2.py', module='foo.module2', has_text=False, base_dir=None, followed=False)

I dug a bit and I suspect it has something to do with this line
https://github.com/python/mypy/blob/1dd8e7fe654991b01bd80ef7f1f675d9e3910c3a/mypy/modulefinder.py#L559 -- the result of finding the module is just one path (pkg_b in this case), so it doesn't have a chance to explore pkg_a.

Expected Behavior

Mypy should detect both foo.module1 and foo.module2

Your Environment

  • Mypy version used: 1.7.1 (latest)
  • Python version used: 3.10

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne in mypy/modulefinder.py rund um die referenzierte Zeile und reproduziere dann das Problem mit der pkg_a/pkg_b-Hierarchie und dem Befehl MYPYPATH=pkg_b:pkg_a mypy --namespace-packages --strict -p foo. Als erledigt gilt die Aufgabe, wenn die Quellcodeerkennung beide Namespace-Package-Komponenten einschließt und die Typprüfung Fehler aus module1.py und module2.py meldet.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
devtools
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Klar beschrieben
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.