Repository navigation
B012: don't flag break/continue in an async for loop inside finally - #602
Merged
Merged
Conversation
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The exemption also hides valid warnings for exception-suppressing exits in an async loop’s else suite.
1 open issue
What changed in this PR
Extends B012’s loop exemption to async for inside finally, matching existing synchronous-loop handling.
Changes:
- Exempts async-loop
breakandcontinuewhile retaining warnings forreturn. - Adds regression coverage and an unreleased changelog entry.
| File | Description |
|---|---|
| tests/eval_files/b012.py | Adds async-loop diagnostic cases. |
| README.rst | Documents the B012 change. |
| bugbear.py | Adds ast.AsyncFor to loop handling. |
Review effort: Balanced
Comment on lines
+1415
to
1416
| if isinstance(node, (ast.While, ast.For, ast.AsyncFor)): | ||
| bad_node_types = (ast.Return,) |
B012 skips break and continue in a for or while loop that sits inside a finally block, since they only leave that loop. An async for loop got no such exemption, so the same code was reported once it became async. Treat AsyncFor like For and While there. A return inside the loop is still reported.
spicysharkco
force-pushed
the
fix/b012-async-for
branch
from
October 19, 2026 18:33
1cf044e to
12aa4fd
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

B012 does not report
breakorcontinuein afororwhileloop inside afinallyblock, since they only leave that loop (#106, fixed in #107). Anasync forloop is missing from that exemption.flake8 --select=B012 file.pyreports:The same loop written as
for x in xs:in a plaindefis clean. Neither statement can silence an exception from thetryblock, so both reports are false positives. The README text for B012 is aboutbreak,continueorreturnthat "will silence exceptions or override return values from thetryorexceptblocks".Cause:
_loopincheck_for_b012only treatsast.Whileandast.Foras loops (bugbear.py#L1415).Fix: add
ast.AsyncForto that tuple. Areturninside the loop is still reported.Test: a new
async defcase intests/eval_files/b012.pywithbreakandcontinue(no warning) andreturn(B012).pytest tests/test_bugbear.py -k b012fails before the fix with two extra B012 reports and passes after. Fulltests/test_bugbear.py: 123 passed, 4 skipped (Python 3.12, flake8 7.4.1). The pre-commit hooks pass. I added a line under UNRELEASED inREADME.rst.