Skip to content

Commit 8462c1f

Browse files
committed
fixes #277, most of #278, and #280
1 parent 592b722 commit 8462c1f

File tree

3 files changed

+42
-16
lines changed

3 files changed

+42
-16
lines changed

bugbear.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -616,13 +616,15 @@ def check_for_b024_and_b027(self, node: ast.ClassDef):
616616
"""Check for inheritance from abstract classes in abc and lack of
617617
any methods decorated with abstract*"""
618618

619-
def is_abc_class(value):
619+
def is_abc_class(value, name="ABC"):
620+
# class foo(metaclass = [abc.]ABCMeta)
620621
if isinstance(value, ast.keyword):
621-
return value.arg == "metaclass" and is_abc_class(value.value)
622-
abc_names = ("ABC", "ABCMeta")
623-
return (isinstance(value, ast.Name) and value.id in abc_names) or (
622+
return value.arg == "metaclass" and is_abc_class(value.value, "ABCMeta")
623+
# class foo(ABC)
624+
# class foo(abc.ABC)
625+
return (isinstance(value, ast.Name) and value.id == name) or (
624626
isinstance(value, ast.Attribute)
625-
and value.attr in abc_names
627+
and value.attr == name
626628
and isinstance(value.value, ast.Name)
627629
and value.value.id == "abc"
628630
)
@@ -647,6 +649,11 @@ def empty_body(body) -> bool:
647649
for stmt in body
648650
)
649651

652+
# don't check multiple inheritance
653+
# https://github.com/PyCQA/flake8-bugbear/issues/277
654+
if len(node.bases) + len(node.keywords) > 1:
655+
return
656+
650657
# only check abstract classes
651658
if not any(map(is_abc_class, (*node.bases, *node.keywords))):
652659
return
@@ -666,7 +673,7 @@ def empty_body(body) -> bool:
666673

667674
if not has_abstract_decorator and empty_body(stmt.body):
668675
self.errors.append(
669-
B025(stmt.lineno, stmt.col_offset, vars=(stmt.name,))
676+
B027(stmt.lineno, stmt.col_offset, vars=(stmt.name,))
670677
)
671678

672679
if not has_abstract_method:

tests/b024.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,32 @@ def method(self):
8181
foo()
8282

8383

84-
class multi_super_1(notabc.ABC, abc.ABCMeta): # error
84+
class multi_super_1(notabc.ABC, abc.ABCMeta): # safe
8585
def method(self):
8686
foo()
8787

8888

89-
class multi_super_2(notabc.ABC, metaclass=abc.ABCMeta): # error
89+
class multi_super_2(notabc.ABC, metaclass=abc.ABCMeta): # safe
90+
def method(self):
91+
foo()
92+
93+
94+
class non_keyword_abcmeta_1(ABCMeta): # safe
95+
def method(self):
96+
foo()
97+
98+
99+
class non_keyword_abcmeta_2(abc.ABCMeta): # safe
100+
def method(self):
101+
foo()
102+
103+
104+
# very invalid code, but that's up to mypy et al to check
105+
class keyword_abc_1(metaclass=ABC): # safe
106+
def method(self):
107+
foo()
108+
109+
110+
class keyword_abc_2(metaclass=abc.ABC): # safe
90111
def method(self):
91112
foo()

tests/test_bugbear.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,6 @@ def test_b024(self):
364364
B024(58, 0, vars=("MetaBase_1",)),
365365
B024(69, 0, vars=("abc_Base_1",)),
366366
B024(74, 0, vars=("abc_Base_2",)),
367-
B024(84, 0, vars=("multi_super_1",)),
368-
B024(89, 0, vars=("multi_super_2",)),
369367
)
370368
self.assertEqual(errors, expected)
371369

@@ -401,15 +399,15 @@ def test_b026(self):
401399
)
402400

403401
def test_b027(self):
404-
filename = Path(__file__).absolute().parent / "b025.py"
402+
filename = Path(__file__).absolute().parent / "b027.py"
405403
bbc = BugBearChecker(filename=str(filename))
406404
errors = list(bbc.run())
407405
expected = self.errors(
408-
B025(13, 4, vars=("empty_1",)),
409-
B025(16, 4, vars=("empty_2",)),
410-
B025(19, 4, vars=("empty_3",)),
411-
B025(23, 4, vars=("empty_4",)),
412-
B025(31, 4, vars=("empty_5",)),
406+
B027(13, 4, vars=("empty_1",)),
407+
B027(16, 4, vars=("empty_2",)),
408+
B027(19, 4, vars=("empty_3",)),
409+
B027(23, 4, vars=("empty_4",)),
410+
B027(31, 4, vars=("empty_5",)),
413411
)
414412
self.assertEqual(errors, expected)
415413

0 commit comments

Comments
 (0)