fleche.caches

Attributes

logger

DigestedIterable

DigestedDict

Exceptions

Rejected

Cache refused to cache the call for some reason or other.

Classes

BaseCache

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

Cache

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

ReadOnlyCache

A cache that can only be read from.

FilteredCache

A read-only view of a cache that only exposes calls matching a predicate.

RefreshingCache

A cache that forces re-execution by always missing on load.

CacheStack

Represents a combination of caches.

SizeLimitedMixin

Mixin that enforces a maximum number of cached calls with random eviction.

SizeLimitedCache

A Cache that enforces a maximum number of cached calls.

Module Contents

fleche.caches.logger[source]
exception fleche.caches.Rejected[source]

Bases: Exception

Cache refused to cache the call for some reason or other.

fleche.caches.DigestedIterable[source]
fleche.caches.DigestedDict[source]
class fleche.caches.BaseCache[source]

Bases: abc.ABC

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

abstractmethod save(call: fleche.call.Call) str[source]
load(key: str, lazy: bool = False) fleche.call.Call[source]
load(key: str, lazy: bool = True) fleche.call.LazyCall
abstractmethod load_value(key: str) Any[source]
abstractmethod evict(key: str | fleche.digest.Digest) None[source]
contains(key: str) bool[source]
transfer(other: BaseCache, pop: bool = False, overwrite: bool = False) None[source]

Transfer all calls from this cache to another cache.

Parameters:
  • other – The destination cache.

  • pop – If True, evict transferred keys from the source cache after moving.

  • overwrite – If True, overwrite existing entries in the target cache. If False (default), skip entries that already exist in the target.

readonly() ReadOnlyCache[source]

Return a read-only view of this cache.

push(cache: BaseCache) CacheStack[source]
abstractmethod expand(key: fleche.digest.Digest | str) fleche.digest.Digest[source]

Expand a short digest prefix to its full-length digest.

Parameters:

key (str or Digest) – the short digest prefix to expand

Returns:

the full-length digest

Return type:

Digest

Raises:
  • KeyError – if the key is not found

  • AmbiguousDigestError – if the prefix matches more than one entry

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

Find the shortest substring that is still an unambigious reference to the same call.

Warning

This is a property of how many values there are in your storage! A key returned from this function may become ambigious in the future when more values are added. Do not rely on this function in your programs, it is provided as a convenience for users only!

Parameters:

key (str or Digest) – the key to shorten

Returns:

shortest key possible

Return type:

Digest

Raises:

AmbiguousDigestError – if no shorter key is possible

abstractmethod _query(call: BaseCache._query.call) Iterable[fleche.call.LazyCall][source]
query(call: BaseCache.query.call) fleche.query.QueryIterator[source]
table(arguments: Iterable[str] = (), results=False) pandas.DataFrame[source]

Return a pandas DataFrame summarizing cached calls via query().

This implementation uses a fully-wildcard Call template to retrieve all calls through self.query and then flattens metadata keys into top-level columns for convenience.

By default, arguments and results are elided.

