python / python/mypy

Treat variable, declared global and assigned a value in a class or function, as a member of the module.

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

Dieses Issue hat noch niemand übernommen.

feature topic-runtime-semantics topic-variable-scope
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Feature

If a global variable is created solely via an assignment in a class or function to a name declared as global, then treat that name as though that assignment was at module level.
Currently, importing of such a name reports an error.

As a related matter, if the name is annotated at the module level, but there is no assignment, treat that name as missing from the module.

Pitch

This will reflect the runtime behavior.

Mypy will have to assume that the assignment might or might not occur, just like if an assignment at module level is located in a conditional block. In the latter case, the type may be inferred from the first assignment that is seen, and later assignments can check for compatible types.

I propose that mypy treat all assignments to global variables be treated like at module level, for purpose of establishing the existence and types of module level variables. The order that the assignments are analyzed should be in a breadth-first traversal of class and function defs (i.e. process an entire body excluding nested bodies, then process these bodies).

You may want to label this as a bug?.

I am working on writing such breadth-first module traverser which will identify all names in all scopes in a file and where they are first assigned. It will handle assigns to variables declared global just as though they appeared at module level. So that will take care of this proposed feature, as well as other issues with local names that are referenced before they are assigned.

Here's an example:

X.py:

from Y import y1, y2, y3, y4

Y.py:

global y0
y0: float
y2: str
def f():
	global y1, y2
	y1 = 1
class C:
	global y3, y4
	y3 = 3

Output from mypy:

X.py:3:1: error: Module "Y" has no attribute "y1"
X.py:3:1: error: Module "Y" has no attribute "y3"
X.py:3:1: error: Module "Y" has no attribute "y4"

The imports of y1 and y3 should succeed. The imports of y0, y2 and y4 should fail because no assignment appears anywhere. mypy is correct for y4 but incorrect for the others.

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

Beginnen Sie mit dem im Issue veranschaulichten Verhalten beim Modulimport und bei der Namensanalyse und prüfen Sie anschließend die vorgeschlagene Breitensuche zur Modultraversierung auf Zuweisungen an globale Namen. Validieren Sie das Ergebnis anhand des Beispiels X.py/Y.py: Die Importe der zugewiesenen y1 und y3 sollten erfolgreich sein, während die Importe der nicht zugewiesenen y0, y2 und y4 fehlschlagen sollten.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

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