hbutils.model.enum

Enum utilities for enhanced IntEnum usage.

This module provides helpers that extend standard enum.IntEnum classes with automatic value assignment and flexible parsing utilities. It includes:

  • AutoIntEnum - An enum.IntEnum subclass that auto-assigns sequential integer values.

  • int_enum_loads() - A decorator that adds a robust loads class method to enum.IntEnum subclasses.

These tools are useful when you want clean, declarative enum definitions while still supporting convenient parsing of values from integers, strings, or custom types.

Example:

>>> from enum import IntEnum, unique
>>> from hbutils.model.enum import AutoIntEnum, int_enum_loads
>>>
>>> class Color(AutoIntEnum):
...     def __init__(self, code: str) -> None:
...         self.code = code
...     RED = "#ff0000"
...     BLUE = "#0000ff"
>>>
>>> Color.RED.value
1
>>> Color.RED.code
'#ff0000'
>>>
>>> @int_enum_loads()
>>> @unique
... class Status(IntEnum):
...     OK = 1
...     FAILED = 2
>>>
>>> Status.loads(1) is Status.OK
True
>>> Status.loads("FAILED") is Status.FAILED
True

Note

The loads method performs cached lookups, which is efficient for repeated parsing. Preprocessors can be used to normalize input values.

__all__

hbutils.model.enum.__all__ = ['AutoIntEnum', 'int_enum_loads']

Built-in mutable sequence.

If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.

AutoIntEnum

class hbutils.model.enum.AutoIntEnum(value)[source]

An enum.IntEnum subclass with automatically assigned values.

This class assigns sequential integer values starting from 1 to each enum member. You can still define custom initialization values via __init__ while the underlying enum value is managed automatically.

This implementation follows the official Python documentation example: https://docs.python.org/3/library/enum.html#using-a-custom-new

Examples:

>>> from hbutils.model import AutoIntEnum
>>> class MyEnum(AutoIntEnum):
...     def __init__(self, v):
...         self.v = v
...     A = 'a_v'
...     B = 'b_vv'
...     C = 'c_vvv'
...
>>> MyEnum.A
<MyEnum.A: 1>
>>> MyEnum.A.value
1
>>> MyEnum.A.v
'a_v'
>>> MyEnum.C
<MyEnum.C: 3>
>>> MyEnum.C.value
3
>>> MyEnum.C.v
'c_vvv'
__new__(value)

int_enum_loads

hbutils.model.enum.int_enum_loads(enable_int: bool = True, value_preprocess: Callable[[int], int] | None = None, enable_str: bool = True, name_preprocess: Callable[[str], str] | None = None, external_process: Callable[[Any], _EnumType | None] | None = None) Callable[[Type[_EnumType]], Type[_EnumType]][source]

Decorate an enum.IntEnum class with a loads class method.

The resulting loads method supports:

  • Direct enum member passthrough

  • Integer value lookups (optionally preprocessed)

  • String name lookups (optionally preprocessed)

  • Custom external processing for other types

Parameters:
  • enable_int (bool) – Whether to allow integer parsing, defaults to True.

  • value_preprocess (Optional[Callable[[int], int]]) – Preprocessor for integer values prior to lookup. If None, the identity function is used.

  • enable_str (bool) – Whether to allow string name parsing, defaults to True.

  • name_preprocess (Optional[Callable[[str], str]]) – Preprocessor for string names prior to lookup. If None, the identity function is used.

  • external_process (Optional[Callable[[Any], Optional[_EnumType]]]) – Handler for unrecognized data types. If None, a TypeError is raised.

Returns:

A decorator that enhances an enum.IntEnum class.

Return type:

Callable[[Type[_EnumType]], Type[_EnumType]]

Raises:

TypeError – If the decorated class is not a subclass of enum.IntEnum.

Examples:

  • Simple usage:

    >>> from enum import IntEnum, unique
    >>>
    >>> @int_enum_loads()
    >>> @unique
    ... class MyEnum(IntEnum):
    ...     A = 1
    ...     B = 2
    >>>
    >>> MyEnum.loads(1)    # MyEnum.A
    >>> MyEnum.loads('A')  # MyEnum.A
    >>> MyEnum.loads(2)    # MyEnum.B
    >>> MyEnum.loads('B')  # MyEnum.B
    >>> MyEnum.loads(-1)   # KeyError
    >>> MyEnum.loads('a')  # KeyError
    >>> MyEnum.loads('C')  # KeyError
    
  • Preprocessors:

    >>> from enum import IntEnum, unique
    >>>
    >>> @int_enum_loads(name_preprocess=str.upper, value_preprocess=abs)
    >>> @unique
    ... class MyEnum(IntEnum):
    ...     A = 1
    ...     B = 2
    >>>
    >>> MyEnum.loads(1)    # MyEnum.A
    >>> MyEnum.loads('A')  # MyEnum.A
    >>> MyEnum.loads(2)    # MyEnum.B
    >>> MyEnum.loads('B')  # MyEnum.B
    >>> MyEnum.loads(-1)   # MyEnum.A
    >>> MyEnum.loads('a')  # MyEnum.A
    >>> MyEnum.loads('C')  # KeyError
    
  • External processor:

    >>> from enum import IntEnum, unique
    >>>
    >>> @int_enum_loads(external_process=lambda data: None)
    >>> @unique
    ... class MyEnum(IntEnum):
    ...     A = 1
    ...     B = 2
    >>>
    >>> MyEnum.loads(1)    # MyEnum.A
    >>> MyEnum.loads('A')  # MyEnum.A
    >>> MyEnum.loads(2)    # MyEnum.B
    >>> MyEnum.loads('B')  # MyEnum.B
    >>> MyEnum.loads(-1)   # None
    >>> MyEnum.loads('a')  # None
    >>> MyEnum.loads('C')  # None