python / python/mypy

Issue inferring type with circular imports/future annotations

Offen
#12,874 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

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

Beschreibung

Hey! I ran into something which I think is a bug, although its a very small use case and can be fixed pretty easily. This is my first time reporting an issue so let me know if I need to supply anything more info, or if this isn't actually a bug

Bug Report

using future annotations with this circular import seems to cause issues with recognizing types

To reproduce:

create the following structure:

src
 ├──my_directory
     ├── __init__.py
     ├──a.py
 ├──__init__.py
 ├──b.py

with the following code in the files:

src/my_directory/init.py:

from .a import OBJECT_FACTORY, Object

src/my_directory/a.py

from .. import b

class Object():
    pass

class ObjectFactory:
    def make_object(self) -> Object:
        pass

OBJECT_FACTORY = ObjectFactory()

src/init.py

# empty file

src/b.py

from __future__ import annotations
from . import my_directory

def func(bar: Bar):
    print(bar.object)

class Bar:
    def __init__( 
        self,
        _: str, # if you delete this type annotation there will no longer be an error
    ):
        self.object = my_directory.OBJECT_FACTORY.make_object()

then run:
mypy src

Expected Behavior:

Should be able to infer that the type of bar.object is Object from the type annotation of the make_object method.

Actual Behavior

src/b.py:5: error: Cannot determine type of "object"
Found 1 error in 1 file (checked 4 source files)

Some interesting behaviors:

  • if you delete the str type annotation in the Bar class, mypy passes with no issues
  • defining func after Bar class passes with no issues
  • deleting the 'from .. import b' in a.py passes with no issues
  • using a static function make_object with the same annotation instead of in OBJECT_FACTORY will pass with no issues
  • running mypy src/b.py instead of mypy src will pass with no issues
    • subsequently, now running mypy src will actually pass without issues (likely due to .mypy_cache, deleting the cache will re-instate the bug)
  • you can fix this issue if you add the type annotation my_directory.Object to self.object in class Bar
My Environment:

mypy --version

mypy 0.960 (compiled: yes)

python --version

Python 3.8.6

  • Mypy command-line flags: no flags
  • OS: Windows 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

Reproduzieren Sie den Bericht mit den Dateien unter src/my_directory/a.py, src/b.py und den init.py-Dateien des Pakets und führen Sie anschließend mypy src mit entferntem Cache aus. Vergleichen Sie das Verhalten, wenn die Konstruktorannotation, der zirkuläre Import oder future annotations geändert werden. Als erledigt gilt die Aufgabe, wenn das gemeldete Beispiel bar.object als Object inferiert, ohne eine redundante Annotation hinzuzufügen, und weiterhin keine Fehler meldet.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
tooling
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

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