Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bff01f3

Browse files
authored
bpo-39587: Enum - use correct mixed-in data type (GH-22263)
1 parent 2e87774 commit bff01f3

3 files changed

Lines changed: 56 additions & 1 deletion

File tree

Lib/enum.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,14 +482,25 @@ def _get_mixins_(bases):
482482
return object, Enum
483483

484484
def _find_data_type(bases):
485+
data_types = []
485486
for chain in bases:
487+
candidate = None
486488
for base in chain.__mro__:
487489
if base is object:
488490
continue
489491
elif '__new__' in base.__dict__:
490492
if issubclass(base, Enum):
491493
continue
492-
return base
494+
data_types.append(candidate or base)
495+
break
496+
elif not issubclass(base, Enum):
497+
candidate = base
498+
if len(data_types) > 1:
499+
raise TypeError('too many data types: %r' % data_types)
500+
elif data_types:
501+
return data_types[0]
502+
else:
503+
return None
493504

494505
# ensure final parent class is an Enum derivative, find any concrete
495506
# data type, and check that Enum has no members

Lib/test/test_enum.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,49 @@ def test_format_enum_str(self):
560560
self.assertFormatIsValue('{:>20}', Directional.WEST)
561561
self.assertFormatIsValue('{:<20}', Directional.WEST)
562562

563+
def test_enum_str_override(self):
564+
class MyStrEnum(Enum):
565+
def __str__(self):
566+
return 'MyStr'
567+
class MyMethodEnum(Enum):
568+
def hello(self):
569+
return 'Hello! My name is %s' % self.name
570+
class Test1Enum(MyMethodEnum, int, MyStrEnum):
571+
One = 1
572+
Two = 2
573+
self.assertEqual(str(Test1Enum.One), 'MyStr')
574+
#
575+
class Test2Enum(MyStrEnum, MyMethodEnum):
576+
One = 1
577+
Two = 2
578+
self.assertEqual(str(Test2Enum.One), 'MyStr')
579+
580+
def test_inherited_data_type(self):
581+
class HexInt(int):
582+
def __repr__(self):
583+
return hex(self)
584+
class MyEnum(HexInt, enum.Enum):
585+
A = 1
586+
B = 2
587+
C = 3
588+
self.assertEqual(repr(MyEnum.A), '<MyEnum.A: 0x1>')
589+
590+
def test_too_many_data_types(self):
591+
with self.assertRaisesRegex(TypeError, 'too many data types'):
592+
class Huh(str, int, Enum):
593+
One = 1
594+
595+
class MyStr(str):
596+
def hello(self):
597+
return 'hello, %s' % self
598+
class MyInt(int):
599+
def repr(self):
600+
return hex(self)
601+
with self.assertRaisesRegex(TypeError, 'too many data types'):
602+
class Huh(MyStr, MyInt, Enum):
603+
One = 1
604+
605+
563606
def test_hash(self):
564607
Season = self.Season
565608
dates = {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
use the correct mix-in data type when constructing Enums

0 commit comments

Comments
 (0)