python / python/mypy

Lazy circular import with bottom import cannot determine type if the module name is alphabetically after the base class module

Aperta
#18,734 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

bug topic-import-cycles
Lingua principale
Python
Stelle
20.6k
Fork
3.3k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

To Reproduce

mkdir mypyissue
cd mypyissue
touch __init__.py a.py b.py c.py circular.py py.typed

a.py:

import typing_extensions as t
from .b import Base
class A(Base):
    def run(self) -> None:
        t.reveal_type(self._v)

b.py:

import typing as t
class Base:
    def __init__(self, v: t.Optional[str] = None) -> None:
        from .circular import circular
        self._v: t.Final = v or circular.v
from .a import A
from .c import C

c.py:

import typing_extensions as t
from .b import Base
class C(Base):
    def run(self) -> None:
        t.reveal_type(self._v)

circular.py

from .b import Base
class Circular:
    @property
    def v(self) -> str:
        return "value"
circular = Circular()

Expected Behavior

self._v to have the correct type for all children. Or at least consistently fail rather than now where somehow the module name matters.

Actual Behavior

c.py:5: error: Cannot determine type of "_v"  [has-type]
c.py:5: note: Revealed type is "Any"
a.py:5: note: Revealed type is "builtins.str"
Found 1 error in 1 file (checked 5 source files)

Notice that a.py has the correct type but not c.py.

Your Environment

  • Mypy version used: mypy 1.15.0 (compiled: yes)
  • Mypy command-line flags: Nothing
  • Mypy configuration options from mypy.ini (and other config files): Nothing
  • Python version used: 3.9.19

Additional notes

  • Pyright works in this case.
  • The first character of the file name is important. In this case, since Base is in b.py, any module named after b alphabetically (i.e., c, d, e, etc...) will fail to determine the type but not a.py. E.g., if b.py was instead d.py, then both a.py and c.py will have the correct type.
  • The bottom imports and the Base import in circular.py are needed to reproduce this. If removed, this works.

Workaround

Explicitly add the type:

self._v: t.Final[str] = v or circular.v

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Riproduci il problema usando i file a.py, b.py, c.py e circular.py elencati con mypy 1.15.0, quindi confronta i tipi inferiti per A e C. Traccia la gestione degli import circolari e dei bottom import responsabile della differenza alfabetica; il lavoro è completato quando entrambe le classi figlie inferiscono _v in modo coerente oppure falliscono in modo coerente, con una copertura di regressione per l’esempio.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
devtools
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
45/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.