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

28 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2024-04-30 09:38 +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, *, module=None, qualname=None, type_=None, start=1): 

28 obj = super().__call__(value, names, module=module, qualname=qualname, type=type_, start=start) 

29 if isinstance(obj, enum.Enum) and obj._is_deprecated: 

30 warnings.warn(DeprecationWarning(f"Enum item '{obj}' is deprecated!"), stacklevel=2) 

31 return obj 

32 

33 

34class DeprecatedItem: 

35 """ 

36 Marker used to make enum items deprecated. 

37 

38 Just use the class instead of creating an instance. 

39 

40 Example: 

41 

42 .. code:: python 

43 

44 import zserio 

45 

46 class MyEnum(zserio.Enum): 

47 STABLE = 1, 

48 OLD = 2, zserio.DeprecatedItem 

49 NEW = 3 

50 """ 

51 

52 

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

54 """ 

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

56 """ 

57 

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

59 """ 

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

61 

62 :param value: The enum item value. 

63 :param deprecated: DeprecatedItem or None. 

64 

65 :returns: Instance of the enum item. 

66 """ 

67 

68 member = object.__new__(cls) 

69 member._value_ = value 

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

71 raise ValueError( 

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

73 ) 

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

75 return member