diff --git a/bugbear.py b/bugbear.py index 1e281ec..1149edf 100644 --- a/bugbear.py +++ b/bugbear.py @@ -326,7 +326,8 @@ def visit_Call(self, node): ): self.errors.append(B009(node.lineno, node.col_offset)) elif ( - node.func.id == "setattr" + not any(isinstance(n, ast.Lambda) for n in self.node_stack) + and node.func.id == "setattr" and len(node.args) == 3 and _is_identifier(node.args[1]) and not iskeyword(node.args[1].s) diff --git a/tests/b009_b010.py b/tests/b009_b010.py index 0f17c2b..e002b0f 100644 --- a/tests/b009_b010.py +++ b/tests/b009_b010.py @@ -1,6 +1,6 @@ """ Should emit: -B009 - Line 17, 18, 19 +B009 - Line 17, 18, 19, 44 B010 - Line 28, 29, 30 """ @@ -28,3 +28,20 @@ setattr(foo, "bar", None) setattr(foo, "_123abc", None) setattr(foo, "abc123", None) + +# Allow use of setattr within lambda expression +# since assignment is not valid in this context. +c = lambda x: setattr(x, "some_attr", 1) + + +class FakeCookieStore: + def __init__(self, has_setter): + self.cookie_filter = None + if has_setter: + self.setCookieFilter = lambda func: setattr(self, "cookie_filter", func) + + +# getattr is still flagged within lambda though +c = lambda x: getattr(x, "some_attr") +# should be replaced with +c = lambda x: x.some_attr diff --git a/tests/test_bugbear.py b/tests/test_bugbear.py index d3ee22c..1a164e6 100644 --- a/tests/test_bugbear.py +++ b/tests/test_bugbear.py @@ -169,6 +169,7 @@ def test_b009_b010(self): B010(28, 0), B010(29, 0), B010(30, 0), + B009(45, 14), ] self.assertEqual(errors, self.errors(*all_errors))