Skip to content

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

Open
@mrolle45

Description

@mrolle45

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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions