Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/cryptography/utils.py : 63%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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.
6import abc
7import inspect
8import sys
9import typing
10import warnings
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
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.
22PersistentlyDeprecated2017 = CryptographyDeprecationWarning
23PersistentlyDeprecated2019 = CryptographyDeprecationWarning
24DeprecatedIn34 = CryptographyDeprecationWarning
27def _check_bytes(name: str, value: bytes):
28 if not isinstance(value, bytes):
29 raise TypeError("{} must be bytes".format(name))
32def _check_byteslike(name: str, value: bytes):
33 try:
34 memoryview(value)
35 except TypeError:
36 raise TypeError("{} must be bytes-like".format(name))
39def read_only_property(name: str):
40 return property(lambda self: getattr(self, name))
43def register_interface(iface):
44 def register_decorator(klass, *, check_annotations=False):
45 verify_interface(iface, klass, check_annotations=check_annotations)
46 iface.register(klass)
47 return klass
49 return register_decorator
52def register_interface_if(predicate, iface):
53 def register_decorator(klass, *, check_annotations=False):
54 if predicate:
55 verify_interface(iface, klass, check_annotations=check_annotations)
56 iface.register(klass)
57 return klass
59 return register_decorator
62def int_to_bytes(integer: int, length: typing.Optional[int] = None) -> bytes:
63 return integer.to_bytes(
64 length or (integer.bit_length() + 7) // 8 or 1, "big"
65 )
68class InterfaceNotImplemented(Exception):
69 pass
72def strip_annotation(signature):
73 return inspect.Signature(
74 [
75 param.replace(annotation=inspect.Parameter.empty)
76 for param in signature.parameters.values()
77 ]
78 )
81def verify_interface(iface, klass, *, check_annotations=False):
82 for method in iface.__abstractmethods__:
83 if not hasattr(klass, method):
84 raise InterfaceNotImplemented(
85 "{} is missing a {!r} method".format(klass, method)
86 )
87 if isinstance(getattr(iface, method), abc.abstractproperty):
88 # Can't properly verify these yet.
89 continue
90 sig = inspect.signature(getattr(iface, method))
91 actual = inspect.signature(getattr(klass, method))
92 if check_annotations:
93 ok = sig == actual
94 else:
95 ok = strip_annotation(sig) == strip_annotation(actual)
96 if not ok:
97 raise InterfaceNotImplemented(
98 "{}.{}'s signature differs from the expected. Expected: "
99 "{!r}. Received: {!r}".format(klass, method, sig, actual)
100 )
103class _DeprecatedValue(object):
104 def __init__(self, value, message, warning_class):
105 self.value = value
106 self.message = message
107 self.warning_class = warning_class
110class _ModuleWithDeprecations(object):
111 def __init__(self, module):
112 self.__dict__["_module"] = module
114 def __getattr__(self, attr):
115 obj = getattr(self._module, attr)
116 if isinstance(obj, _DeprecatedValue):
117 warnings.warn(obj.message, obj.warning_class, stacklevel=2)
118 obj = obj.value
119 return obj
121 def __setattr__(self, attr, value):
122 setattr(self._module, attr, value)
124 def __delattr__(self, attr):
125 obj = getattr(self._module, attr)
126 if isinstance(obj, _DeprecatedValue):
127 warnings.warn(obj.message, obj.warning_class, stacklevel=2)
129 delattr(self._module, attr)
131 def __dir__(self):
132 return ["_module"] + dir(self._module)
135def deprecated(value, module_name, message, warning_class):
136 module = sys.modules[module_name]
137 if not isinstance(module, _ModuleWithDeprecations):
138 sys.modules[module_name] = _ModuleWithDeprecations(
139 module
140 ) # type: ignore[assignment]
141 return _DeprecatedValue(value, message, warning_class)
144def cached_property(func):
145 cached_name = "_cached_{}".format(func)
146 sentinel = object()
148 def inner(instance):
149 cache = getattr(instance, cached_name, sentinel)
150 if cache is not sentinel:
151 return cache
152 result = func(instance)
153 setattr(instance, cached_name, result)
154 return result
156 return property(inner)
159int_from_bytes = deprecated(
160 int.from_bytes,
161 __name__,
162 "int_from_bytes is deprecated, use int.from_bytes instead",
163 DeprecatedIn34,
164)