diff --git a/Lib/enum.py b/Lib/enum.py index 787945a0aa5..0def138e3e4 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -125,11 +125,11 @@ 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._member_names_ = [] # names in definition order + enum_class._member_map_ = OrderedDict() # name->value map # Reverse value->name map for hashable values. - enum_class._value2member_map = {} + enum_class._value2member_map_ = {} # check for a __getnewargs__, and if not present sabotage # pickling, since it won't work anyway @@ -156,27 +156,27 @@ class EnumMeta(type): else: enum_member = __new__(enum_class, *args) original_value = member_type(*args) - if not hasattr(enum_member, '_value'): - enum_member._value = original_value - value = enum_member._value - enum_member._member_type = member_type - enum_member._name = member_name + if not hasattr(enum_member, '_value_'): + enum_member._value_ = original_value + value = enum_member._value_ + enum_member._member_type_ = member_type + enum_member._name_ = member_name enum_member.__init__(*args) # If another member with the same value was already defined, the # new member becomes an alias to the existing one. - for name, canonical_member in enum_class._member_map.items(): - if canonical_member.value == enum_member._value: + for name, canonical_member in enum_class._member_map_.items(): + if canonical_member.value == enum_member._value_: enum_member = canonical_member break else: # Aliases don't appear in member names (only in __members__). - enum_class._member_names.append(member_name) - enum_class._member_map[member_name] = enum_member + enum_class._member_names_.append(member_name) + enum_class._member_map_[member_name] = enum_member try: # This may fail if value is not hashable. We can't add the value # to the map, and by-value lookups for this value will be # linear. - enum_class._value2member_map[value] = enum_member + enum_class._value2member_map_[value] = enum_member except TypeError: pass @@ -221,10 +221,10 @@ class EnumMeta(type): return cls._create_(value, names, module=module, type=type) def __contains__(cls, member): - return isinstance(member, cls) and member.name in cls._member_map + return isinstance(member, cls) and member.name in cls._member_map_ def __dir__(self): - return ['__class__', '__doc__', '__members__'] + self._member_names + return ['__class__', '__doc__', '__members__'] + self._member_names_ @property def __members__(cls): @@ -234,7 +234,7 @@ class EnumMeta(type): is a read-only view of the internal mapping. """ - return MappingProxyType(cls._member_map) + return MappingProxyType(cls._member_map_) def __getattr__(cls, name): """Return the enum member matching `name` @@ -248,18 +248,18 @@ class EnumMeta(type): if _is_dunder(name): raise AttributeError(name) try: - return cls._member_map[name] + return cls._member_map_[name] except KeyError: raise AttributeError(name) from None def __getitem__(cls, name): - return cls._member_map[name] + return cls._member_map_[name] def __iter__(cls): - return (cls._member_map[name] for name in cls._member_names) + return (cls._member_map_[name] for name in cls._member_names_) def __len__(cls): - return len(cls._member_names) + return len(cls._member_names_) def __repr__(cls): return "" % cls.__name__ @@ -327,7 +327,7 @@ class EnumMeta(type): for base in bases: if (base is not Enum and issubclass(base, Enum) and - base._member_names): + base._member_names_): raise TypeError("Cannot extend enumerations") # base is now the last base in bases if not issubclass(base, Enum): @@ -417,21 +417,21 @@ class Enum(metaclass=EnumMeta): # by-value search for a matching enum member # see if it's in the reverse mapping (for hashable values) try: - if value in cls._value2member_map: - return cls._value2member_map[value] + if value in cls._value2member_map_: + return cls._value2member_map_[value] except TypeError: # not there, now do long search -- O(n) behavior - for member in cls._member_map.values(): + for member in cls._member_map_.values(): if member.value == value: return member raise ValueError("%s is not a valid %s" % (value, cls.__name__)) def __repr__(self): return "<%s.%s: %r>" % ( - self.__class__.__name__, self._name, self._value) + self.__class__.__name__, self._name_, self._value_) def __str__(self): - return "%s.%s" % (self.__class__.__name__, self._name) + return "%s.%s" % (self.__class__.__name__, self._name_) def __dir__(self): return (['__class__', '__doc__', 'name', 'value']) @@ -442,10 +442,10 @@ class Enum(metaclass=EnumMeta): return NotImplemented def __getnewargs__(self): - return (self._value, ) + return (self._value_, ) def __hash__(self): - return hash(self._name) + return hash(self._name_) # _RouteClassAttributeToGetattr is used to provide access to the `name` # and `value` properties of enum members while keeping some measure of @@ -456,11 +456,11 @@ class Enum(metaclass=EnumMeta): @_RouteClassAttributeToGetattr def name(self): - return self._name + return self._name_ @_RouteClassAttributeToGetattr def value(self): - return self._value + return self._value_ class IntEnum(int, Enum): diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index c94718263c2..d0b4a1c0892 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -516,7 +516,7 @@ class TestEnum(unittest.TestCase): def question(self): print(42) self.assertIsNot(type(Why.question), Why) - self.assertNotIn(Why.question, Why._member_names) + self.assertNotIn(Why.question, Why._member_names_) self.assertNotIn(Why.question, Why) def test_wrong_inheritance_order(self): @@ -777,10 +777,10 @@ class TestEnum(unittest.TestCase): def __new__(cls): value = len(cls.__members__) + 1 obj = object.__new__(cls) - obj._value = value + obj._value_ = value return obj def __int__(self): - return int(self._value) + return int(self._value_) self.assertEqual( list(AutoNumber), [AutoNumber.first, AutoNumber.second, AutoNumber.third], @@ -794,10 +794,10 @@ class TestEnum(unittest.TestCase): def __new__(cls): value = len(cls.__members__) + 1 obj = object.__new__(cls) - obj._value = value + obj._value_ = value return obj def __int__(self): - return int(self._value) + return int(self._value_) class Color(AutoNumber): red = () green = () @@ -810,7 +810,7 @@ class TestEnum(unittest.TestCase): def __new__(cls): value = len(cls.__members__) + 1 obj = int.__new__(cls, value) - obj._value = value + obj._value_ = value return obj class Color(AutoNumber): red = () @@ -823,19 +823,19 @@ class TestEnum(unittest.TestCase): class OrderedEnum(Enum): def __ge__(self, other): if self.__class__ is other.__class__: - return self._value >= other._value + return self._value_ >= other._value_ return NotImplemented def __gt__(self, other): if self.__class__ is other.__class__: - return self._value > other._value + return self._value_ > other._value_ return NotImplemented def __le__(self, other): if self.__class__ is other.__class__: - return self._value <= other._value + return self._value_ <= other._value_ return NotImplemented def __lt__(self, other): if self.__class__ is other.__class__: - return self._value < other._value + return self._value_ < other._value_ return NotImplemented class Grade(OrderedEnum): A = 5 @@ -847,6 +847,7 @@ class TestEnum(unittest.TestCase): self.assertLessEqual(Grade.F, Grade.C) self.assertLess(Grade.D, Grade.A) self.assertGreaterEqual(Grade.B, Grade.B) + def test_extending2(self): class Shade(Enum): def shade(self): @@ -923,7 +924,7 @@ class TestEnum(unittest.TestCase): def __new__(cls): value = [len(cls.__members__) + 1] obj = object.__new__(cls) - obj._value = value + obj._value_ = value return obj class ColorInAList(AutoNumberInAList): red = ()