Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/src/zserio/enum.py: 100%
30 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-12-05 10:43 +0000
1"""
2The module provides custom zserio Enum which allows to mark enum items deprecated.
3"""
5import enum
6import typing
7import warnings
10class _EnumType(enum.EnumMeta):
11 """
12 Special enum meta class which fires a warning whenever a deprecated enum item is accessed.
13 """
15 def __getattribute__(cls, name):
16 obj = super().__getattribute__(name)
17 if isinstance(obj, enum.Enum) and obj._is_deprecated:
18 warnings.warn(DeprecationWarning(f"Enum item '{obj}' is deprecated!"), stacklevel=2)
19 return obj
21 def __getitem__(cls, name):
22 member = super().__getitem__(name)
23 if member._is_deprecated:
24 warnings.warn(DeprecationWarning(f"Enum item '{member}' is deprecated!"), stacklevel=2)
25 return member
27 def __call__(cls, value, names=None):
28 # Python 3.12.3 has changed default value for 'names' from 'None' to '_not_given'
29 if names is None:
30 obj = super().__call__(value)
31 else:
32 obj = super().__call__(value, names=names)
33 if isinstance(obj, enum.Enum) and obj._is_deprecated:
34 warnings.warn(DeprecationWarning(f"Enum item '{obj}' is deprecated!"), stacklevel=2)
35 return obj
38class DeprecatedItem:
39 """
40 Marker used to make enum items deprecated.
42 Just use the class instead of creating an instance.
44 Example:
46 .. code:: python
48 import zserio
50 class MyEnum(zserio.Enum):
51 STABLE = 1,
52 OLD = 2, zserio.DeprecatedItem
53 NEW = 3
54 """
57class Enum(enum.Enum, metaclass=_EnumType):
58 """
59 Custom zserio enum base class which allows to mark items deprecated.
60 """
62 def __new__(cls, value: typing.Any, deprecated: typing.Optional[DeprecatedItem] = None):
63 """
64 Creator method which allows to mark the item as deprecated.
66 :param value: The enum item value.
67 :param deprecated: DeprecatedItem or None.
69 :returns: Instance of the enum item.
70 """
72 member = object.__new__(cls)
73 member._value_ = value
74 if deprecated is not None and deprecated != DeprecatedItem:
75 raise ValueError(
76 f"Invalid argument 'deprecated', which is {deprecated}! " f"Expecting {DeprecatedItem} or None."
77 )
78 member._is_deprecated = deprecated is not None # type: ignore[attr-defined]
79 return member