The DataFrame index will be the lookup key (digest) of each call. Columns are:

  • name: the function name

  • module: the module name

  • ‘result`: if results argument is True

  • metadata fields are flattened and added as columns directly

If given argument names collide with any of the above columns, they are prefixed by ‘a_’. Only requested arguments are loaded from cache.

Parameters:
  • arguments (iterable of str) – add the given arguments (of the queried calls) as columns to the table

  • results (bool) – if True, add results of queried calls to table

Returns:

table of all calls on cache

Return type:

pandas.DataFrame

filter(predicate: Callable[[fleche.call.Call | fleche.call.LazyCall], bool] | fleche.call.Call) FilteredCache[source]

Create a read-only view of this cache that only exposes calls matching the predicate.

Parameters:

predicate – A function that takes a Call or LazyCall and returns True if it should be included in the new cache, or a Call object to use as a template.

Returns:

A read-only view of the cache.

Return type:

FilteredCache

class fleche.caches.Cache[source]

Bases: BaseCache

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

values: fleche.storage.ValueStorage[source]
calls: fleche.storage.CallStorage[source]
load_value(key)[source]
_handle_args_save(value)[source]
_handle_args_load(key)[source]
save(call: fleche.call.Call) str[source]
_decode_call(call: fleche.call.Call, lazy: bool = False) fleche.call.Call[source]
_decode_call(call: fleche.call.Call, lazy: bool = True) fleche.call.LazyCall
load(key: str, lazy: bool = False) fleche.call.Call[source]
load(key: str, lazy: bool = True) fleche.call.LazyCall
contains(key: str) bool[source]
expand(key: fleche.digest.Digest | str) fleche.digest.Digest[source]

Expand a short digest prefix to its full-length digest.

Parameters:

key (str or Digest) – the short digest prefix to expand

Returns:

the full-length digest

Return type:

Digest

Raises:
  • KeyError – if the key is not found

  • AmbiguousDigestError – if the prefix matches more than one entry

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

Find the shortest substring that is still an unambigious reference to the same call.

Warning

This is a property of how many values there are in your storage! A key returned from this function may become ambigious in the future when more values are added. Do not rely on this function in your programs, it is provided as a convenience for users only!

Parameters:

key (str or Digest) – the key to shorten

Returns:

shortest key possible

Return type:

Digest

Raises:

AmbiguousDigestError – if no shorter key is possible

_query(call: Cache._query.call) Iterable[fleche.call.LazyCall][source]

Query for cached calls that match a template and return decoded results.

This delegates to the underlying CallStorage.query() using the provided template call. Any digested argument values and the result are decoded via this cache’s value storage before yielding.

Parameters:

call – A Call instance used as a template; fields set to None act as wildcards. For arguments and result, comparisons follow digest semantics (i.e., values are matched by their digest).

Yields:

Call | LazyCall – Matching calls with arguments and result decoded from digests where possible.

evict(key: str | fleche.digest.Digest) None[source]
redigest() None[source]

Ensures consistent cache keys in case digest function changed.

This may take time depending on cache size.

class fleche.caches.ReadOnlyCache[source]

Bases: BaseCache

A cache that can only be read from.

cache: BaseCache[source]
save(call: fleche.call.Call)[source]
load(key, lazy: bool = True)[source]
expand(key: fleche.digest.Digest | str) fleche.digest.Digest[source]

Expand a short digest prefix to its full-length digest.

Parameters:

key (str or Digest) – the short digest prefix to expand

Returns:

the full-length digest

Return type:

Digest

Raises:
  • KeyError – if the key is not found

  • AmbiguousDigestError – if the prefix matches more than one entry

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

Find the shortest substring that is still an unambigious reference to the same call.

Warning

This is a property of how many values there are in your storage! A key returned from this function may become ambigious in the future when more values are added. Do not rely on this function in your programs, it is provided as a convenience for users only!

Parameters:

key (str or Digest) – the key to shorten

Returns:

shortest key possible

Return type:

Digest

Raises:

AmbiguousDigestError – if no shorter key is possible

evict(key: str | fleche.digest.Digest) None[source]
load_value(key)[source]
contains(key: str) bool[source]
_query(call: ReadOnlyCache._query.call) Iterable[fleche.call.LazyCall][source]

Forward queries to the wrapped cache.

Parameters:

call – A template Call where None fields act as wildcards.

Yields:

Call | LazyCall – Results yielded by the wrapped cache’s query method.

class fleche.caches.FilteredCache[source]

Bases: ReadOnlyCache

A read-only view of a cache that only exposes calls matching a predicate.

predicate: Callable[[fleche.call.Call | fleche.call.LazyCall], bool][source]
load(key, lazy: bool = True)[source]
_query(call: FilteredCache._query.call) Iterable[fleche.call.LazyCall][source]

Forward queries to the wrapped cache.

Parameters:

call – A template Call where None fields act as wildcards.

Yields:

Call | LazyCall – Results yielded by the wrapped cache’s query method.

class fleche.caches.RefreshingCache[source]

Bases: BaseCache

A cache that forces re-execution by always missing on load.

It forwards saves and value loads to an underlying cache, allowing new results to be stored while ensuring that existing ones are ignored for the duration of its use.

This is necessary to handle nested fleche calls during a rerun, otherwise forcing them to re-execute would be awkward.

cache: BaseCache[source]
save(call: fleche.call.Call) str[source]
load(key: str, lazy: bool = False) fleche.call.Call[source]
load(key: str, lazy: bool = True) fleche.call.LazyCall
load_value(key: str) Any[source]
contains(key: str) bool[source]
evict(key: str | fleche.digest.Digest) None[source]
expand(key: fleche.digest.Digest | str) fleche.digest.Digest[source]

Expand a short digest prefix to its full-length digest.

Parameters:

key (str or Digest) – the short digest prefix to expand

Returns:

the full-length digest

Return type:

Digest

Raises:
  • KeyError – if the key is not found

  • AmbiguousDigestError – if the prefix matches more than one entry

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

Find the shortest substring that is still an unambigious reference to the same call.

Warning

This is a property of how many values there are in your storage! A key returned from this function may become ambigious in the future when more values are added. Do not rely on this function in your programs, it is provided as a convenience for users only!

Parameters:

key (str or Digest) – the key to shorten

Returns:

shortest key possible

Return type:

Digest

Raises:

AmbiguousDigestError – if no shorter key is possible

_query(call: RefreshingCache._query.call) fleche.query.QueryIterator[source]
class fleche.caches.CacheStack[source]

Bases: BaseCache

Represents a combination of caches.

Saving will always hit the lowest level, while loading will traverse up.

stack: tuple[BaseCache, Ellipsis][source]
__post_init__()[source]
save(call: fleche.call.Call)[source]
load(key, lazy: bool = True)[source]
load_value(key)[source]
contains(key: str) bool[source]
push(cache: BaseCache) CacheStack[source]
evict(key: str | fleche.digest.Digest) None[source]
expand(key: fleche.digest.Digest | str) fleche.digest.Digest[source]

Expand a short digest prefix to its full-length digest.

Parameters:

key (str or Digest) – the short digest prefix to expand

Returns:

the full-length digest

Return type:

Digest

Raises:
  • KeyError – if the key is not found

  • AmbiguousDigestError – if the prefix matches more than one entry

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

Find the shortest substring that is still an unambigious reference to the same call.

Warning

This is a property of how many values there are in your storage! A key returned from this function may become ambigious in the future when more values are added. Do not rely on this function in your programs, it is provided as a convenience for users only!

Parameters:

key (str or Digest) – the key to shorten

Returns:

shortest key possible

Return type:

Digest

Raises:

AmbiguousDigestError – if no shorter key is possible

_query(call: CacheStack._query.call) Iterable[fleche.call.LazyCall][source]

Aggregate query results across the stack, avoiding duplicates.

The caches are queried from bottom to top. Results are deduplicated by their lookup key (via Call.to_lookup_key()) and yielded in the order they are first seen.

Parameters:

call – A template Call where None fields act as wildcards.

Yields:

Call | LazyCall – Matching calls from any cache in the stack, without duplicates.

class fleche.caches.SizeLimitedMixin[source]

Bases: BaseCache

Mixin that enforces a maximum number of cached calls with random eviction.

Combine this with Cache (mixin first in MRO) to get a size-limited cache:

@dataclass
class SizeLimitedCache(SizeLimitedMixin, Cache):
    max_size: int

When a new call is saved and the number of cached calls exceeds max_size, a call record is selected for eviction via _pick_eviction_target(). Value storage is intentionally left untouched.

The concrete class must provide a max_size integer, which is provided automatically when mixed with Cache.

max_size: int[source]
_lock: threading.RLock[source]
_keys: set[str][source]
__post_init__(*args, **kwargs)[source]
_pick_eviction_target(keys: list[str]) str[source]

Select the call to evict from a sample of cached call keys.

The default implementation chooses uniformly at random. Override this method to implement a different eviction policy without touching any other part of the class.

Parameters:

keys – A non-empty list of all tracked call keys.

Returns:

The key of the call that should be evicted.

_enforce_size_limit() None[source]

Evict call records until the cache is within max_size.

save(call: SizeLimitedMixin.save.call) str[source]
evict(key: str | fleche.digest.Digest) None[source]
class fleche.caches.SizeLimitedCache[source]

Bases: SizeLimitedMixin, Cache

A Cache that enforces a maximum number of cached calls.

When a new call is saved and the number of cached calls exceeds max_size, a call record is selected for eviction via _pick_eviction_target(). The default policy evicts uniformly at random; override _pick_eviction_target() to change this.

Parameters:
  • values – Value storage (forwarded to Cache).

  • _calls – Call storage (forwarded to Cache).

  • max_size – Maximum number of calls to keep.

max_size: int[source]