Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/utils.py: 68%

71 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-14 06:36 +0000

1# This file is dual licensed under the terms of the Apache License, Version 

2# 2.0, and the BSD License. See the LICENSE file in the root of this repository 

3# for complete details. 

4 

5 

6import enum 

7import sys 

8import types 

9import typing 

10import warnings 

11 

12 

13# We use a UserWarning subclass, instead of DeprecationWarning, because CPython 

14# decided deprecation warnings should be invisble by default. 

15class CryptographyDeprecationWarning(UserWarning): 

16 pass 

17 

18 

19# Several APIs were deprecated with no specific end-of-life date because of the 

20# ubiquity of their use. They should not be removed until we agree on when that 

21# cycle ends. 

22DeprecatedIn36 = CryptographyDeprecationWarning 

23DeprecatedIn37 = CryptographyDeprecationWarning 

24DeprecatedIn39 = CryptographyDeprecationWarning 

25DeprecatedIn40 = CryptographyDeprecationWarning 

26 

27 

28def _check_bytes(name: str, value: bytes) -> None: 

29 if not isinstance(value, bytes): 

30 raise TypeError(f"{name} must be bytes") 

31 

32 

33def _check_byteslike(name: str, value: bytes) -> None: 

34 try: 

35 memoryview(value) 

36 except TypeError: 

37 raise TypeError(f"{name} must be bytes-like") 

38 

39 

40def int_to_bytes(integer: int, length: typing.Optional[int] = None) -> bytes: 

41 return integer.to_bytes( 

42 length or (integer.bit_length() + 7) // 8 or 1, "big" 

43 ) 

44 

45 

46class InterfaceNotImplemented(Exception): 

47 pass 

48 

49 

50class _DeprecatedValue: 

51 def __init__(self, value: object, message: str, warning_class): 

52 self.value = value 

53 self.message = message 

54 self.warning_class = warning_class 

55 

56 

57class _ModuleWithDeprecations(types.ModuleType): 

58 def __init__(self, module: types.ModuleType): 

59 super().__init__(module.__name__) 

60 self.__dict__["_module"] = module 

61 

62 def __getattr__(self, attr: str) -> object: 

63 obj = getattr(self._module, attr) 

64 if isinstance(obj, _DeprecatedValue): 

65 warnings.warn(obj.message, obj.warning_class, stacklevel=2) 

66 obj = obj.value 

67 return obj 

68 

69 def __setattr__(self, attr: str, value: object) -> None: 

70 setattr(self._module, attr, value) 

71 

72 def __delattr__(self, attr: str) -> None: 

73 obj = getattr(self._module, attr) 

74 if isinstance(obj, _DeprecatedValue): 

75 warnings.warn(obj.message, obj.warning_class, stacklevel=2) 

76 

77 delattr(self._module, attr) 

78 

79 def __dir__(self) -> typing.Sequence[str]: 

80 return ["_module"] + dir(self._module) 

81 

82 

83def deprecated( 

84 value: object, 

85 module_name: str, 

86 message: str, 

87 warning_class: typing.Type[Warning], 

88 name: typing.Optional[str] = None, 

89) -> _DeprecatedValue: 

90 module = sys.modules[module_name] 

91 if not isinstance(module, _ModuleWithDeprecations): 

92 sys.modules[module_name] = module = _ModuleWithDeprecations(module) 

93 dv = _DeprecatedValue(value, message, warning_class) 

94 # Maintain backwards compatibility with `name is None` for pyOpenSSL. 

95 if name is not None: 

96 setattr(module, name, dv) 

97 return dv 

98 

99 

100def cached_property(func: typing.Callable) -> property: 

101 cached_name = f"_cached_{func}" 

102 sentinel = object() 

103 

104 def inner(instance: object): 

105 cache = getattr(instance, cached_name, sentinel) 

106 if cache is not sentinel: 

107 return cache 

108 result = func(instance) 

109 setattr(instance, cached_name, result) 

110 return result 

111 

112 return property(inner) 

113 

114 

115# Python 3.10 changed representation of enums. We use well-defined object 

116# representation and string representation from Python 3.9. 

117class Enum(enum.Enum): 

118 def __repr__(self) -> str: 

119 return f"<{self.__class__.__name__}.{self._name_}: {self._value_!r}>" 

120 

121 def __str__(self) -> str: 

122 return f"{self.__class__.__name__}.{self._name_}"