fleche.storage.base

Attributes

logger

Exceptions

SaveError

Common base class for all non-exit exceptions.

AmbiguousDigestError

Inappropriate argument value (of correct type).

Classes

KeyManagement

Abstract base providing key-management helpers for any keyed storage.

StorageBackend

Primitive backend interface for key-value storage.

ValueStorage

Abstract domain interface for value storage.

ValueMixin

Bridges ValueStorage with StorageBackend primitives.

Digested

Helper class that provides a standard way to create an ABC using

DigestedIterable

Helper class that provides a standard way to create an ABC using

DigestedDict

Helper class that provides a standard way to create an ABC using

DestructuringMixin

Mixin that recursively destructures collections on save/load.

CallStorage

Abstract domain interface for call storage.

CallMixin

Bridges CallStorage with StorageBackend primitives.

Module Contents

fleche.storage.base.logger[source]
exception fleche.storage.base.SaveError[source]

Bases: Exception

Common base class for all non-exit exceptions.

exception fleche.storage.base.AmbiguousDigestError[source]

Bases: ValueError

Inappropriate argument value (of correct type).

class fleche.storage.base.KeyManagement[source]

Bases: abc.ABC

Abstract base providing key-management helpers for any keyed storage.

Subclasses must implement list, _evict, and _contains. The concrete helpers evict, contains, expand, and shrink are implemented here once and inherited by all storage classes.

abstractmethod list() Iterable[fleche.digest.Digest][source]
abstractmethod _evict(key: fleche.digest.Digest) None[source]
abstractmethod _contains(key: fleche.digest.Digest) bool[source]
evict(key: fleche.digest.Digest | str) None[source]

Removes the entry corresponding to the key from the storage.

contains(key: fleche.digest.Digest | str) bool[source]
expand(key: fleche.digest.Digest | str) fleche.digest.Digest[source]

Expands a short-hand digest to the full length one.

shrink(key: fleche.digest.Digest | str) fleche.digest.Digest[source]

Find the shortest substring that is still an unambiguous reference to the same value.

class fleche.storage.base.StorageBackend[source]

Bases: KeyManagement

Primitive backend interface for key-value storage.

Backends implement the low-level put/get/_evict/list operations. Higher-level classes (ValueMixin, CallMixin) add domain-specific logic on top.

abstractmethod put(value: Any, key: fleche.digest.Digest) fleche.digest.Digest[source]
abstractmethod get(key: fleche.digest.Digest) Any[source]
_contains(key: fleche.digest.Digest) bool[source]
class fleche.storage.base.ValueStorage[source]

Bases: KeyManagement

Abstract domain interface for value storage.

abstractmethod save(value: Any, key: fleche.digest.Digest | None = None) fleche.digest.Digest[source]
abstractmethod load(key: fleche.digest.Digest | str) Any[source]
class fleche.storage.base.ValueMixin[source]

Bases: ValueStorage, StorageBackend

Bridges ValueStorage with StorageBackend primitives.

Implements save and load using put and get. Concrete classes inherit from this and a StorageBackend implementation to get a fully functional value storage.

save(value: Any, key: fleche.digest.Digest | None = None) fleche.digest.Digest[source]
load(key: fleche.digest.Digest | str) Any[source]
class fleche.storage.base.Digested[source]

Bases: abc.ABC

Helper class that provides a standard way to create an ABC using inheritance.

abstractmethod underlying()[source]

Return plain underlying value, ie. list/dict/etc of nested values or their partial digests

__digest__()[source]
abstractmethod mend(storage: DestructuringMixin)[source]
classmethod sunder(intern: Callable[[Any], tuple[Any, int | float]], value: Any)[source]
Abstractmethod:

static get(storage, key)[source]
class fleche.storage.base.DigestedIterable[source]

Bases: Digested

Helper class that provides a standard way to create an ABC using inheritance.

items: list | tuple[source]
underlying()[source]

Return plain underlying value, ie. list/dict/etc of nested values or their partial digests

mend(storage: DestructuringMixin) list | tuple[source]
classmethod sunder(intern: Callable[[Any], tuple[Any, int | float]], value: list | tuple)[source]
class fleche.storage.base.DigestedDict[source]

Bases: Digested

Helper class that provides a standard way to create an ABC using inheritance.

items: dict[source]
underlying()[source]

Return plain underlying value, ie. list/dict/etc of nested values or their partial digests

mend(storage: DestructuringMixin) dict[source]
classmethod sunder(intern: Callable[[Any], tuple[Any, int | float]], value: dict)[source]
class fleche.storage.base.DestructuringMixin[source]

Bases: StorageBackend

Mixin that recursively destructures collections on save/load.

Place before a concrete 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:

class DestructuringMemory(ValueMixin, DestructuringMixin, Memory):
    pass

dm = DestructuringMemory(storage={})
key = dm.save([1, [2, 3]])
assert dm.load(key) == [1, [2, 3]]
remaining_depth: int = 0[source]
_intern_rec(value: Any, key: fleche.digest.Digest | None = None) tuple[Any, int | float][source]

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 Digested wrapper) or a 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.

put(value: Any, key: fleche.digest.Digest) fleche.digest.Digest[source]
get(key: fleche.digest.Digest | Any) Any[source]
class fleche.storage.base.CallStorage[source]

Bases: KeyManagement

Abstract domain interface for call storage.

abstractmethod save(call: fleche.call.Call) fleche.digest.Digest[source]
abstractmethod load(key: fleche.digest.Digest | str) fleche.call.Call[source]
abstractmethod query(template: fleche.call.QueryCall) Iterable[fleche.call.Call][source]
transform(func: Callable[[fleche.call.Call], fleche.call.Call] | None = None) None[source]

Applies a transformation function to all Call objects in the storage.

Parameters:

func (Callable[[Call], Call] | None) – A function that takes a Call and returns a transformed Call. If None, the identity function is used (useful for re-calculating keys).

class fleche.storage.base.CallMixin[source]

Bases: CallStorage, StorageBackend

Bridges CallStorage with StorageBackend primitives.

Implements save, load, and query using put and get, deriving the storage key from the call’s lookup key. transform is inherited from CallStorage.

Concrete classes inherit from this and a StorageBackend implementation to get a fully functional call storage.

save(call: fleche.call.Call) fleche.digest.Digest[source]
load(key: fleche.digest.Digest | str) fleche.call.Call[source]
query(template: fleche.call.QueryCall) Iterable[fleche.call.Call][source]

Find cached calls that ‘match’ the template.

Returns all calls where the given arguments, results or metadata match exactly the stored ones. Values may be given either as they are or as Digest.

Parameters:

template (Call) – specification for calls to return; use None as wildcard.

Returns:

an iterable over all matching call objects

Return type:

Iterable[Call]