Skip to content

Conversation

@ambv
Copy link
Contributor

@ambv ambv commented Aug 20, 2025

When a for loop contains branches with break and an else block, variables declared inside those branches were incorrectly discarded from further analysis, leading Mypy to incorrectly report a variable as undefined after the loop or as used before declaration.

With this fix, when a for loop's else block is considered, variables declared in every branch of the for loop body that called break are now considered as defined within the body of the loop.

Fixes #14209
Fixes #19690

ambv and others added 3 commits August 20, 2025 17:03
When a for loop contains branches with `break` and an `else` block,
variables declared inside those branches were incorrectly discarded
from further analysis, leading Mypy to incorrectly report a variable
as undefined after the loop or as used before declaration.

With this fix, when a for loop's `else` block is considered, variables
declared in every branch of the `for` loop body that called `break` are
now considered as defined within the body of the loop.

Fixes python#14209
Fixes python#19690
@github-actions

This comment has been minimized.

@cdce8p cdce8p added the topic-possibly-undefined possibly-undefined error code label Aug 21, 2025
@ambv ambv requested a review from ilevkivskyi August 23, 2025 10:34
@ambv
Copy link
Contributor Author

ambv commented Aug 23, 2025

@ilevkivskyi, I asked you for review since you reviewed the original change three years back.

Copy link
Member

@ilevkivskyi ilevkivskyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I forget many details since I last looked at this code, bu this looks reasonable. I just have a test suggestion.

else:
raise RuntimeError

print(value) # Should not error - value is defined if we broke
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also add one two tests where it should error? Like, e.g, if raise above is conditional.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I will add the test.

@spt29
Copy link

spt29 commented Dec 5, 2025

It would be cool to get this landed, I just stumbled across a similar false positive in our codebase. Is there anything left to be done apart from actually merging this fix?

@johnslavik
Copy link
Member

Is there anything left to be done apart from actually merging this fix?

Yes: https://github.com/python/mypy/pull/19696/files#r2300505910

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some more tests

@github-actions

This comment has been minimized.

@github-actions
Copy link
Contributor

According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅

@hauntsaninja hauntsaninja merged commit cf508c2 into python:master Jan 18, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic-possibly-undefined possibly-undefined error code upnext

Projects

None yet

Development

Successfully merging this pull request may close these issues.

try: except: continue inside for: else: causes spurious used-before-def (🐞) for/else with break statement incorrect possibly-undefined error

6 participants