← Back to list

A Problem with Combined Enum in Python

Try not to use combined Enum if possible

Lynn G. Kwong in Level Up Coding · 2024-10-20 08:24 · 104 claps · 2.6 min read paywalled
#python #enum #typing #pyright #issues
Open on Medium ↗

A Problem with Combined Enum in Python

Try not to use combined Enum if possible

Image by makbonae on Pixabay

Image by makbonae on Pixabay

Sometimes we may want to create a combined Enum which includes all the elements of other Enum classes. For example, we may want to create an Enum for the AI models of each AI platform like OpenAI, Gemini, Claude, etc, and use it as a common entry for all the AI models. In this post, we will introduce the problem with such a solution and why we should avoid using it in practice.

[embed]https://youtube.com/@kwonglynn

Create a combined Enum

In Python, we cannot directly combine two Enum classes in the sense of merging them into a new Enum that contains all members of both. We cannot subclass multiple Enum classes to create a new Enum that inherits members from both either. A feasible solution is to create the combined Enum dynamically using the functional API of Enum.

from enum import IntEnum

class EnumA(IntEnum):
    OPTION_A = 1
    OPTION_B = 2

class EnumB(IntEnum):
    OPTION_C = 3
    OPTION_D = 4

CombinedEnum = IntEnum(
    "CombinedEnum",
    {**EnumA.__members__, **EnumB.__members__},
)

print(EnumA.OPTION_A) # 1
print(EnumB.OPTION_C) # 3
print(CombinedEnum.OPTION_A) # 1
print(CombinedEnum.OPTION_C) # 3

In this solution, we call the Enum class or its subclass which is IntEnum in this example as a function and pass the Enum name and Enum members to create a new Enum dynamically. When we check the members of the combined Enum created, it seems working properly.

Add a class method to the combined Enum

To add a class method to a combined Enum, we can first create a custom Base Enum that defines the class method and then create the combined Enum with this Base Enum.

from enum import IntEnum

class EnumA(IntEnum):
    OPTION_A = 1
    OPTION_B = 2

class EnumB(IntEnum):
    OPTION_C = 3
    OPTION_D = 4

class BaseEnum(IntEnum):
    @classmethod
    def includes(cls, name):
        return name in cls.__members__

CombinedEnum = BaseEnum(
    "CombinedEnum",
    {**EnumA.__members__, **EnumB.__members__},
)

print(CombinedEnum.includes("OPTION_A"))  # True

This is rarely used, I just want to introduce it as we happen to have it in our project. The class method added in this way for the combined Enum can be detected by IDEs and type checkers like mypy and pyright.

The problem of combined Enum in static typing

However, the critical issue with the combined Enum solution presented above is just with static type checkers. When the code is checked with a static type checker, we will encounter these two errors.

def print_option(option: CombinedEnum):
    print(option.value)
# error: Variable not allowed in type expression

print_option(CombinedEnum.OPTION_A)
# error: Cannot access attribute "OPTION_A" for class "IntEnum"

Firstly, the combined Enum cannot be used as a type for function arguments. The error message is “Variable not allowed in type expression”. This error occurs because when you create an Enum class using the functional API, the resulting class is not recognized by static type checkers during type analysis, since the class is created at runtime, and type checkers analyze code statically. The other error says that the Enum attribute cannot be accessed. The reason is the same. The dynamic class is only created at runtime, and thus the attributes are not available in static code checking.

As a result, we will end up in an awkward situation. The code would run successfully if you run it directly. However, it will fail static code checking by type checkers. We have done some studies and found this issue cannot be solved for the time being as it’s due to the nature of the Python programming language. In fact, we should avoid using combined Enums because Enums are by design immutable in Python and thus don’t allow subclassing. We should use Enums properly and refactor our code to make it work properly with individual Enums instead.

Related content


메타데이터
post_id
c3e065597794
slug
a-problem-with-combined-enum-in-python-c3e065597794
url
https://levelup.gitconnected.com/a-problem-with-combined-enum-in-python-c3e065597794
canonical_url
https://levelup.gitconnected.com/a-problem-with-combined-enum-in-python-c3e065597794
author_url
https://medium.com/@lynn-kwong
status
ok
fetched_at
2026-07-09 06:39:14