Description
Bug Report
When assigning to variables within an if
elif
block, mypy
appears to incorrectly carry the assigned type between blocks (where it can never have been assigned in the else
part).
To Reproduce
Using a very contrived example, which causes a common variable name to be "reused" between types;
x = 1
if x == 1:
record = 1
elif x == 2:
record = ""
mypy
reports an incompatible type
$ mypy --strict test.py
test.py:5: error: Incompatible types in assignment (expression has type "str", variable has type "int")
Found 1 error in 1 file (checked 1 source file)
Expected Behavior
Since the second record
variable cannot have been assigned (otherwise we would have never got to this block), it cannot have the type of int
.
mypy
should treat it as an unassigned variable and associate the new str
type at the point of assignment.
Effectively this should result in no errors and be the same logically as e.g.
x = 1
if x == 1:
record1 = 1
elif x == 2:
record2 = ""
Which passes cleanly;
$ mypy --strict test.py
Success: no issues found in 1 source file
Actual Behavior
mypy
appears to be carrying the inferred type of the first assignment (in the if
block) over into the second (elif
block) assignment, even though the variable has not been assigned.
mypy
view of the world;
test.py:8: note: Revealed type is "builtins.int"
python
view of the world;
Traceback (most recent call last):
File "/divesoft-parser/test.py", line 8, in <module>
reveal_type(record)
NameError: name 'record' is not defined
Your Environment
- Mypy version used:
mypy 0.950 (compiled: yes)
- Mypy command-line flags:
--strict
- Mypy configuration options from
mypy.ini
(and other config files): None - Python version used:
3.9.12
- Operating system and version:
OSX 11.6.5
x-ref https://gitter.im/python/typing?at=626ac42846495f47cfb712a3