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
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com