Skip to content

Commit

Permalink
fix(b038): Restrict rule to mutating functions only
Browse files Browse the repository at this point in the history
Previous implementation produced false positives.
This fixes those and adds some more tests.

See PyCQA#451
  • Loading branch information
mimre25 committed Jan 16, 2024
1 parent f365c21 commit 6ffdefb
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
18 changes: 17 additions & 1 deletion bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -1598,6 +1598,18 @@ def compose_call_path(node):


class B038Checker(ast.NodeVisitor):
# https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types
MUTATING_FUNCTIONS = (
"append",
"sort",
"reverse",
"remove",
"clear",
"extend",
"insert",
"pop",
)

def __init__(self, name: str):
self.name = name
self.mutations = []
Expand All @@ -1619,8 +1631,12 @@ def visit_Call(self, node: ast.Call):
if isinstance(node.func, ast.Attribute):
name = _to_name_str(node.func.value)
function_object = name
function_name = node.func.attr

if function_object == self.name:
if (
function_object == self.name
and function_name in self.MUTATING_FUNCTIONS
):
self.mutations.append(node)

self.generic_visit(node)
Expand Down
26 changes: 26 additions & 0 deletions tests/b038.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,29 @@ def __init__(self, ls):
print(elem)
if elem % 2 == 0:
del a.some_list[2] # should error



some_list = [1, 2, 3]
for elem in some_list:
print(elem)
if elem == 2:
found_idx = some_list.index(elem) # should not error
some_list.append(elem) # should error
some_list.sort() # should error
some_list.reverse() # should error
some_list.clear() # should error
some_list.extend([1,2]) # should error
some_list.insert(1, 1) # should error
some_list.pop(1) # should error
some_list.pop() # should error
some_list = 3 # should error
break



mydicts = {'a': {'foo': 1, 'bar': 2}}

for mydict in mydicts:
if mydicts.get('a', ''):
print(mydict['foo']) # should not error
8 changes: 8 additions & 0 deletions tests/test_bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,14 @@ def test_b038(self):
B038(27, 8),
B038(41, 8),
B038(47, 8),
B038(56, 8),
B038(57, 8),
B038(58, 8),
B038(59, 8),
B038(60, 8),
B038(61, 8),
B038(62, 8),
B038(63, 8),
]
self.assertEqual(errors, self.errors(*expected))

Expand Down

0 comments on commit 6ffdefb

Please sign in to comment.