diff --git a/README.rst b/README.rst index 221bf3f..f2fdb8b 100644 --- a/README.rst +++ b/README.rst @@ -222,6 +222,11 @@ MIT Change Log ---------- +Unreleased +~~~~~~~~~~ + +* Update B006: list, dictionary, and set comprehensions are now also disallowed (#186) + 21.9.1 ~~~~~~ diff --git a/bugbear.py b/bugbear.py index 3d05ae6..b47f0d7 100644 --- a/bugbear.py +++ b/bugbear.py @@ -328,7 +328,9 @@ def check_for_b005(self, node): def check_for_b006(self, node): for default in node.args.defaults + node.args.kw_defaults: - if isinstance(default, B006.mutable_literals): + if isinstance( + default, (*B006.mutable_literals, *B006.mutable_comprehensions) + ): self.errors.append(B006(default.lineno, default.col_offset)) elif isinstance(default, ast.Call): call_path = ".".join(self.compose_call_path(default.func)) @@ -653,6 +655,7 @@ def visit(self, node): ) ) B006.mutable_literals = (ast.Dict, ast.List, ast.Set) +B006.mutable_comprehensions = (ast.ListComp, ast.DictComp, ast.SetComp) B006.mutable_calls = { "Counter", "OrderedDict", diff --git a/tests/b006_b008.py b/tests/b006_b008.py index 40bf797..e095323 100644 --- a/tests/b006_b008.py +++ b/tests/b006_b008.py @@ -119,3 +119,15 @@ def operators_ok_unqualified( v=attrgetter("foo"), v2=itemgetter("foo"), v3=methodcaller("foo") ): pass + + +def list_comprehension_also_not_okay(default=[i ** 2 for i in range(3)]): + pass + + +def dict_comprehension_also_not_okay(default={i: i ** 2 for i in range(3)}): + pass + + +def set_comprehension_also_not_okay(default={i ** 2 for i in range(3)}): + pass diff --git a/tests/test_bugbear.py b/tests/test_bugbear.py index 3f91edc..6a0fb55 100644 --- a/tests/test_bugbear.py +++ b/tests/test_bugbear.py @@ -103,6 +103,9 @@ def test_b006_b008(self): B006(70, 32), B008(98, 29), B008(102, 44), + B006(124, 45 if sys.version_info >= (3, 8) else 46), + B006(128, 45), + B006(132, 44), ), )