base.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from __future__ import annotations
  2. from typing import Any, Protocol, runtime_checkable
  3. class UntypedSerializerProtocol(Protocol):
  4. """Protocol for serialization and deserialization of objects."""
  5. def dumps(self, obj: Any) -> bytes: ...
  6. def loads(self, data: bytes) -> Any: ...
  7. @runtime_checkable
  8. class SerializerProtocol(Protocol):
  9. """Protocol for serialization and deserialization of objects.
  10. - `dumps`: Serialize an object to bytes.
  11. - `dumps_typed`: Serialize an object to a tuple `(type, bytes)`.
  12. - `loads`: Deserialize an object from bytes.
  13. - `loads_typed`: Deserialize an object from a tuple `(type, bytes)`.
  14. Valid implementations include the `pickle`, `json` and `orjson` modules.
  15. """
  16. def dumps_typed(self, obj: Any) -> tuple[str, bytes]: ...
  17. def loads_typed(self, data: tuple[str, bytes]) -> Any: ...
  18. class SerializerCompat(SerializerProtocol):
  19. def __init__(self, serde: UntypedSerializerProtocol) -> None:
  20. self.serde = serde
  21. def dumps_typed(self, obj: Any) -> tuple[str, bytes]:
  22. return type(obj).__name__, self.serde.dumps(obj)
  23. def loads_typed(self, data: tuple[str, bytes]) -> Any:
  24. return self.serde.loads(data[1])
  25. def maybe_add_typed_methods(
  26. serde: SerializerProtocol | UntypedSerializerProtocol,
  27. ) -> SerializerProtocol:
  28. """Wrap serde old serde implementations in a class with loads_typed and dumps_typed for backwards compatibility."""
  29. if not isinstance(serde, SerializerProtocol):
  30. return SerializerCompat(serde)
  31. return serde
  32. class CipherProtocol(Protocol):
  33. """Protocol for encryption and decryption of data.
  34. - `encrypt`: Encrypt plaintext.
  35. - `decrypt`: Decrypt ciphertext.
  36. """
  37. def encrypt(self, plaintext: bytes) -> tuple[str, bytes]:
  38. """Encrypt plaintext. Returns a tuple (cipher name, ciphertext)."""
  39. ...
  40. def decrypt(self, ciphername: str, ciphertext: bytes) -> bytes:
  41. """Decrypt ciphertext. Returns the plaintext."""
  42. ...