[Python-Dev] PEP 435 - requesting pronouncement

Tim Delaney timothy.c.delaney at gmail.com
Sun May 5 01:27:25 CEST 2013


Typo line 171: <Colro.blue: 3>

One thing I'd like to be clear in the PEP about is whether enum_type and
_EnumDict._enum_names should be documented, or whether they're considered
implementation details.

I'd like to make a subclass of Enum that accepts ... for auto-valued enums
but that requires subclassing the metaclass and access to
classdict._enum_names. I can get to enum_type via type(Enum), but
_EnumDict._enum_names requires knowing the attribute. It would sufficient
for my purposes if it was just documented that the passed classdict had a
_enum_names attribute.

In testing the below, I've also discovered a bug in the reference
implementation - currently it will not handle an __mro__ like:

(<Enum 'AutoIntEnum'>, <Enum 'IntEnum'>, <class 'int'>, <Enum 'Enum'>,
<class 'object'>)

Apply the following patch to make that work:

diff -r 758d43b9f732 ref435.py
--- a/ref435.py Fri May 03 18:59:32 2013 -0700
+++ b/ref435.py Sun May 05 09:23:25 2013 +1000
@@ -116,7 +116,11 @@
             if bases[-1] is Enum:
                 obj_type = bases[0]
             else:
-                obj_type = bases[-1].__mro__[1] # e.g. (IntEnum, int,
Enum, object)
+                for base in bases[-1].__mro__:
+                    if not issubclass(base, Enum):
+                        obj_type = base
+                        break
+
         else:
             obj_type = object
         # save enum items into separate mapping so they don't get baked
into

My auto-enum implementation (using the above patch - without it you can get
the essentially the same results with class AutoIntEnum(int, Enum,
metaclass=auto_enum).

class auto_enum(type(Enum)):
    def __new__(metacls, cls, bases, classdict):
        temp = type(classdict)()
        names = set(classdict._enum_names)
        i = 0

        for k in classdict._enum_names:
            v = classdict[k]

            if v is Ellipsis:
                v = i
            else:
                i = v

            i += 1
            temp[k] = v

        for k, v in classdict.items():
            if k not in names:
                temp[k] = v

        return super(auto_enum, metacls).__new__(metacls, cls, bases, temp)

class AutoNumberedEnum(Enum, metaclass=auto_enum):
    pass

class AutoIntEnum(IntEnum, metaclass=auto_enum):
    pass

class TestAutoNumber(AutoNumberedEnum):
    a = ...
    b = 3
    c = ...

class TestAutoInt(AutoIntEnum):
    a = ...
    b = 3
    c = ...

print(TestAutoNumber, list(TestAutoNumber))
print(TestAutoInt, list(TestAutoInt))

---------- Run ----------
<Enum 'TestAutoNumber'> [<TestAutoNumber.a: 0>, <TestAutoNumber.b: 3>,
<TestAutoNumber.c: 4>]
<Enum 'TestAutoInt'> [<TestAutoInt.a: 0>, <TestAutoInt.b: 3>,
<TestAutoInt.c: 4>]

Tim Delaney
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20130505/ebc64679/attachment.html>


More information about the Python-Dev mailing list