Fix B020 false positive for attribute iterables#562
Conversation
cooperlees
left a comment
There was a problem hiding this comment.
I'm not sure we want to fix this, open to other perspectives tho ... and I'll go with majority ...
| for smoother in smoother.smoothers: | ||
| print(smoother) |
There was a problem hiding this comment.
| for smoother in smoother.smoothers: | |
| print(smoother) | |
| for smoother_loop in smoother.smoothers: | |
| print(smoother_loop) | |
| smoother = smother_loop |
I argue not doing this is a good practice even tho it's technically not overwriting what your iterating ...
I am a fan of being explicit even at the cost of more assignments etc.
There was a problem hiding this comment.
Pull request overview
This PR fixes a B020 false positive where the loop target name appears as the base of an attribute-access iterable (e.g., for smoother in smoother.smoothers:), while preserving detection for method-call iterables (e.g., values.items()), and adds a regression test to cover the reported case from #521.
Changes:
- Update B020 iterable name collection to ignore plain attribute access while still traversing method-call bases.
- Add an eval-file regression case ensuring
for smoother in smoother.smoothers:does not trigger B020.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
bugbear.py |
Adjusts B020NameFinder traversal to skip ast.Attribute nodes and special-case method calls so existing B020 coverage (like values.items()) remains. |
tests/eval_files/b020.py |
Adds a regression example for attribute access on the loop target name that should not emit B020. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -2214,6 +2214,18 @@ def visit(self, node) -> None: | |||
| class B020NameFinder(NameFinder): | |||
| """Ignore names defined within the local scope of a comprehension.""" | |||
|
Thanks for looking. My reasoning for treating this as a false positive is that B020 is most useful when the loop target overwrites the iterable object itself, e.g. the warning protects For plain attribute access, The patch keeps the existing method-call behavior ( |
Fixes #521.
Summary
smoother.smoothersas the iterable being reassignedvalues.items()coveredTests
uv run --python 3.13 --with '.[dev]' pytest tests/test_bugbear.py -k B020 -quv run --python 3.13 --with '.[dev]' pytest tests/test_bugbear.py -quv run --python 3.13 --with flake8 --with attrs flake8 bugbear.py tests/test_bugbear.pyuv run --python 3.13 --with mypy --with types-flake8 --with attrs --with flake8 mypy bugbear.pygit diff --check