fleche.storage.destructuring ============================ .. py:module:: fleche.storage.destructuring Classes ------- .. autoapisummary:: fleche.storage.destructuring.Digested fleche.storage.destructuring.DigestedIterable fleche.storage.destructuring.DigestedDict fleche.storage.destructuring.DestructuringMixin Module Contents --------------- .. py:class:: Digested Bases: :py:obj:`abc.ABC` Helper class that provides a standard way to create an ABC using inheritance. .. py:method:: underlying() :abstractmethod: Return plain underlying value, ie. list/dict/etc of nested values or their partial digests .. py:method:: __digest__() .. py:method:: mend(storage: DestructuringMixin) :abstractmethod: .. py:method:: sunder(intern: Callable[[Any], tuple[Any, int | float]], value: Any) :classmethod: :abstractmethod: .. py:method:: get(storage, key) :staticmethod: .. py:class:: DigestedIterable Bases: :py:obj:`Digested` Helper class that provides a standard way to create an ABC using inheritance. .. py:attribute:: items :type: list | tuple .. py:method:: underlying() Return plain underlying value, ie. list/dict/etc of nested values or their partial digests .. py:method:: mend(storage: DestructuringMixin) -> list | tuple .. py:method:: sunder(intern: Callable[[Any], tuple[Any, int | float]], value: list | tuple) :classmethod: .. py:class:: DigestedDict Bases: :py:obj:`Digested` Helper class that provides a standard way to create an ABC using inheritance. .. py:attribute:: items :type: dict .. py:method:: underlying() Return plain underlying value, ie. list/dict/etc of nested values or their partial digests .. py:method:: mend(storage: DestructuringMixin) -> dict .. py:method:: sunder(intern: Callable[[Any], tuple[Any, int | float]], value: dict) :classmethod: .. py:class:: DestructuringMixin Bases: :py:obj:`fleche.storage.base.StorageBackend` Mixin that recursively destructures collections on save/load. Place before a concrete :class:`StorageBackend` in the MRO to add destructuring behavior. Lists, tuples, and dicts are broken apart so each element is stored independently; on load the original structure is reassembled. Example:: @dataclass(frozen=True) class ValueMemory(ValueMixin, DestructuringMixin, MemoryBackend): ... vm = ValueMemory(storage={}) key = vm.save([1, [2, 3]]) assert vm.load(key) == [1, [2, 3]] .. py:attribute:: remaining_depth :type: int :value: 0 .. py:method:: _is_trojan_tuple(value) :staticmethod: .. py:method:: _intern_rec(value: Any, key: fleche.digest.Digest | None = None) -> tuple[Any, int | float] Post-order traversal: recurse to leaves, decide inline-vs-store on the way back up. Returns ``(result, depth)`` where *result* is the plain value when ``depth < remaining_depth`` (the element is inlined in its parent's :class:`Digested` wrapper) or a :class:`Digest` when the element was written to storage separately. Every node in the structure is visited exactly once (O(n)), unlike a separate depth-counting pass. .. py:method:: put(value: Any, key: fleche.digest.Digest) -> fleche.digest.Digest .. py:method:: get(key: fleche.digest.Digest | Any) -> Any