Description
Bug Report
mypy warns about the right side of a condition being unreachable when a variable is reset in an outer loop, then set again inside the inner loop.
To Reproduce
from typing import Optional
test: Optional[float] = None
reveal_type(test) # Revealed type: Union[builtins.float, None]
for i in range(10):
test = None
reveal_type(test) # Revealed type: None (???)
for k in range(10):
if test is None or k > test:
test = k
Expected Behavior
No error.
Actual Behavior
mypy outputs error: Right operand of "or" is never evaluated
. This is clearly because the type of test
is re-evaluated at some point, even though it was declared with a type and no statement narrows that type.
This appears related to #7204, #8721, #8865, #13973, #14120, except it can't be solved by declaring the type of the variable before the loop in which it's updated (because that violates no-redef
).
Note: I'm not sure why anyone would want to actually do this in practice. But I thought it might provide a useful test case.
Your Environment
- Mypy version used: 1.1.1
- Mypy command-line flags: --disable-error-code name-defined, plus a few others that I don't believe could possibly have any relevance.
- Mypy configuration options from
mypy.ini
(and other config files): None - Python version used: 3.10.10
Activity
Melebius commentedon Jun 15, 2023
Similar problem here while using mypy==1.3.0.
My example code:
Run output:
patrickelectric commentedon Aug 4, 2023
grihabor commentedon Jun 9, 2024
+1
Here is a smaller example:
The script output:
Mypy error:
A5rocks commentedon Jan 22, 2025
@grihabor and @Melebius your issues were fixed by #18433, though the initial example was not.
grihabor commentedon Jan 23, 2025
Nice, thanks for the ping
tyralla commentedon Jun 3, 2025
I tend to think the problem underlying the initial example has nothing to do with loops but with promotions, because both
float
andint
are involved.So, maybe this is a simpler repro:
With "normal" subtypes, the same type of type narrowing works:
Likely, an attempt to solve this could start here:
https://github.com/python/mypy/blob/5a0fa556be741270e25c95a923ef8450d28dd448/mypy/meet.py#L130C1-L145C10
Improve the support for promotions inside unions. (#19245)