Coverage for /home/runner/work/zserio/zserio/compiler/extensions/python/runtime/src/zserio/enum.py: 100%

34 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2026-10-19 14:18 +0000

1""" 

2The module provides custom zserio Enum which allows to mark enum items deprecated. 

3""" 

4 

5import enum 

6import typing 

7import warnings 

8 

9 

10class _EnumType(enum.EnumMeta): 

11 """ 

12 Special enum meta class which fires a warning whenever a deprecated enum item is accessed. 

13 """ 

14 

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 

20 

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 

26 

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 

36 

37 

38class DeprecatedItem: 

39 """ 

40 Marker used to make enum items deprecated. 

41 

42 Just use the class instead of creating an instance. 

43 

44 Example: 

45 

46 .. code:: python 

47 

48 import zserio 

49 

50 class MyEnum(zserio.Enum): 

51 STABLE = 1, 

52 OLD = 2, zserio.DeprecatedItem 

53 NEW = 3 

54 """ 

55 

56 

57class Enum(enum.Enum, metaclass=_EnumType): 

58 """ 

59 Custom zserio enum base class which allows to mark items deprecated. 

60 

61 Items of the same enum are ordered by their values. 

62 """ 

63 

64 def __new__(cls, value: typing.Any, deprecated: typing.Optional[DeprecatedItem] = None): 

65 """ 

66 Creator method which allows to mark the item as deprecated. 

67 

68 :param value: The enum item value. 

69 :param deprecated: DeprecatedItem or None. 

70 

71 :returns: Instance of the enum item. 

72 """ 

73 

74 member = object.__new__(cls) 

75 member._value_ = value 

76 if deprecated is not None and deprecated != DeprecatedItem: 

77 raise ValueError( 

78 f"Invalid argument 'deprecated', which is {deprecated}! " f"Expecting {DeprecatedItem} or None." 

79 ) 

80 member._is_deprecated = deprecated is not None # type: ignore[attr-defined] 

81 return member 

82 

83 def __lt__(self, other: object) -> bool: 

84 if self.__class__ is other.__class__: 

85 return self.value < other.value # type: ignore[attr-defined] 

86 

87 return NotImplemented