Skip to content

Enums

Proto3 enums become Python Enum subclasses. The generator supports string-valued enums (default), integer-valued enums (opt-in), enum value options, and the well-known auto_trim_enum_prefix behaviour.

Basic enum

By default, enums use str as the mixin type and string names as values:

enum Hue {
  HUE_UNSPECIFIED = 0;
  HUE_RED         = 1;
  HUE_BLUE        = 2;
}
class Hue(str, _Enum):
    """
    A primary hue.
    """

    UNSPECIFIED = "UNSPECIFIED"  # 0
    RED = "RED"  # 1
    BLUE = "BLUE"  # 2

Prefix trimming (auto_trim_enum_prefix)

The default auto_trim_enum_prefix=true removes the enum type name prefix from value names. The prefix match is case-insensitive and strips a trailing _:

HUE_UNSPECIFIED → UNSPECIFIED
HUE_RED         → RED

With auto_trim_enum_prefix=false the full name is kept:

class Hue(str, _Enum):
    HUE_UNSPECIFIED = "HUE_UNSPECIFIED"
    HUE_RED = "HUE_RED"
    HUE_BLUE = "HUE_BLUE"

See Plugin Options for details.

Integer enums (use_integers_for_enums)

With use_integers_for_enums=true, the mixin type becomes int and values are integers:

class Hue(int, _Enum):
    UNSPECIFIED = 0
    RED = 1
    BLUE = 2

See Plugin Options for details.

Top-level vs. nested enums

Enums defined at the file level become top-level classes. Enums defined inside a message become nested classes of that message:

// Top-level enum
enum Hue {
  HUE_UNSPECIFIED = 0;
  HUE_RED         = 1;
  HUE_BLUE        = 2;
}

message Shape {
  // Nested enum
  enum Kind {
    KIND_UNSPECIFIED = 0;
    KIND_CIRCLE      = 1;
    KIND_SQUARE      = 2 [deprecated = true];
  }

  Hue  color = 1;
  Kind kind  = 2;
}
class Hue(str, _Enum):
    """
    A primary hue.
    """

    UNSPECIFIED = "UNSPECIFIED"  # 0
    RED = "RED"  # 1
    BLUE = "BLUE"  # 2


class Shape(_ProtoModel):
    class Kind(_ProtoEnum):
        UNSPECIFIED = (
            "UNSPECIFIED",
            _EnumValueOptions(number=0),
        )  # 0
        CIRCLE = (
            "CIRCLE",
            _EnumValueOptions(number=1),
        )  # 1
        SQUARE = (
            "SQUARE",
            _EnumValueOptions(number=2, deprecated=True),
        )  # 2

    color: "Hue | None" = _Field(default=None)
    kind: "Shape.Kind | None" = _Field(default=None)

Note: KIND_SQUARE carries [deprecated = true], so Shape.Kind is generated as _ProtoEnum with value tuples instead of plain str, _Enum. See Enum value options below.

Enum value options

Proto3 enum values can carry options (built-in or custom). These are preserved as accessible metadata on the Python enum members.

Built-in: deprecated and debug_redact

enum Status {
  STATUS_UNSPECIFIED = 0;
  STATUS_ACTIVE      = 1;
  STATUS_INACTIVE    = 2;
  STATUS_ARCHIVED    = 3 [deprecated = true, debug_redact = true];
}
class Status(_ProtoEnum):
    """
    Status enum with value options.
    """

    UNSPECIFIED = (
        "UNSPECIFIED",
        _EnumValueOptions(number=0),
    )  # 0
    ACTIVE = (
        "ACTIVE",
        _EnumValueOptions(number=1),
    )  # 1
    INACTIVE = (
        "INACTIVE",
        _EnumValueOptions(number=2),
    )  # 2
    ARCHIVED = (
        "ARCHIVED",
        _EnumValueOptions(number=3, deprecated=True, debug_redact=True),
    )  # 3

When any enum value in a file carries options, the generator switches from plain str, _Enum to _ProtoEnum (a thin subclass) and stores options as a second tuple element. Each member's options are accessible via the .options property.

Custom extensions

Custom enum value options are also preserved:

class Currency(_ProtoEnum):
    """
    Currency enum with custom options.
    """

    UNSPECIFIED = (
        "UNSPECIFIED",
        _EnumValueOptions(number=0),
    )  # 0
    USD = (
        "USD",
        _EnumValueOptions(
            number=1,
            display_name="US Dollar",
            is_default=True,
            priority=1,
            rank=1,
            rate=1.5,
            serial=1000,
            version=1,
            weight=1,
        ),
    )  # 1
    EUR = (
        "EUR",
        _EnumValueOptions(
            number=2,
            display_name="Euro",
            is_default=False,
            priority=2,
        ),
    )  # 2
    GBP = (
        "GBP",
        _EnumValueOptions(
            number=3,
            display_name="British Pound",
        ),
    )  # 3

Enum in JSON / dict

Because enum values default to string names (with auto_trim_enum_prefix=true), they serialize to ProtoJSON-compatible strings:

import json

from enums_pydantic import Hue

print(json.dumps({"hue": Hue.RED}))
# {"hue": "RED"}