Does not catch variable declared global/nonlocal after appearing in the same scope.
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
If a program references a variable and then declares it global or nonlocal, mypy does not catch this.
To Reproduce
foo.py:
x = 'x'
from typing import TYPE_CHECKING
def foo() -> None:
x = 42
global x
if TYPE_CHECKING: reveal_type(x)
print(x)
foo()
$ mypy foo.py
foo.py:8: note: Revealed type is 'builtins.str'
$ python3 foo.py
File "foo.py", line 7
global x
^
SyntaxError: name 'x' is assigned to before global declaration
Expected Behavior
mypy should report the error on line 7.
This applies to any other usage of 'x',
- except
(x): int(with no assignment)
which is not a syntax error, as it is not a name binding for 'x'.
When you fix mypy to catch these syntax errors, be sure and take this into account. The only difference between(x): intandx: intis in the value ofast3.AnnAssign.simple= 0 and 1, resp.ast3.AnnAssign.simple= 0 in both cases if there is an assignment.
Actual Behavior
No error (see above).
Suggestion
I would guess that the fix belongs in the semantic analyzer. When it encounters a global or nonlocal declaration, it should know that the variable name has already been used or bound.
Don't forget to check for ast3.AnnAssign.simple = 1 and not consider the variable to be bound, or even used, in this case.
Note that ast3.AnnAssign.target is an ast3.Name instance, and ast3.AnnAssign.target.expr_context is an ast3.Store instance. This is a bug in the parser. It should be ast3.Load(), or better yet, None, since the variable is not really used at all.
Your Environment
- Mypy version used: 0.761
- Python version used: 3.8.10
- Operating system and version: Ubuntu (WSL on Windows)
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 in mypy's semantic analyzer and reproduce the issue with the foo.py example from the report. Trace handling of global and nonlocal declarations, including ast3.AnnAssign.simple cases, and verify that x is not incorrectly treated as used or bound for x: int without assignment. Done means mypy reports the syntax error while preserving the stated exception.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100