[3.7] bpo-34282: Fix Enum._convert method shadowing members named _convert (GH-9034)

* Fix Enum._convert shadowing members named _convert
This commit is contained in:
orlnub123 2018-09-10 19:39:48 +03:00 committed by Ethan Furman
parent 4902017430
commit c0d63bf73b
3 changed files with 24 additions and 4 deletions

View File

@ -171,9 +171,11 @@ class EnumMeta(type):
enum_class._member_map_ = OrderedDict() # name->value map enum_class._member_map_ = OrderedDict() # name->value map
enum_class._member_type_ = member_type enum_class._member_type_ = member_type
# save attributes from super classes so we know if we can take # save DynamicClassAttribute attributes from super classes so we know
# the shortcut of storing members in the class dict # if we can take the shortcut of storing members in the class dict
base_attributes = {a for b in enum_class.mro() for a in b.__dict__} dynamic_attributes = {k for c in enum_class.mro()
for k, v in c.__dict__.items()
if isinstance(v, DynamicClassAttribute)}
# Reverse value->name map for hashable values. # Reverse value->name map for hashable values.
enum_class._value2member_map_ = {} enum_class._value2member_map_ = {}
@ -233,7 +235,7 @@ class EnumMeta(type):
enum_class._member_names_.append(member_name) enum_class._member_names_.append(member_name)
# performance boost for any member that would not shadow # performance boost for any member that would not shadow
# a DynamicClassAttribute # a DynamicClassAttribute
if member_name not in base_attributes: if member_name not in dynamic_attributes:
setattr(enum_class, member_name, enum_member) setattr(enum_class, member_name, enum_member)
# now add to _member_map_ # now add to _member_map_
enum_class._member_map_[member_name] = enum_member enum_class._member_map_[member_name] = enum_member

View File

@ -1516,6 +1516,23 @@ class TestEnum(unittest.TestCase):
yellow = 6 yellow = 6
self.assertEqual(MoreColor.magenta.hex(), '5 hexlified!') self.assertEqual(MoreColor.magenta.hex(), '5 hexlified!')
def test_subclass_duplicate_name(self):
class Base(Enum):
def test(self):
pass
class Test(Base):
test = 1
self.assertIs(type(Test.test), Test)
def test_subclass_duplicate_name_dynamic(self):
from types import DynamicClassAttribute
class Base(Enum):
@DynamicClassAttribute
def test(self):
return 'dynamic'
class Test(Base):
test = 1
self.assertEqual(Test.test.test, 'dynamic')
def test_no_duplicates(self): def test_no_duplicates(self):
class UniqueEnum(Enum): class UniqueEnum(Enum):

View File

@ -0,0 +1 @@
Fix enum members getting shadowed by parent attributes.