Skip to content

Fix B020 false positive with attribute and subscript access#539

Closed
Fridayai700 wants to merge 2 commits intoPyCQA:mainfrom
Fridayai700:fix-b020-attribute-false-positive
Closed

Fix B020 false positive with attribute and subscript access#539
Fridayai700 wants to merge 2 commits intoPyCQA:mainfrom
Fridayai700:fix-b020-attribute-false-positive

Conversation

@Fridayai700
Copy link

Summary

Fixes #521 — B020 was incorrectly flagging patterns like:

for smoother in smoother.smoothers:
    x = smoother.basis

for data in data["a"]:
    print(data)

These are safe because the iterable expression (smoother.smoothers, data["a"]) is evaluated once before the loop starts. The loop variable name appearing as an attribute/subscript base is not the same as the loop variable being the direct iterable.

Changes

  • Override visit_Attribute and visit_Subscript in B020NameFinder to stop descending into attribute bases and subscript bases
  • Direct name references (for x in x) and names inside function calls (for x in f(x)) are still correctly flagged
  • for key, values in values.items() is no longer flagged (the name appears inside an attribute access)
  • Added test cases from issue B020 false positives with iterable attribute acess #521

Behavior change

The existing test expected for key, values in values.items() to be flagged. This PR changes that — since values is used as an attribute base (values.items()), not as the direct iterable, it should not trigger B020. The pattern is common, idiomatic Python.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Friday and others added 2 commits February 17, 2026 06:42
B020 was flagging `for x in x.attr` and `for x in x[key]` as
reassigning the iterable, but these patterns are safe because:

1. The iterable expression is evaluated once before the loop starts
2. The name is used as an attribute/subscript base, producing a
   different object — it's not the direct iterable

Override visit_Attribute and visit_Subscript in B020NameFinder
to stop recording names that appear as attribute bases or subscript
bases. Direct name references (for x in x) and names inside
function calls (for x in f(x)) are still flagged.

This also means `for key, values in values.items()` is no longer
flagged, which is correct — values.items() is a method call on an
attribute, not a direct reference to the iterable.

Fixes PyCQA#521

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The visit_Attribute and visit_Subscript methods in B020NameFinder are
intentionally empty to suppress name recording for attribute/subscript
bases. Add noqa comments so flake8-bugbear's own B906 check doesn't
flag them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

B020 false positives with iterable attribute acess

1 participant