Skip to content

Commit

Permalink
B018 to detect useless-statements at all levels (#434)
Browse files Browse the repository at this point in the history
* add unit test for b018 at all levels

* fix b018 to detect useless statements at all levels
  • Loading branch information
r-downing authored Dec 2, 2023
1 parent 4ca0e6b commit 89f950c
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 27 deletions.
52 changes: 25 additions & 27 deletions bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ def visit(self, node):
if is_contextful:
self.contexts.pop()

self.check_for_b018(node)

def visit_ExceptHandler(self, node):
if node.type is None:
self.errors.append(B001(node.lineno, node.col_offset))
Expand Down Expand Up @@ -447,7 +449,6 @@ def visit_Call(self, node):
self.generic_visit(node)

def visit_Module(self, node):
self.check_for_b018(node)
self.generic_visit(node)

def visit_Assign(self, node):
Expand Down Expand Up @@ -503,15 +504,13 @@ def visit_FunctionDef(self, node):
self.check_for_b901(node)
self.check_for_b902(node)
self.check_for_b006_and_b008(node)
self.check_for_b018(node)
self.check_for_b019(node)
self.check_for_b021(node)
self.check_for_b906(node)
self.generic_visit(node)

def visit_ClassDef(self, node):
self.check_for_b903(node)
self.check_for_b018(node)
self.check_for_b021(node)
self.check_for_b024_and_b027(node)
self.generic_visit(node)
Expand Down Expand Up @@ -1164,31 +1163,30 @@ 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:
if not isinstance(subnode, ast.Expr):
continue
if isinstance(
subnode.value,
(
ast.List,
ast.Set,
ast.Dict,
ast.Tuple,
),
) or (
isinstance(subnode.value, ast.Constant)
and (
isinstance(subnode.value.value, (int, float, complex, bytes, bool))
or subnode.value.value is None
)
):
self.errors.append(
B018(
subnode.lineno,
subnode.col_offset,
vars=(subnode.value.__class__.__name__,),
)
if not isinstance(node, ast.Expr):
return
if isinstance(
node.value,
(
ast.List,
ast.Set,
ast.Dict,
ast.Tuple,
),
) or (
isinstance(node.value, ast.Constant)
and (
isinstance(node.value.value, (int, float, complex, bytes, bool))
or node.value.value is None
)
):
self.errors.append(
B018(
node.lineno,
node.col_offset,
vars=(node.value.__class__.__name__,),
)
)

def check_for_b021(self, node):
if (
Expand Down
44 changes: 44 additions & 0 deletions tests/b018_nested.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

X = 1
False # bad


def func(y):
a = y + 1
5.5 # bad
return a


class TestClass:
GOOD = [1, 3]
[5, 6] # bad

def method(self, xx, yy=5):
t = (xx,)
(yy,) # bad

while 1:
i = 3
4 # bad
for n in range(i):
j = 5
1.5 # bad
if j < n:
u = {1, 2}
{4, 5} # bad
elif j == n:
u = {1, 2, 3}
{4, 5, 6} # bad
else:
u = {2, 3}
{4, 6} # bad
try:
1j # bad
r = 2j
except Exception:
r = 3j
5 # bad
finally:
4j # bad
r += 1
return u + t
21 changes: 21 additions & 0 deletions tests/test_bugbear.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,27 @@ def test_b018_modules(self):
]
self.assertEqual(errors, self.errors(*expected))

def test_b018_nested(self):
filename = Path(__file__).absolute().parent / "b018_nested.py"
bbc = BugBearChecker(filename=str(filename))
errors = list(bbc.run())

expected = [
B018(3, 0, vars=("Constant",)),
B018(8, 4, vars=("Constant",)),
B018(14, 4, vars=("List",)),
B018(18, 8, vars=("Tuple",)),
B018(22, 12, vars=("Constant",)),
B018(25, 16, vars=("Constant",)),
B018(28, 20, vars=("Set",)),
B018(31, 20, vars=("Set",)),
B018(34, 20, vars=("Set",)),
B018(36, 24, vars=("Constant",)),
B018(40, 24, vars=("Constant",)),
B018(42, 24, vars=("Constant",)),
]
self.assertEqual(errors, self.errors(*expected))

def test_b019(self):
filename = Path(__file__).absolute().parent / "b019.py"
bbc = BugBearChecker(filename=str(filename))
Expand Down

0 comments on commit 89f950c

Please sign in to comment.