Source code for uds.utilities.enums

"""Module with special `Enums <https://en.wikipedia.org/wiki/Enumerated_type#Python>`_ implementations."""

__all__ = ["ExtendableEnum", "ValidatedEnum", "ByteEnum", "NibbleEnum"]

from typing import Any

from aenum import Enum, IntEnum, extend_enum


[docs]class ExtendableEnum(Enum): """Enum that supports new members adding."""
[docs] @classmethod def add_member(cls, name: str, value: Any) -> Enum: """ Register a new member. :param name: Name of a new member. :param value: Value of a new member. :raise ValueError: Such name or value is already in use. :return: The new member that was just created. """ for member in cls: # type: ignore if member.name == name: raise ValueError(f"Name '{name}' is already in use.") if member.value == value: raise ValueError(f"Value '{value}' is already in use.") extend_enum(cls, name, value) return cls[name] # type: ignore
[docs]class ValidatedEnum(Enum): """Enum that supports members validation."""
[docs] @classmethod def is_member(cls, value: Any) -> bool: """ Check whether given argument is a member or a value stored by this Enum. :param value: Value to check. :return: True if given argument is a member or a value of this Enum, else False. """ try: cls(value) except ValueError: return False return True
[docs] @classmethod def validate_member(cls, value: Any) -> None: """ Validate whether given argument is a member or a value stored by this Enum. :param value: Value to validate. :raise TypeError: Provided value is not a member neither a value of this Enum. """ if not cls.is_member(value): raise ValueError(f"Provided value is not a member of this Enum. Actual value: {value}.")
[docs]class ByteEnum(IntEnum): """Enum which members are one byte integers (0x00-0xFF) only.""" def __new__(cls, value: int): """ Creation of a new member. :param value: One byte integer. :raise TypeError: Provided value is not int type. :raise ValueError: Provided value is not in inclusive range 0x00-0xFF. """ if not isinstance(value, int): raise TypeError(f"Provided 'value' is not int type. Actual type: {type(value)}.") if not 0x00 <= value <= 0xFF: raise ValueError(f"Provided 'value' is not in range 0x00-0xFF. Actual value = {value}.") member = int.__new__(cls, value) member._value_ = value # noqa: F841 return member
[docs]class NibbleEnum(IntEnum): """Enum which members are one nibble (4 bits) integers (0x0-0xF) only.""" def __new__(cls, value: int): """ Creation of a new member. :param value: One nibble (4 bits) integer. :raise TypeError: Provided value is not int type. :raise ValueError: Provided value is not in inclusive range 0x0-0xF. """ if not isinstance(value, int): raise TypeError(f"Provided 'value' is not int type. Actual type: {type(value)}.") if not 0x0 <= value <= 0xF: raise ValueError(f"Provided 'value' is not in range 0x0-0xF. Actual value = {value}.") member = int.__new__(cls, value) member._value_ = value # noqa: F841 return member