diff -r e33b4c18af59 Lib/enum.py --- a/Lib/enum.py Wed Sep 16 12:18:55 2015 -0400 +++ b/Lib/enum.py Thu Sep 17 12:31:13 2015 +0200 @@ -1,7 +1,9 @@ import sys -from collections import OrderedDict from types import MappingProxyType, DynamicClassAttribute +# import delayed in __members__() property +OrderedDict = None + __all__ = ['Enum', 'IntEnum', 'unique'] @@ -113,7 +115,8 @@ class EnumMeta(type): # create our new Enum type enum_class = super().__new__(metacls, cls, bases, classdict) enum_class._member_names_ = [] # names in definition order - enum_class._member_map_ = OrderedDict() # name->value map + enum_class._all_member_names_ = [] # including aliases + enum_class._member_map_ = {} # name->value map enum_class._member_type_ = member_type # save attributes from super classes so we know if we can take @@ -173,6 +176,8 @@ class EnumMeta(type): else: # Aliases don't appear in member names (only in __members__). enum_class._member_names_.append(member_name) + # Aliases do appear in _all_member_names_ + enum_class._all_member_names_.append(member_name) # performance boost for any member that would not shadow # a DynamicClassAttribute if member_name not in base_attributes: @@ -284,6 +289,15 @@ class EnumMeta(type): is a read-only view of the internal mapping. """ + global OrderedDict + if OrderedDict is None: + from collections import OrderedDict + if not isinstance(cls._member_map_, OrderedDict): + print("CONVERT", cls) + ordered = OrderedDict() + for member_name in cls._all_member_names_: + ordered[member_name] = cls._member_map_[member_name] + cls._member_map_ = ordered return MappingProxyType(cls._member_map_) def __repr__(cls): @@ -557,7 +571,8 @@ def _reduce_ex_by_name(self, proto): def unique(enumeration): """Class decorator for enumerations ensuring unique member values.""" duplicates = [] - for name, member in enumeration.__members__.items(): + for name in enumeration._all_member_names_: + member = enumeration[name] if name != member.name: duplicates.append((name, member.name)) if duplicates: diff -r e33b4c18af59 Lib/test/test_enum.py --- a/Lib/test/test_enum.py Wed Sep 16 12:18:55 2015 -0400 +++ b/Lib/test/test_enum.py Thu Sep 17 12:31:13 2015 +0200 @@ -319,10 +319,11 @@ class TestEnum(unittest.TestCase): self.assertIs(Season(3), Season.AUTUMN) self.assertIs(Season(1), Season.SPRING) self.assertEqual(Season.FALL.name, 'AUTUMN') - self.assertEqual( - [k for k,v in Season.__members__.items() if v.name != k], - ['FALL', 'ANOTHER_SPRING'], - ) + dups = [ + k for k in Season._all_member_names_ + if Season.__members__[k].name != k + ] + self.assertEqual(dups, ['FALL', 'ANOTHER_SPRING']) def test_duplicate_name(self): with self.assertRaises(TypeError):