Change _names to _names_ since the latter is reserved for Enum use.

Before this change only the methods were _single_underscored_; now
the attributes are as well.
This commit is contained in:
Ethan Furman 2013-07-19 19:47:21 -07:00
parent 2aa2732eaf
commit 520ad57916
2 changed files with 42 additions and 41 deletions

View File

@ -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 "<enum %r>" % 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):

View File

@ -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 = ()