Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False positive unreachable when variable is set and reset inside loop #14987

Open
adebrecht661 opened this issue Mar 31, 2023 · 5 comments
Open
Labels
bug mypy got something wrong

Comments

@adebrecht661
Copy link

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
@adebrecht661 adebrecht661 added the bug mypy got something wrong label Mar 31, 2023
@Melebius
Copy link

Similar problem here while using mypy==1.3.0.

My example code:

data = """
{foo}
bar >
baz
"""

prompt = None
reponse = None
lines = data.splitlines()
for line in lines:
    if prompt and reponse:  # mypy error: Right operand of "and" is never evaluated  [unreachable]
        print("Break reached!")  # mypy error: Statement is unreachable  [unreachable]
        break
    if not prompt and line.endswith(">"):
        prompt = line
        continue
    if not reponse and line.endswith("}"):
        reponse = line
        continue

Run output:

$ python example.py
Break reached!
$

@patrickelectric
Copy link

patrickelectric commented Aug 4, 2023

Here looking at this issue after my PR fails on CI.
image

@grihabor
Copy link

grihabor commented Jun 9, 2024

+1

Here is a smaller example:

state = None
for x in 'ab':
    if state is not None:
        print('reachable')
    state = 'x'

The script output:

reachable

Mypy error:

main.py:4:9: error: Statement is unreachable  [unreachable]
            print('reachable')
            ^~~~~~~~~~~~~~~~~~
Found 1 error in 1 file (checked 1 source file)

✕ mypy failed.

@A5rocks
Copy link
Collaborator

A5rocks commented Jan 22, 2025

@grihabor and @Melebius your issues were fixed by #18433, though the initial example was not.

@grihabor
Copy link

Nice, thanks for the ping

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong
Projects
None yet
Development

No branches or pull requests

5 participants