Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -2214,6 +2214,18 @@ def visit(self, node) -> None:
class B020NameFinder(NameFinder):
"""Ignore names defined within the local scope of a comprehension."""

def visit_Attribute(self, node) -> None: # noqa: B906
pass

def visit_Call(self, node) -> None:
if isinstance(node.func, ast.Attribute):
self.visit(node.func.value)
self.visit(node.args)
self.visit(node.keywords)
return

self.generic_visit(node)

def visit_GeneratorExp(self, node) -> None:
self.visit(node.generators)

Expand Down
5 changes: 5 additions & 0 deletions tests/eval_files/b020.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@

for var in sorted(range(10), key=lambda var: var.real):
print(var)

# Attribute access on the loop target name is not iterating over the same
# object, so it should not trigger B020.
for smoother in smoother.smoothers:
print(smoother)
Comment on lines +44 to +45

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.

Suggested change
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.