mirror of
				https://gitlab.sectorq.eu/jaydee/omv_backup.git
				synced 2025-10-30 18:11:10 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			128 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| # This file is dual licensed under the terms of the Apache License, Version
 | |
| # 2.0, and the BSD License. See the LICENSE file in the root of this repository
 | |
| # for complete details.
 | |
| 
 | |
| from __future__ import annotations
 | |
| 
 | |
| import enum
 | |
| import sys
 | |
| import types
 | |
| import typing
 | |
| import warnings
 | |
| 
 | |
| 
 | |
| # We use a UserWarning subclass, instead of DeprecationWarning, because CPython
 | |
| # decided deprecation warnings should be invisible by default.
 | |
| class CryptographyDeprecationWarning(UserWarning):
 | |
|     pass
 | |
| 
 | |
| 
 | |
| # Several APIs were deprecated with no specific end-of-life date because of the
 | |
| # ubiquity of their use. They should not be removed until we agree on when that
 | |
| # cycle ends.
 | |
| DeprecatedIn36 = CryptographyDeprecationWarning
 | |
| DeprecatedIn37 = CryptographyDeprecationWarning
 | |
| DeprecatedIn40 = CryptographyDeprecationWarning
 | |
| DeprecatedIn41 = CryptographyDeprecationWarning
 | |
| DeprecatedIn42 = CryptographyDeprecationWarning
 | |
| DeprecatedIn43 = CryptographyDeprecationWarning
 | |
| 
 | |
| 
 | |
| def _check_bytes(name: str, value: bytes) -> None:
 | |
|     if not isinstance(value, bytes):
 | |
|         raise TypeError(f"{name} must be bytes")
 | |
| 
 | |
| 
 | |
| def _check_byteslike(name: str, value: bytes) -> None:
 | |
|     try:
 | |
|         memoryview(value)
 | |
|     except TypeError:
 | |
|         raise TypeError(f"{name} must be bytes-like")
 | |
| 
 | |
| 
 | |
| def int_to_bytes(integer: int, length: int | None = None) -> bytes:
 | |
|     if length == 0:
 | |
|         raise ValueError("length argument can't be 0")
 | |
|     return integer.to_bytes(
 | |
|         length or (integer.bit_length() + 7) // 8 or 1, "big"
 | |
|     )
 | |
| 
 | |
| 
 | |
| class InterfaceNotImplemented(Exception):
 | |
|     pass
 | |
| 
 | |
| 
 | |
| class _DeprecatedValue:
 | |
|     def __init__(self, value: object, message: str, warning_class):
 | |
|         self.value = value
 | |
|         self.message = message
 | |
|         self.warning_class = warning_class
 | |
| 
 | |
| 
 | |
| class _ModuleWithDeprecations(types.ModuleType):
 | |
|     def __init__(self, module: types.ModuleType):
 | |
|         super().__init__(module.__name__)
 | |
|         self.__dict__["_module"] = module
 | |
| 
 | |
|     def __getattr__(self, attr: str) -> object:
 | |
|         obj = getattr(self._module, attr)
 | |
|         if isinstance(obj, _DeprecatedValue):
 | |
|             warnings.warn(obj.message, obj.warning_class, stacklevel=2)
 | |
|             obj = obj.value
 | |
|         return obj
 | |
| 
 | |
|     def __setattr__(self, attr: str, value: object) -> None:
 | |
|         setattr(self._module, attr, value)
 | |
| 
 | |
|     def __delattr__(self, attr: str) -> None:
 | |
|         obj = getattr(self._module, attr)
 | |
|         if isinstance(obj, _DeprecatedValue):
 | |
|             warnings.warn(obj.message, obj.warning_class, stacklevel=2)
 | |
| 
 | |
|         delattr(self._module, attr)
 | |
| 
 | |
|     def __dir__(self) -> typing.Sequence[str]:
 | |
|         return ["_module", *dir(self._module)]
 | |
| 
 | |
| 
 | |
| def deprecated(
 | |
|     value: object,
 | |
|     module_name: str,
 | |
|     message: str,
 | |
|     warning_class: type[Warning],
 | |
|     name: str | None = None,
 | |
| ) -> _DeprecatedValue:
 | |
|     module = sys.modules[module_name]
 | |
|     if not isinstance(module, _ModuleWithDeprecations):
 | |
|         sys.modules[module_name] = module = _ModuleWithDeprecations(module)
 | |
|     dv = _DeprecatedValue(value, message, warning_class)
 | |
|     # Maintain backwards compatibility with `name is None` for pyOpenSSL.
 | |
|     if name is not None:
 | |
|         setattr(module, name, dv)
 | |
|     return dv
 | |
| 
 | |
| 
 | |
| def cached_property(func: typing.Callable) -> property:
 | |
|     cached_name = f"_cached_{func}"
 | |
|     sentinel = object()
 | |
| 
 | |
|     def inner(instance: object):
 | |
|         cache = getattr(instance, cached_name, sentinel)
 | |
|         if cache is not sentinel:
 | |
|             return cache
 | |
|         result = func(instance)
 | |
|         setattr(instance, cached_name, result)
 | |
|         return result
 | |
| 
 | |
|     return property(inner)
 | |
| 
 | |
| 
 | |
| # Python 3.10 changed representation of enums. We use well-defined object
 | |
| # representation and string representation from Python 3.9.
 | |
| class Enum(enum.Enum):
 | |
|     def __repr__(self) -> str:
 | |
|         return f"<{self.__class__.__name__}.{self._name_}: {self._value_!r}>"
 | |
| 
 | |
|     def __str__(self) -> str:
 | |
|         return f"{self.__class__.__name__}.{self._name_}"
 | 
