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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

76 statements  

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 

5from __future__ import annotations 

6 

7import enum 

8import sys 

9import types 

10import typing 

11import warnings 

12 

13 

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

15# decided deprecation warnings should be invisible by default. 

16class CryptographyDeprecationWarning(UserWarning): 

17 pass 

18 

19 

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

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

22# cycle ends. 

23DeprecatedIn36 = CryptographyDeprecationWarning 

24DeprecatedIn37 = CryptographyDeprecationWarning 

25DeprecatedIn40 = CryptographyDeprecationWarning 

26DeprecatedIn41 = CryptographyDeprecationWarning 

27DeprecatedIn42 = CryptographyDeprecationWarning 

28DeprecatedIn43 = CryptographyDeprecationWarning 

29 

30 

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

32 if not isinstance(value, bytes): 

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

34 

35 

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

37 try: 

38 memoryview(value) 

39 except TypeError: 

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

41 

42 

43def int_to_bytes(integer: int, length: int | None = None) -> bytes: 

44 if length == 0: 

45 raise ValueError("length argument can't be 0") 

46 return integer.to_bytes( 

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

48 ) 

49 

50 

51class InterfaceNotImplemented(Exception): 

52 pass 

53 

54 

55class _DeprecatedValue: 

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

57 self.value = value 

58 self.message = message 

59 self.warning_class = warning_class 

60 

61 

62class _ModuleWithDeprecations(types.ModuleType): 

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

64 super().__init__(module.__name__) 

65 self.__dict__["_module"] = module 

66 

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

68 obj = getattr(self._module, attr) 

69 if isinstance(obj, _DeprecatedValue): 

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

71 obj = obj.value 

72 return obj 

73 

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

75 setattr(self._module, attr, value) 

76 

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

78 obj = getattr(self._module, attr) 

79 if isinstance(obj, _DeprecatedValue): 

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

81 

82 delattr(self._module, attr) 

83 

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

85 return ["_module", *dir(self._module)] 

86 

87 

88def deprecated( 

89 value: object, 

90 module_name: str, 

91 message: str, 

92 warning_class: type[Warning], 

93 name: str | None = None, 

94) -> _DeprecatedValue: 

95 module = sys.modules[module_name] 

96 if not isinstance(module, _ModuleWithDeprecations): 

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

98 dv = _DeprecatedValue(value, message, warning_class) 

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

100 if name is not None: 

101 setattr(module, name, dv) 

102 return dv 

103 

104 

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

106 cached_name = f"_cached_{func}" 

107 sentinel = object() 

108 

109 def inner(instance: object): 

110 cache = getattr(instance, cached_name, sentinel) 

111 if cache is not sentinel: 

112 return cache 

113 result = func(instance) 

114 setattr(instance, cached_name, result) 

115 return result 

116 

117 return property(inner) 

118 

119 

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

121# representation and string representation from Python 3.9. 

122class Enum(enum.Enum): 

123 def __repr__(self) -> str: 

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

125 

126 def __str__(self) -> str: 

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