Source code for pyflocker.ciphers.backends

from __future__ import annotations

import enum
import typing
from importlib import import_module

from pyflocker.ciphers import exc

_DEFAULT_BACKEND = None

if typing.TYPE_CHECKING:  # pragma: no cover
    import types
    from types import ModuleType


[docs] class Backends(enum.Enum): """The backends of PyFLocker.""" CRYPTOGRAPHY = "cryptography" CRYPTODOME = "cryptodome"
[docs] def load_algorithm( name: str, backend: Backends | None = None ) -> types.ModuleType: """Load a specific algorithm from the given ``backend``. Args: name: The name of the algorithm. backend: The backend to use. Returns: module: Algorithm module from the required backend. Raises: UnsupportedAlgorithm: This is raised if the algorithm is not found in the backend. """ _backend = load_backend(backend) try: return import_module(f".{name}", _backend.__name__) except ImportError as e: msg = f"{name} is not implemented by backend {backend}." raise exc.UnsupportedAlgorithm(msg) from e
[docs] def load_backend( backend: Backends | None = None, ) -> types.ModuleType: """Load a backend. Args: backend: An attribute from :class:`Backends` class. Returns: module: The backend module. """ # Rules: # 1. if default is present and backend is None: return default # 2. if backend is given: # 2.1. don't set default # 2.2. load that particular backend or raise # otherwise find a backend or raise # once the backend is found, set it as default global _DEFAULT_BACKEND if backend is None: if _DEFAULT_BACKEND is None: _DEFAULT_BACKEND = _find_backend() return _DEFAULT_BACKEND # type: ignore # backend is not None if not isinstance(backend, Backends): msg = "argument backend must be of type Backends." raise TypeError(msg) if _DEFAULT_BACKEND is None: _DEFAULT_BACKEND = _import_helper(backend) return _DEFAULT_BACKEND # noqa: PIE781 return _import_helper(backend)
def _import_helper(backend: Backends) -> ModuleType: return import_module( f".{backend.name.lower()}_", __spec__.parent, # type: ignore ) def _find_backend() -> ModuleType | None: errors = 0 for i in list(Backends): try: return _import_helper(i) except ImportError: errors += 1 if errors == len(Backends): msg = "No backends found." raise ImportError(msg) return None