Skip to content

Commit 7a562dd

Browse files
Fix crash in invalid-metaclass check (#8699)
1 parent 60daec6 commit 7a562dd

File tree

4 files changed

+41
-7
lines changed

4 files changed

+41
-7
lines changed

doc/whatsnew/fragments/8698.bugfix

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix crash in ``invalid-metaclass`` check when a metaclass had duplicate bases.
2+
3+
Closes #8698

pylint/checkers/typecheck.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,10 @@ def _no_context_variadic(
747747

748748

749749
def _is_invalid_metaclass(metaclass: nodes.ClassDef) -> bool:
750-
mro = metaclass.mro()
750+
try:
751+
mro = metaclass.mro()
752+
except (astroid.DuplicateBasesError, astroid.InconsistentMroError):
753+
return True
751754
return not any(is_builtin_object(cls) and cls.name == "type" for cls in mro)
752755

753756

tests/functional/i/invalid/invalid_metaclass.py

+24
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
# pylint: disable=multiple-statements
66

77
import abc
8+
from pathlib import Path
9+
from typing import Protocol
810

911
import six
1012
from unknown import Unknown
@@ -68,3 +70,25 @@ class Invalid(metaclass=invalid_metaclass_1): # [invalid-metaclass]
6870

6971
class InvalidSecond(metaclass=invalid_metaclass_2): # [invalid-metaclass]
7072
pass
73+
74+
75+
class MetaclassWithInvalidMRO(type(object), type(object)): # [duplicate-bases]
76+
pass
77+
78+
79+
class FifthInvalid(metaclass=MetaclassWithInvalidMRO): # [invalid-metaclass]
80+
pass
81+
82+
83+
class Proto(Protocol):
84+
...
85+
86+
87+
class MetaclassWithInconsistentMRO(type(Path), type(Proto)): # [inconsistent-mro]
88+
pass
89+
90+
91+
class SixthInvalid( # [invalid-metaclass]
92+
Path, Proto, metaclass=MetaclassWithInconsistentMRO
93+
):
94+
pass
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
invalid-metaclass:41:0:41:18:FirstInvalid:Invalid metaclass 'int' used:UNDEFINED
2-
invalid-metaclass:45:0:45:19:SecondInvalid:Invalid metaclass 'InvalidAsMetaclass' used:UNDEFINED
3-
invalid-metaclass:49:0:49:18:ThirdInvalid:Invalid metaclass '2' used:UNDEFINED
4-
invalid-metaclass:53:0:53:19:FourthInvalid:Invalid metaclass 'Instance of invalid_metaclass.InvalidAsMetaclass' used:UNDEFINED
5-
invalid-metaclass:65:0:65:13:Invalid:Invalid metaclass 'int' used:UNDEFINED
6-
invalid-metaclass:69:0:69:19:InvalidSecond:Invalid metaclass '1' used:UNDEFINED
1+
invalid-metaclass:43:0:43:18:FirstInvalid:Invalid metaclass 'int' used:UNDEFINED
2+
invalid-metaclass:47:0:47:19:SecondInvalid:Invalid metaclass 'InvalidAsMetaclass' used:UNDEFINED
3+
invalid-metaclass:51:0:51:18:ThirdInvalid:Invalid metaclass '2' used:UNDEFINED
4+
invalid-metaclass:55:0:55:19:FourthInvalid:Invalid metaclass 'Instance of invalid_metaclass.InvalidAsMetaclass' used:UNDEFINED
5+
invalid-metaclass:67:0:67:13:Invalid:Invalid metaclass 'int' used:UNDEFINED
6+
invalid-metaclass:71:0:71:19:InvalidSecond:Invalid metaclass '1' used:UNDEFINED
7+
duplicate-bases:75:0:75:29:MetaclassWithInvalidMRO:Duplicate bases for class 'MetaclassWithInvalidMRO':UNDEFINED
8+
invalid-metaclass:79:0:79:18:FifthInvalid:Invalid metaclass 'MetaclassWithInvalidMRO' used:UNDEFINED
9+
inconsistent-mro:87:0:87:34:MetaclassWithInconsistentMRO:Inconsistent method resolution order for class 'MetaclassWithInconsistentMRO':UNDEFINED
10+
invalid-metaclass:91:0:91:18:SixthInvalid:Invalid metaclass 'MetaclassWithInconsistentMRO' used:UNDEFINED

0 commit comments

Comments
 (0)