Coverage for plugins/module_utils/generic.py: 100%

62 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-04-15 00:57 +0200

1import pathlib 

2from functools import partial 

3from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Type, Union 

4 

5__all__ = ( 

6 "Types", 

7 "SYSTEMD_SERVICE_CONFIG", 

8 "SYSTEMD_NETWORK_CONFIG", 

9 "SYSTEMD_CONFIG_ROOT", 

10) 

11 

12 

13SYSTEMD_CONFIG_ROOT = pathlib.Path("/etc/systemd") 

14SYSTEMD_NETWORK_CONFIG = SYSTEMD_CONFIG_ROOT / "network" 

15SYSTEMD_SERVICE_CONFIG = SYSTEMD_CONFIG_ROOT / "system" 

16 

17 

18class _sdict(dict): 

19 _help: Optional[str] 

20 __name__: str 

21 

22 

23class _Type(type): 

24 def __new__(metacls, cls, bases, classdict, **kwds): 

25 individual = dict() 

26 virtfunc = None 

27 virtual = () 

28 special = dict() 

29 for key, value in classdict.items(): 

30 if key.startswith("_"): 

31 if key == "__getattr__": 

32 virtfunc = value 

33 elif key == "__dir__": 

34 virtual = tuple(value(None)) 

35 elif key in ("__doc__",): 

36 special[key] = value 

37 else: 

38 individual[key] = value 

39 if len(virtual) != 0 and virtfunc is None: # pragma: nocover 

40 raise TypeError( 

41 "Virtual funcs defined, but no func to generate them defined" 

42 ) 

43 special["_attr"] = tuple(virtual + tuple(individual.keys())) 

44 special["_vfunc"] = virtfunc 

45 special["_virtual"] = virtual 

46 special["_individual"] = individual 

47 annotations = dict() 

48 if len(virtual) != 0 and virtfunc is not None: # pragma: nocover 

49 anno = virtfunc(None, virtual[0]).__annotations__ 

50 for virtualkey in virtual: 

51 annotations[virtualkey] = Callable[[*anno.values()], Dict[str, Any]] 

52 annotations["__dir__"] = Callable[[], Tuple[str]] 

53 special["__annotations__"] = annotations 

54 inst = super().__new__(metacls, cls, bases, special, **kwds) 

55 return inst 

56 

57 def __getattribute__(self, __name: str) -> Any: 

58 if __name in ( 

59 "__dict__", 

60 "__doc__", 

61 "_attr", 

62 "__annotations__", 

63 "_virtual", 

64 "_vfunc", 

65 "_individual", 

66 ): 

67 return super().__getattribute__(__name) 

68 if __name in self._virtual: 

69 return self._vfunc(self, __name) 

70 if __name in self._individual: 

71 return partial(self._individual[__name], self) 

72 raise AttributeError(f"Attribut {__name} not found.") 

73 

74 

75class Types(metaclass=_Type): 

76 """Provides helpers for the ansible types""" 

77 

78 def list( 

79 self, 

80 elements: Union[Type[object], str], 

81 required: bool = False, 

82 help: Optional[str] = None, 

83 ) -> dict: 

84 if not isinstance(elements, str): 

85 elements = elements.__name__ 

86 option = _sdict(type="list", elements=elements, required=required) 

87 option._help = help 

88 return option 

89 

90 def __dir__(self) -> tuple: 

91 return ( 

92 "str", 

93 "dict", 

94 "bool", 

95 "int", 

96 "float", 

97 "path", 

98 "raw", 

99 "jsonarg", 

100 "json", 

101 "bytes", 

102 "bits", 

103 ) 

104 

105 def __getattr__(self, name: str): 

106 def argument( 

107 required: bool = False, 

108 help: Optional[str] = None, 

109 choices: Optional[Sequence] = None, 

110 default: Optional[Any] = None, 

111 ): 

112 output = _sdict(type=name, required=required) 

113 if choices is not None: 

114 output["choices"] = choices 

115 if default is not None: 

116 output["default"] = default 

117 output._help = help 

118 return output 

119 

120 argument.__name__ = name 

121 return argument