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

(🐞) for/else with break statement incorrect possibly-undefined error #14209

Open
KotlinIsland opened this issue Nov 27, 2022 · 12 comments
Open
Labels
bug mypy got something wrong topic-possibly-undefined possibly-undefined error code

Comments

@KotlinIsland
Copy link
Contributor

KotlinIsland commented Nov 27, 2022

#14191 (comment)

a: list[int]

for i in a:
    if i:
        b = i
        break
else:
    b = 1

print(b)  # error: Name "b" may be undefined  [possibly-undefined]
@KotlinIsland KotlinIsland added the bug mypy got something wrong label Nov 27, 2022
@AlexWaygood AlexWaygood added the topic-possibly-undefined possibly-undefined error code label Nov 28, 2022
@Dreamsorcerer
Copy link
Contributor

Dreamsorcerer commented Jul 27, 2023

Also when the else condition raises:

x: int
while x:
    if x == 5:
        foo = 10
        break
else:
    raise RuntimeError()

foo  # possibly-undefined

@KotlinIsland KotlinIsland changed the title (🐞) for/else with break statement incorrect partially defined error (🐞) for/else with break statement incorrect possibly-undefined error Jul 27, 2023
@erictraut
Copy link

I'm not able to repro the problem with the latest version of mypy. But then again, I'm not able to repro with any versions going back to 0.990, so maybe I'm not using the right configuration.

@KotlinIsland, are you able to repro this issue with the latest version?

BTW, it would be useful in the future if you included the mypy version in your bug reports as requested in the bug template.

@Dreamsorcerer
Copy link
Contributor

Did you miss enabling the error code? mypy --enable-error-code 'possibly-undefined'

Both still reproduce on 1.5.

@erictraut
Copy link

Ah, that was what I was missing. I though this error code was enabled by default in recent versions of mypy.

@KotlinIsland
Copy link
Contributor Author

@erictraut You should try using basedmypy, all errors are enabled by default.

@Dreamsorcerer
Copy link
Contributor

Dreamsorcerer commented Aug 16, 2023

It also seems impossible to get something like this to type check:

for i in range(5):
    b = True

print(b)  # error: Name "b" may be undefined  [possibly-undefined]

I guess mypy doesn't know how to confirm that the loop is guaranteed to execute.

@giacomo-alzetta-aiven
Copy link

This also fails:

for element in sequence:
    if (something := something_else.get(element)) is not None:
        break
else:
    return None
print(something)   # triggers possibly-undefined

Seems like mypy doesn't understand that the else clause of the for loop will run if sequence is empty...

@NMertsch
Copy link

I never contributed code to mypy before, but would love to get this fixed.
Is this a "good first issue" candidate?

@KotlinIsland
Copy link
Contributor Author

Yeah, it would be a relatively simple scenario. Likely only one spot that needs fixing

NMertsch pushed a commit to NMertsch/mypy that referenced this issue Aug 29, 2024
NMertsch added a commit to NMertsch/mypy that referenced this issue Aug 29, 2024
@NMertsch
Copy link

I started my Draft PR (#17720) by adding three failing test cases reproducing the issue. If someone can help me with a builtins/fixture issue, that would be highly appreciated.

It's not a blocker yet (I have two "good" failing tests to work with), but I'm curious to learn more about how this is done "properly" 🙂

@KotlinIsland
Copy link
Contributor Author

update unit/fixtures/exception.pyi to:

class list:
    def __iter__(self): ...

NMertsch added a commit to NMertsch/mypy that referenced this issue Aug 30, 2024
NMertsch added a commit to NMertsch/mypy that referenced this issue Sep 1, 2024
NMertsch added a commit to NMertsch/mypy that referenced this issue Sep 9, 2024
NMertsch added a commit to NMertsch/mypy that referenced this issue Sep 10, 2024
@NMertsch
Copy link

NMertsch commented Sep 10, 2024

While investigating this issue, I determined five separate issues or possible improvements with possibly-undefined and loops:

  1. for and while loop: else execution is dependent on position, not just presence of break (cause for this issue)
  2. for and while loop: else is not just "no break", but also executed if the body is not executed
  3. for loop: index is only defined if the body is executed
  4. for loop: infer emptiness of expression
  5. while loop: infer truthiness of expression

I hope I can get #17720 merged, but currently don't have the capacity to work on the other points.

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

No branches or pull requests

6 participants