python / python/mypy

spurious used-before-def on admittedly odd wildcard import

Offen
#14,668 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug topic-possibly-undefined
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
Ø Merge
1 T. 18 Std.
Gemergte PRs (30 T.)
54

Beschreibung

Bug Report

When using wildcard imports and modifying the import module-level variables, mypy will detect a undef-before-use of imported module-level variables. This is an admittedly weird bit of code, but crops up, for example, in some kinds of Django settings.py refactorings people do.

To Reproduce

This bug unfortunately requires two files to reproduce, so I have to inline them here.
Executing last.py will get you correct output, but mypy will claim there's a undef-before-use.

# first.py
A_VALUE: str = "in first"
# last.py
from first import *
# from first import A_VALUE

A_VALUE += " in last"  # comment either this, or the next line, or uncomment the import above for the mypy check to pass
A_VALUE = "in last again " + A_VALUE

if __name__ == "__main__":
    print(A_VALUE)

Expected Behavior
The expected behavior would be a successful pass, I believe.

Actual Behavior

Running PYTHONPATH=. mypy last.py will get you:

last.py:3: error: Name "A_VALUE" is used before definition  [used-before-def]
Found 1 error in 1 file (checked 1 source file)

For context, running PYTHONPATH=. python3 last.py will show the expected output of in last again in first in last.

Interestingly, both A_VALUE updates in last.py are necessary for mypy to call out a used-before-def. And if you explicitly import the module-level variable, mypy passes successfully, too. We've seen this behavior with a .index and a += method call on a List before a =, so we don't believe it's something specific to str or +=.

Your Environment

  • Mypy version used: 1.0.0
  • Mypy command-line flags: N/A
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.10.9 and 3.8.14

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

Reproduziere den Bericht mit first.py und last.py mithilfe von PYTHONPATH=. mypy last.py, vergleiche dann den Wildcard-Import mit dem expliziten Import und mit dem Entfernen eines der beiden Updates. Verfolge, wie Namen aus Wildcard-Imports die Prüfung auf Verwendung vor der Definition erreichen; abgeschlossen ist die Aufgabe, wenn das Zwei-Dateien-Beispiel ohne Unterdrückung der Diagnose erfolgreich ist und das bestehende Verhalten erhalten bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
compilers, devtools
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.