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(_ProtoEnum):
    """
    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(_ProtoEnum):
    HUE_UNSPECIFIED = ("HUE_UNSPECIFIED", 0)
    HUE_RED = ("HUE_RED", 1)
    HUE_BLUE = ("HUE_BLUE", 2)

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(_ProtoEnum):
    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(_ProtoEnum):
    """
    A primary hue.
    """

    UNSPECIFIED = ("UNSPECIFIED", 0)
    RED = ("RED", 1)
    BLUE = ("BLUE", 2)


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

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

Note: All generated enums use _ProtoEnum as their base class. Each member exposes a .number attribute with the proto integer, and a .options property for enum value options. 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", 0)
    ACTIVE = ("ACTIVE", 1)
    INACTIVE = ("INACTIVE", 2)
    ARCHIVED = (
        "ARCHIVED",
        3,
        _EnumValueOptions(deprecated=True, debug_redact=True),
    )

Every generated enum uses _ProtoEnum as its base class. Each member exposes a .number attribute with the proto integer value, and a .options property for enum value options. When an enum value carries options, they are passed as a tuple element alongside the value.

Custom extensions

Custom enum value options are also preserved:

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

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

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"}