From 1efe034ddc6c67348ab1145773bc9ad7100614af Mon Sep 17 00:00:00 2001 From: Kai Mueller <15907922+kasium@users.noreply.github.com> Date: Thu, 21 Oct 2021 13:51:54 +0000 Subject: [PATCH 1/3] Add B018 check to find useless string declarations This will find all sorts of useless string declarations in functions and classes. It will also prevent to use multiline strings as comments Resolves #195 --- README.rst | 3 +++ bugbear.py | 13 +++++++++++++ tests/b018.py | 35 +++++++++++++++++++++++++++++++++++ tests/test_bugbear.py | 9 +++++++++ 4 files changed, 60 insertions(+) create mode 100644 tests/b018.py diff --git a/README.rst b/README.rst index 6ccb84e..294e10a 100644 --- a/README.rst +++ b/README.rst @@ -130,6 +130,9 @@ 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**: Useless definition of a string. Either assign the string to a variable or remove it. +If the string is used as a comment, consider to use "#". + Opinionated warnings ~~~~~~~~~~~~~~~~~~~~ diff --git a/bugbear.py b/bugbear.py index ba0294f..395ad15 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,12 @@ def visit(self, node): "context manager form of assertRaises." ) ) +B018 = Error( + message=( + "Useless definition of a string. Either assign the string to a variable or remove it. " + "If the string is used as a comment, consider to use '#'." + ) +) # 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)) From 4b3e0809c4fb8e2d57a4f04680b74ec18a9bfeac Mon Sep 17 00:00:00 2001 From: Kai Mueller <15907922+kasium@users.noreply.github.com> Date: Thu, 21 Oct 2021 15:53:49 +0000 Subject: [PATCH 2/3] Better error message --- README.rst | 3 +-- bugbear.py | 5 +---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 294e10a..40fabe9 100644 --- a/README.rst +++ b/README.rst @@ -130,8 +130,7 @@ 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**: Useless definition of a string. Either assign the string to a variable or remove it. -If the string is used as a comment, consider to use "#". +**B018**: Found useless expression. Either assign it to a variable or remove it. Opinionated warnings diff --git a/bugbear.py b/bugbear.py index 395ad15..b46c5a7 100644 --- a/bugbear.py +++ b/bugbear.py @@ -775,10 +775,7 @@ def visit(self, node): ) ) B018 = Error( - message=( - "Useless definition of a string. Either assign the string to a variable or remove it. " - "If the string is used as a comment, consider to use '#'." - ) + message="B018 Found useless expression. Either assign it to a variable or remove it." ) # Warnings disabled by default. From 625e4cfea9d95031f3228c9a2f929c4d623860b6 Mon Sep 17 00:00:00 2001 From: Kai Mueller <15907922+kasium@users.noreply.github.com> Date: Thu, 21 Oct 2021 15:54:51 +0000 Subject: [PATCH 3/3] Fix black --- bugbear.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bugbear.py b/bugbear.py index b46c5a7..581c090 100644 --- a/bugbear.py +++ b/bugbear.py @@ -775,7 +775,9 @@ def visit(self, node): ) ) B018 = Error( - message="B018 Found useless expression. Either assign it to a variable or remove it." + message=( + "B018 Found useless expression. Either assign it to a variable or remove it." + ) ) # Warnings disabled by default.