diff --git a/README.rst b/README.rst index 6ccb84e..40fabe9 100644 --- a/README.rst +++ b/README.rst @@ -130,6 +130,8 @@ Either assert for a more specific exception (builtin or custom), use (``with self.assertRaises(Exception) as ex:``) with an assertion against the data available in ``ex``. +**B018**: Found useless expression. Either assign it to a variable or remove it. + Opinionated warnings ~~~~~~~~~~~~~~~~~~~~ diff --git a/bugbear.py b/bugbear.py index ba0294f..581c090 100644 --- a/bugbear.py +++ b/bugbear.py @@ -278,10 +278,12 @@ def visit_FunctionDef(self, node): self.check_for_b901(node) self.check_for_b902(node) self.check_for_b006(node) + self.check_for_b018(node) self.generic_visit(node) def visit_ClassDef(self, node): self.check_for_b903(node) + self.check_for_b018(node) self.generic_visit(node) def visit_Try(self, node): @@ -575,6 +577,11 @@ def check_for_b903(self, node): self.errors.append(B903(node.lineno, node.col_offset)) + def check_for_b018(self, node): + for subnode in node.body[1:]: + if isinstance(subnode, ast.Expr) and isinstance(subnode.value, ast.Str): + self.errors.append(B018(subnode.lineno, subnode.col_offset)) + @attr.s class NameFinder(ast.NodeVisitor): @@ -767,6 +774,11 @@ def visit(self, node): "context manager form of assertRaises." ) ) +B018 = Error( + message=( + "B018 Found useless expression. Either assign it to a variable or remove it." + ) +) # Warnings disabled by default. B901 = Error( diff --git a/tests/b018.py b/tests/b018.py new file mode 100644 index 0000000..11c207c --- /dev/null +++ b/tests/b018.py @@ -0,0 +1,35 @@ +""" +Should emit: +B018 - on lines 14, 19, 30, 35 +""" + + +def foo1(): + """my docstring""" + + +def foo2(): + """my docstring""" + a = 2 + "str" + + +def foo3(): + a = 2 + "str" + + +class Foo1: + """abc""" + + +class Foo2: + """abc""" + + a = 2 + "str" + + +class Foo3: + a = 2 + "str" diff --git a/tests/test_bugbear.py b/tests/test_bugbear.py index 445918d..c3e3437 100644 --- a/tests/test_bugbear.py +++ b/tests/test_bugbear.py @@ -28,6 +28,7 @@ B015, B016, B017, + B018, B904, B901, B902, @@ -211,6 +212,14 @@ def test_b017(self): expected = self.errors(B017(22, 8)) self.assertEqual(errors, expected) + def test_b018(self): + filename = Path(__file__).absolute().parent / "b018.py" + bbc = BugBearChecker(filename=str(filename)) + errors = list(bbc.run()) + self.assertEqual( + errors, self.errors(B018(14, 4), B018(19, 4), B018(30, 4), B018(35, 4)) + ) + def test_b901(self): filename = Path(__file__).absolute().parent / "b901.py" bbc = BugBearChecker(filename=str(filename))