Closed
Description
Bug Report
When iterating over an empty iterable with afor
loop , the index isn't defined. If the index is a predefined variable, it is left unchanged. Mypy, however always infers the iterable is never empty and the index is always overwritten. This causes a divergence between static analysis and runtime behavior.
(I initially found this via a false positive truthy-bool error)
To Reproduce
# example.py
from typing import *
l: list[str] = []
x: str | int = 5
for x in l:
pass
reveal_type(x) # Revealed type is "builtins.str" -- expected `str | int`
# python3.11 example.py
# Runtime type is 'int'
https://mypy-play.net/?mypy=master&python=3.11&gist=eecaaa80bc226778521644f9dedbda5b
Expected Behavior
mypy should infer x: str
inside the for
statement body, but outside, it should infer the original value or'd with the type of the iterable. In this example it should be str | int
Actual Behavior
mypy infers str
whereas at runtime it is int
.
Your Environment
- Mypy version used: master, 1.6.1, 1.5.1
- Mypy command-line flags: N/A
- Mypy configuration options from
mypy.ini
(and other config files): N/A - Python version used: 3.11