Skip to content

Fix spurious possibly-undefined errors in for-else with break#19696

Merged
hauntsaninja merged 7 commits into
python:masterfrom
ambv:for-else-break
Jan 18, 2026
Merged

Fix spurious possibly-undefined errors in for-else with break#19696
hauntsaninja merged 7 commits into
python:masterfrom
ambv:for-else-break

Conversation

@ambv

@ambv ambv commented Aug 20, 2025

Copy link
Copy Markdown
Contributor

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

ambv commented Aug 23, 2025

Copy link
Copy Markdown
Contributor Author

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

@ilevkivskyi ilevkivskyi left a comment

Copy link
Copy Markdown
Member

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
Copy Markdown
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
Copy Markdown
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

spt29 commented Dec 5, 2025

Copy link
Copy Markdown

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
Copy Markdown
Member

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

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

@hauntsaninja hauntsaninja left a comment

Copy link
Copy Markdown
Collaborator

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
Copy Markdown
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

7 participants