Skip to content

enum — Support for Enumerations

An enumeration is a set of symbolic names (members) bound to unique, constant values. Using raw strings ("pending", "active") or arbitrary integers (0, 1, 2) for state flags leads to subtle bugs: typos in strings pass silently, magic integers lack meaning, and invalid values cannot be prevented.

The standard library enum module (PEP 435) provides strongly-typed enumerations that eliminate these failure modes.


Basic Enumeration with Enum

Define an enumeration by subclassing Enum:

from enum import Enum

class OrderStatus(Enum):
    PENDING = "pending"
    PROCESSING = "processing"
    SHIPPED = "shipped"
    DELIVERED = "delivered"
    CANCELLED = "cancelled"

# Access members
status = OrderStatus.PENDING

# Inspect name and value
print(status.name)   # "PENDING"
print(status.value)  # "pending"

Identity and Equality

Enum members are singletons. Use is or == for comparisons:

# Both identity and equality checks work:
if status is OrderStatus.PENDING:
    print("Order is awaiting payment confirmation.")

# Member identity is unique:
print(OrderStatus.PENDING == OrderStatus.SHIPPED)  # False

Automatic Values with auto()

When the specific values do not matter (only distinct symbolic identities are required), use auto() to assign sequential values automatically:

from enum import Enum, auto

class Direction(Enum):
    NORTH = auto()  # 1
    EAST = auto()   # 2
    SOUTH = auto()  # 3
    WEST = auto()   # 4

print(Direction.NORTH.value)  # 1

Enforcing Uniqueness with @unique

By default, Python allows multiple enum member names to share the same value (creating aliases). To disallow aliases and raise ValueError on duplicates, decorate with @enum.unique:

from enum import Enum, unique

@unique
class HttpCode(Enum):
    OK = 200
    NOT_FOUND = 404
    SERVER_ERROR = 500
    # Duplicate value raises ValueError:
    # BAD_GATEWAY = 500

Specialized Enum Subclasses

1. StrEnum (Python 3.11+)

StrEnum members inherit directly from str. They can be used directly wherever a string is expected, making them ideal for JSON serialization and API schemas:

from enum import StrEnum

class FileFormat(StrEnum):
    JSON = "json"
    CSV = "csv"
    PARQUET = "parquet"

# Directly usable in string operations
print(f"Exporting to {FileFormat.CSV} format.")
print(FileFormat.JSON.endswith("on"))  # True

2. IntEnum

IntEnum members inherit from int and can be compared directly with integers:

from enum import IntEnum

class Priority(IntEnum):
    LOW = 1
    MEDIUM = 2
    HIGH = 3

print(Priority.HIGH > Priority.LOW)  # True
print(Priority.HIGH == 3)            # True (compares with raw int)

3. Bitwise Flags with Flag and IntFlag

Flag supports bitwise operations (|, &, ~) to represent combinations of permissions or options:

from enum import Flag, auto

class Permission(Flag):
    READ = auto()     # 1 (0b001)
    WRITE = auto()    # 2 (0b010)
    EXECUTE = auto()  # 4 (0b100)

# Combine flags with bitwise OR
user_perms = Permission.READ | Permission.WRITE

# Check if a specific permission is granted
print(Permission.READ in user_perms)     # True
print(Permission.EXECUTE in user_perms)  # False
print(repr(user_perms))                  # <Permission.READ|WRITE: 3>

Accessing Members Dynamically

Convert between raw values/strings and Enum members:

# Lookup by name (string):
status = OrderStatus["SHIPPED"]
print(status)  # OrderStatus.SHIPPED

# Lookup by value:
status_by_val = OrderStatus("delivered")
print(status_by_val)  # OrderStatus.DELIVERED

# Safe lookup with fallback:
try:
    invalid = OrderStatus("unknown")
except ValueError:
    print("Invalid order status supplied!")

Adding Methods to Enums

Enums are full Python classes and can define methods and properties:

class Mood(Enum):
    HAPPY = 1
    TIRED = 2
    ENERGIZED = 3

    def describe(self) -> str:
        descriptions = {
            Mood.HAPPY: "Feeling cheerful and productive!",
            Mood.TIRED: "Needs a fresh cup of coffee.",
            Mood.ENERGIZED: "Ready to conquer the backlog!"
        }
        return descriptions[self]

print(Mood.HAPPY.describe())
Feeling cheerful and productive!