diff --git a/bugbear.py b/bugbear.py index 8cf3325..4233d05 100644 --- a/bugbear.py +++ b/bugbear.py @@ -1598,6 +1598,19 @@ 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", + "popitem", + ) + def __init__(self, name: str): self.name = name self.mutations = [] @@ -1619,8 +1632,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) diff --git a/tests/b038.py b/tests/b038.py index e19b066..6e11603 100644 --- a/tests/b038.py +++ b/tests/b038.py @@ -45,3 +45,31 @@ 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 + mydicts.popitem() # should error + diff --git a/tests/test_bugbear.py b/tests/test_bugbear.py index 0bac96b..29bc7d0 100644 --- a/tests/test_bugbear.py +++ b/tests/test_bugbear.py @@ -981,6 +981,15 @@ 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), + B038(74, 8), ] self.assertEqual(errors, self.errors(*expected))