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

Skip to content

Commit 2aa2732

Browse files
committed
Close #18508 -- fix _value2member_map to always have the member's value
1 parent e410f26 commit 2aa2732

2 files changed

Lines changed: 31 additions & 11 deletions

File tree

Lib/enum.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
"""Python Enumerations"""
2-
31
import sys
42
from collections import OrderedDict
53
from types import MappingProxyType
@@ -154,11 +152,13 @@ def __new__(metacls, cls, bases, classdict):
154152
args = (args, ) # wrap it one more time
155153
if not use_args:
156154
enum_member = __new__(enum_class)
157-
enum_member._value = value
155+
original_value = value
158156
else:
159157
enum_member = __new__(enum_class, *args)
160-
if not hasattr(enum_member, '_value'):
161-
enum_member._value = member_type(*args)
158+
original_value = member_type(*args)
159+
if not hasattr(enum_member, '_value'):
160+
enum_member._value = original_value
161+
value = enum_member._value
162162
enum_member._member_type = member_type
163163
enum_member._name = member_name
164164
enum_member.__init__(*args)
@@ -416,12 +416,14 @@ def __new__(cls, value):
416416
return value
417417
# by-value search for a matching enum member
418418
# see if it's in the reverse mapping (for hashable values)
419-
if value in cls._value2member_map:
420-
return cls._value2member_map[value]
421-
# not there, now do long search -- O(n) behavior
422-
for member in cls._member_map.values():
423-
if member.value == value:
424-
return member
419+
try:
420+
if value in cls._value2member_map:
421+
return cls._value2member_map[value]
422+
except TypeError:
423+
# not there, now do long search -- O(n) behavior
424+
for member in cls._member_map.values():
425+
if member.value == value:
426+
return member
425427
raise ValueError("%s is not a valid %s" % (value, cls.__name__))
426428

427429
def __repr__(self):

Lib/test/test_enum.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ class NEI(NamedInt, Enum):
694694
x = ('the-x', 1)
695695
y = ('the-y', 2)
696696

697+
697698
self.assertIs(NEI.__new__, Enum.__new__)
698699
self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)")
699700
globals()['NamedInt'] = NamedInt
@@ -785,6 +786,7 @@ def __int__(self):
785786
[AutoNumber.first, AutoNumber.second, AutoNumber.third],
786787
)
787788
self.assertEqual(int(AutoNumber.second), 2)
789+
self.assertEqual(AutoNumber.third.value, 3)
788790
self.assertIs(AutoNumber(1), AutoNumber.first)
789791

790792
def test_inherited_new_from_enhanced_enum(self):
@@ -916,6 +918,22 @@ def surface_gravity(self):
916918
self.assertEqual(round(Planet.EARTH.surface_gravity, 2), 9.80)
917919
self.assertEqual(Planet.EARTH.value, (5.976e+24, 6.37814e6))
918920

921+
def test_nonhash_value(self):
922+
class AutoNumberInAList(Enum):
923+
def __new__(cls):
924+
value = [len(cls.__members__) + 1]
925+
obj = object.__new__(cls)
926+
obj._value = value
927+
return obj
928+
class ColorInAList(AutoNumberInAList):
929+
red = ()
930+
green = ()
931+
blue = ()
932+
self.assertEqual(list(ColorInAList), [ColorInAList.red, ColorInAList.green, ColorInAList.blue])
933+
self.assertEqual(ColorInAList.red.value, [1])
934+
self.assertEqual(ColorInAList([1]), ColorInAList.red)
935+
936+
919937

920938
class TestUnique(unittest.TestCase):
921939

0 commit comments

Comments
 (0)