pythonenumsmetaprogrammingpython-3.5metaclass

Python Enum combination


I would like to create a new Enum (IntEnum) class based on two existing ones. There is a working solution for this, like so:

from enum import unique, IntEnum
from itertools import chain
from collections import OrderedDict

@unique
class FirstEnumClass(IntEnum):
    a = 1
    b = 2

@unique
class SecondEnumClass(IntEnum):
    c = 3
    d = 4

# here a combined class is created:
CombinedEnumClass = unique(IntEnum('CombinedEnumClass', OrderedDict([(i.name, i.value) for i in chain(FirstEnumClass, SecondEnumClass)])))

My question: is there a fancy way to achieve this, so that there is a proper class definition? Like overriding some of the metaclass methods, or so? I would like something like this, so that docstring can also be given:

@unique
class CombinedEnumClass(IntEnum):
    """ docstring """
    # magic needed here

Any idea? Thanks!


Solution

  • The library prevents explicitly to do that:

    Subclassing an enumeration is allowed only if the enumeration does not define any members.

    Allowing subclassing of enums that define members would lead to a violation of some important invariants of types and instances. On the other hand, it makes sense to allow sharing some common behavior between a group of enumerations.

    Therefore, I found a Stackoverflow answer using almost the same workaround as you do. I think this is the only way.