Treat variable, declared global and assigned a value in a class or function, as a member of the module.
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start from the module import and name-analysis behavior illustrated in the issue, then review the proposed breadth-first module traversal for assignments to global names. Validate the result against the X.py/Y.py example: assigned y1 and y3 imports should succeed, while unassigned y0, y2, and y4 imports should fail.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100