Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ Release date: TBA

References pylint-dev/pylint#872

* Fix ``DuplicateBasesError`` crash in the enum brain when inferring an enum
class with duplicate bases (e.g. ``class C(enum.Enum, enum.Enum)``).
``infer_enum_class`` now catches ``MroError`` and leaves such a malformed
class untransformed.

Closes #3065


What's New in astroid 4.1.2?
============================
Expand Down
9 changes: 8 additions & 1 deletion astroid/brain/brain_namedtuple_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
AstroidTypeError,
AstroidValueError,
InferenceError,
MroError,
UseInferenceDefault,
)
from astroid.inference_tip import inference_tip
Expand Down Expand Up @@ -386,7 +387,13 @@ def __mul__(self, other):

def infer_enum_class(node: nodes.ClassDef) -> nodes.ClassDef:
"""Specific inference for enums."""
for basename in (b for cls in node.mro() for b in cls.basenames):
try:
mro = node.mro()
except MroError:
# A malformed class hierarchy (e.g. duplicate bases) has no resolvable
# MRO; leave the node untransformed rather than crashing.
return node
for basename in (b for cls in mro for b in cls.basenames):
if node.root().name == "enum":
# Skip if the class is directly from enum module.
break
Expand Down
15 changes: 15 additions & 0 deletions tests/brain/test_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -559,3 +559,18 @@ class MyEnum(enum.Enum):

inferred_value = next(sunder_value.infer())
assert inferred_value.value == 42

def test_enum_duplicate_bases_no_crash(self) -> None:
"""An enum class with duplicate bases has no resolvable MRO.

Regression test for https://github.com/pylint-dev/astroid/issues/3065
"""
node = builder.extract_node("""
import enum

class C(enum.Enum, enum.Enum): #@
pass
""")
# Inference must not raise ``DuplicateBasesError``.
inferred = next(node.infer())
assert isinstance(inferred, nodes.ClassDef)
Loading