<div dir="ltr">Split off from the PEP 435 - requesting pronouncement thread.<div><br></div><div style>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:</div>
<div style><br></div><div style>1. Finds the first non-Enum class on the MRO of the new class and uses that as the enum type.</div><div style><br></div><div style>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.</div>
<div style><br></div><div style><div><div>diff -r 758d43b9f732 ref435.py</div><div>--- a/ref435.py<span class="" style="white-space:pre">     </span>Fri May 03 18:59:32 2013 -0700</div><div>+++ b/ref435.py<span class="" style="white-space:pre">      </span>Sun May 05 13:43:56 2013 +1000</div>
<div>@@ -116,7 +116,17 @@</div><div>             if bases[-1] is Enum:</div><div>                 obj_type = bases[0]</div><div>             else:</div><div>-                obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int, Enum, object)</div>
<div>+                obj_type = None</div><div>+</div><div>+                for base in bases:</div><div>+                    for c in base.__mro__:</div><div>+                        if not issubclass(c, Enum):</div><div>
+                            obj_type = c</div><div>+                            break</div><div>+</div><div>+                    if obj_type is not None:</div><div>+                        break</div><div>+</div><div>         else:</div>
<div>             obj_type = object</div><div>         # save enum items into separate mapping so they don't get baked into</div><div>@@ -143,8 +153,7 @@</div><div>                     enum_item = object.__new__(enum_class)</div>
<div>                 else:</div><div>                     enum_item = obj_type.__new__(enum_class, value)</div><div>-                enum_item._value = value</div><div>-                enum_item._name = e</div><div>+                enum_item.__init__(e, value)</div>
<div>             enum_map[e] = enum_item</div><div>         enum_class.__aliases__ = aliases      # non-unique enums names</div><div>         enum_class._enum_names = enum_names     # enum names in definition order</div>
<div>@@ -232,6 +241,10 @@</div><div>                 return enum</div><div>         raise ValueError("%s is not a valid %s" % (value, cls.__name__))</div><div> </div><div>+    def __init__(self, name, value):</div>
<div>+        self._name = name</div><div>+        self._value = value</div><div>+</div><div>     def __repr__(self):</div><div>         return "<%s.%s: %r>" % (self.__class__.__name__, self._name, self._value)</div>
<div> </div></div><div style>Auto-int implementation:</div><div style><br></div><div style><div><div>class AutoInt(int):</div><div>    __slots__ = ()</div><div><br></div><div>    def __new__(cls, value):</div><div>        if value is Ellipsis:</div>
<div>            try:</div><div>                i = cls._auto_number</div><div>            except AttributeError:</div><div>                i = cls._auto_number = 0</div><div><br></div><div>        else:</div><div>            i = cls._auto_number = value</div>
<div><br></div><div>        cls._auto_number += 1</div><div>        return int.__new__(cls, i)</div><div><br></div><div>class AutoIntEnum(AutoInt, IntEnum):</div><div>    def __init__(self, name, value):</div><div>        super(AutoIntEnum, self).__init__(name, int(self))</div>
<div><br></div><div>class TestAutoIntEnum(AutoIntEnum):</div><div>    a = ...</div><div>    b = 3</div><div>    c = ...</div><div><br></div><div>class TestAutoIntEnum2(AutoIntEnum):</div><div>    a = ...</div><div>    b = ...</div>
<div>    c = ...</div><div><br></div><div>print(TestAutoIntEnum, list(TestAutoIntEnum))</div><div>print(TestAutoIntEnum2, list(TestAutoIntEnum2))</div></div><div><br></div></div><div><div>---------- Run ----------</div><div>
<Enum 'TestAutoIntEnum'> [<TestAutoIntEnum.a: 0>, <TestAutoIntEnum.b: 3>, <TestAutoIntEnum.c: 4>]<br></div><div><Enum 'TestAutoIntEnum2'> [<TestAutoIntEnum2.a: 0>, <TestAutoIntEnum2.b: 1>, <TestAutoIntEnum2.c: 2>]</div>
<div><br></div><div>Tim Delaney<br></div></div></div></div>