[Python-Dev] PEP 435 - reference implementation discussion
Tim Delaney
timothy.c.delaney at gmail.com
Sun May 5 05:50:25 CEST 2013
Split off from the PEP 435 - requesting pronouncement thread.
Think I've come up with a system that works for my auto-numbering case
without knowing the internals of enum_type. Patch passes all existing test
cases. The patch does two things:
1. Finds the first non-Enum class on the MRO of the new class and uses that
as the enum type.
2. Instead of directly setting the _name and _value of the enum_item, it
lets the Enum class do it via Enum.__init__(). Subclasses can override
this. This gives Enums a 2-phase construction just like other classes.
diff -r 758d43b9f732 ref435.py
--- a/ref435.py Fri May 03 18:59:32 2013 -0700
+++ b/ref435.py Sun May 05 13:43:56 2013 +1000
@@ -116,7 +116,17 @@
if bases[-1] is Enum:
obj_type = bases[0]
else:
- obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int,
Enum, object)
+ obj_type = None
+
+ for base in bases:
+ for c in base.__mro__:
+ if not issubclass(c, Enum):
+ obj_type = c
+ break
+
+ if obj_type is not None:
+ break
+
else:
obj_type = object
# save enum items into separate mapping so they don't get baked
into
@@ -143,8 +153,7 @@
enum_item = object.__new__(enum_class)
else:
enum_item = obj_type.__new__(enum_class, value)
- enum_item._value = value
- enum_item._name = e
+ enum_item.__init__(e, value)
enum_map[e] = enum_item
enum_class.__aliases__ = aliases # non-unique enums names
enum_class._enum_names = enum_names # enum names in definition
order
@@ -232,6 +241,10 @@
return enum
raise ValueError("%s is not a valid %s" % (value, cls.__name__))
+ def __init__(self, name, value):
+ self._name = name
+ self._value = value
+
def __repr__(self):
return "<%s.%s: %r>" % (self.__class__.__name__, self._name,
self._value)
Auto-int implementation:
class AutoInt(int):
__slots__ = ()
def __new__(cls, value):
if value is Ellipsis:
try:
i = cls._auto_number
except AttributeError:
i = cls._auto_number = 0
else:
i = cls._auto_number = value
cls._auto_number += 1
return int.__new__(cls, i)
class AutoIntEnum(AutoInt, IntEnum):
def __init__(self, name, value):
super(AutoIntEnum, self).__init__(name, int(self))
class TestAutoIntEnum(AutoIntEnum):
a = ...
b = 3
c = ...
class TestAutoIntEnum2(AutoIntEnum):
a = ...
b = ...
c = ...
print(TestAutoIntEnum, list(TestAutoIntEnum))
print(TestAutoIntEnum2, list(TestAutoIntEnum2))
---------- Run ----------
<Enum 'TestAutoIntEnum'> [<TestAutoIntEnum.a: 0>, <TestAutoIntEnum.b: 3>,
<TestAutoIntEnum.c: 4>]
<Enum 'TestAutoIntEnum2'> [<TestAutoIntEnum2.a: 0>, <TestAutoIntEnum2.b:
1>, <TestAutoIntEnum2.c: 2>]
Tim Delaney
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20130505/a7fbdabd/attachment.html>
More information about the Python-Dev
mailing list