Skip to content

Commit 8f255ce

Browse files
committed
Fixed issue 119946 - Enum with ABC mixin
1 parent f79ffc8 commit 8f255ce

3 files changed

Lines changed: 51 additions & 5 deletions

File tree

Lib/enum.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import sys
22
import builtins as bltns
33
from types import MappingProxyType, DynamicClassAttribute
4+
from abc import ABCMeta
45

56

67
__all__ = [
@@ -466,7 +467,7 @@ def update(self, members, **more_members):
466467
_EnumDict = EnumDict # keep private name for backwards compatibility
467468

468469

469-
class EnumType(type):
470+
class EnumType(ABCMeta):
470471
"""
471472
Metaclass for Enum
472473
"""
@@ -1773,7 +1774,7 @@ def convert_class(cls):
17731774
body['__rand__'] = Flag.__rand__
17741775
body['__invert__'] = Flag.__invert__
17751776
for name, obj in cls.__dict__.items():
1776-
if name in ('__dict__', '__weakref__'):
1777+
if name in ('__dict__', '__weakref__', '_abc_impl'):
17771778
continue
17781779
if _is_dunder(name) or _is_private(cls_name, name) or _is_sunder(name) or _is_descriptor(obj):
17791780
body[name] = obj
@@ -2038,7 +2039,7 @@ def _test_simple_enum(checked_enum, simple_enum):
20382039
)
20392040
for key in set(checked_keys + simple_keys):
20402041
if key in ('__module__', '_member_map_', '_value2member_map_', '__doc__',
2041-
'__static_attributes__', '__firstlineno__'):
2042+
'__static_attributes__', '__firstlineno__', '_abc_impl'):
20422043
# keys known to be different, or very long
20432044
continue
20442045
elif key in member_names:
@@ -2094,7 +2095,7 @@ def _test_simple_enum(checked_enum, simple_enum):
20942095
simple_value = simple_member_dict[key]
20952096
if checked_value != simple_value:
20962097
failed_member.append("%r:\n %s\n %s" % (
2097-
key,
2098+
key,
20982099
"checked member -> %r" % (checked_value, ),
20992100
"simple member -> %r" % (simple_value, ),
21002101
))

Lib/test/test_enum.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from test.support import ALWAYS_EQ, REPO_ROOT
2222
from test.support import threading_helper
2323
from datetime import timedelta
24+
from abc import ABC, abstractmethod
2425

2526
python_version = sys.version_info[:2]
2627

@@ -3910,6 +3911,23 @@ class Color(StrMixin, AllMixin, Flag):
39103911
self.assertEqual(Color.ALL.value, 7)
39113912
self.assertEqual(str(Color.BLUE), 'blue')
39123913

3914+
def test_abstract_mixin(self):
3915+
class HasColor(ABC):
3916+
@abstractmethod
3917+
def color(self):
3918+
...
3919+
class Flowers(HasColor, Enum):
3920+
ROSES = 1
3921+
VIOLETS = 2
3922+
def color(self):
3923+
match self:
3924+
case self.ROSES:
3925+
return 'red'
3926+
case self.VIOLETS:
3927+
return 'blue'
3928+
self.assertEqual(Flowers.ROSES.color(), 'red')
3929+
self.assertEqual(Flowers.VIOLETS.color(), 'blue')
3930+
39133931
@threading_helper.reap_threads
39143932
@threading_helper.requires_working_threading()
39153933
def test_unique_composite(self):
@@ -5221,7 +5239,33 @@ def __new__(cls, value, label):
52215239
VEST = 1, 'uppert half'
52225240
PANTS = 2, 'lower half'
52235241
_test_simple_enum(CheckedComplexFlag, ComplexFlag)
5224-
5242+
#
5243+
#
5244+
class HasColor(ABC):
5245+
@abstractmethod
5246+
def color(self):
5247+
...
5248+
class CheckedABCMixin(HasColor, Enum):
5249+
ROSES = 1
5250+
VIOLETS = 2
5251+
def color(self):
5252+
match self:
5253+
case self.ROSES:
5254+
return 'red'
5255+
case self.VIOLETS:
5256+
return 'blue'
5257+
#
5258+
@_simple_enum(Enum)
5259+
class ABCMixin(HasColor):
5260+
ROSES = 1
5261+
VIOLETS = 2
5262+
def color(self):
5263+
match self:
5264+
case self.ROSES:
5265+
return 'red'
5266+
case self.VIOLETS:
5267+
return 'blue'
5268+
_test_simple_enum(CheckedABCMixin, ABCMixin)
52255269

52265270
class MiscTestCase(unittest.TestCase):
52275271

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow Enum classes to have mixins derived from an abstract base class (ABC).

0 commit comments

Comments
 (0)