FABulous.caching#

Caching utilities for FABulous.

Provides: - Cache: singleton file-backed cache (implemented via __new__) - cache_with: dependency-aware caching decorator

Usage:

# Initialize the cache directory Cache(“/path/to/cache”)

# Use the decorator to cache a function @cache_with(files=lambda self: [self.config_path]) def build(self):

Classes#

class Cache(cache_dir=None)[source]#

Singleton file-backed cache for function results.

The first instantiation may specify cache_dir. Subsequent instantiations return the same instance; if cache_dir is provided it updates the path.

Caching can be globally enabled/disabled using enable() and disable() methods, or temporarily controlled using the temporarily_disabled() context manager.

Parameters:
  • cache_dir (str | None) – The cache directory path.

  • instance. (Create or return the singleton Cache)

:param : :type : param cache_dir: The cache directory path. If provided on first call, sets the cache dir. :param : :type : type cache_dir: str | None :param : :type : returns: The singleton instance. :param : :type : rtype: Self :param : :type : raises RuntimeError: If attempting to reinitialize with a different cache_dir.

Properties:

property cache_dir[source]#

The cache directory path.

Returns:

The path to the cache directory.

Return type:

str

Methods:

cache_disabled()[source]#

Context manager to temporarily disable caching.

Yields:

None

Return type:

Generator[None, None, None]

Examples

>>> # Caching is normally enabled
>>> result1 = cached_function()  # Uses cache
>>> with Cache.cache_disabled():
...     result2 = cached_function()  # Bypasses cache
>>> result3 = cached_function()  # Uses cache again
cache_enabled()[source]#

Context manager to temporarily enable caching.

Useful when caching is globally disabled but you want to enable it for a specific code block.

Yields:

None

Return type:

Generator[None, None, None]

Examples

>>> Cache.disable()  # Disable globally
>>> with Cache.cache_enabled():
...     result = cached_function()  # Uses cache
disable()[source]#

Disable caching globally.

When disabled, all cache checks will return cache miss, forcing functions to re- execute every time.

Return type:

None

enable()[source]#

Enable caching globally.

Return type:

None

get(fn, args, kwargs)[source]#

Get cached result or return _CACHE_MISS sentinel.

Parameters:
  • fn (Callable) – The function.

  • args (tuple) – Positional arguments.

  • kwargs (dict) – Keyword arguments.

Returns:

The cached result or _CACHE_MISS.

Return type:

Any

get_async(fn, args, kwargs)[source]#

Get cached result or return _CACHE_MISS sentinel.

Parameters:
  • fn (Callable) – The function.

  • args (tuple) – Positional arguments.

  • kwargs (dict) – Keyword arguments.

Returns:

The cached result or _CACHE_MISS.

Return type:

Any

is_cache_hit(cache_key, files, params=None)[source]#

Return True when stored metadata indicates dependencies are unchanged.

Parameters:
  • cache_key (str) – Unique key identifying the cached function call

  • files (list[Path]) – List of file paths that the function depends on

  • params (dict[str, Any] | None) – Optional dictionary of parameters affecting the function

Returns:

True if the cache is valid (hit), False if a cache miss

Return type:

bool

is_enabled()[source]#

Check if caching is currently enabled.

Returns:

True if enabled, False otherwise.

Return type:

bool

reset()[source]#

Clear all cached entries and reset the singleton state.

Return type:

None

reset_async()[source]#

Clear all cached entries and reset the singleton state.

Return type:

None

set(fn, args, kwargs, value)[source]#

Store a pickled cached value for the given function call.

Parameters:
  • fn (Callable) – The function.

  • args (tuple) – Positional arguments.

  • kwargs (dict) – Keyword arguments.

  • value (Any) – The value to cache.

Return type:

None

set_async(fn, args, kwargs, value)[source]#

Store a pickled cached value for the given function call.

Parameters:
  • fn (Callable) – The function.

  • args (tuple) – Positional arguments.

  • kwargs (dict) – Keyword arguments.

  • value (Any) – The value to cache.

Return type:

None

update(cache_key, files, params=None)[source]#

Write metadata for a cache key.

Parameters:
  • cache_key (str) – The cache key.

  • files (list[Path]) – List of dependent files.

  • params (dict[str, Any] | None) – Parameters.

Return type:

None

class DiscoveryHelper[source]#

Helper class for discovering file dependencies in config files.

Methods:

expand_config_files(files)[source]#

Expand list of files by recursively extracting paths from config files.

For each configuration file in the input list, this method will: 1. Include the config file itself 2. Recursively extract and include any file paths referenced within it 3. Cache the expansion results to avoid recomputation

Parameters:

files (list[Path]) – List of file paths, may include config files.

Returns:

Expanded list including all referenced files.

Return type:

list[Path]

extract_file_paths_from_value(value, base_dir, visited)[source]#

Recursively extract file paths from a configuration value.

Parameters:
  • value (Any) – The value to extract paths from.

  • base_dir (Path) – Base directory for resolving relative paths.

  • visited (set[Path]) – Set of already visited paths to prevent loops.

Returns:

List of Path objects found in the value.

Return type:

list[Path]

extract_paths_from_config(config_file, visited=None)[source]#

Extract all file paths referenced in a configuration file.

Recursively searches through JSON/YAML config files for string values that represent valid file paths. Prevents infinite loops by tracking visited files.

Parameters:
  • config_file (Path) – Path to the configuration file.

  • visited (set[Path] | None) – Set of already visited config files (for loop prevention).

Returns:

List of Path objects found in the configuration.

Return type:

list[Path]

is_config_file(file_path)[source]#

Check if a file is a configuration file.

Supported formats are JSON and YAML.

Parameters:

file_path (Path) – The path to the file to check.

Returns:

True if the file is a config file, False otherwise.

Return type:

bool

class HashHelper[source]#

Helper class for hashing files and parameters.

Methods:

hash_file_content(file_path)[source]#

Return a SHA256 hash of a file’s contents.

Uses hashlib.file_digest() for efficient file hashing without loading the entire file into memory.

Parameters:

file_path (Path) – The path to the file to hash.

Returns:

The SHA256 hash as a hexadecimal string.

Return type:

str

Raises:

FileNotFoundError – If the file does not exist.

hash_files(files)[source]#

Return a combined hash for a list of files.

The files are sorted by path to ensure stable ordering.

Parameters:

files (list[Path]) – List of file paths to hash.

Returns:

The combined SHA256 hash as a hexadecimal string.

Return type:

str

hash_params(params)[source]#

Return a stable hash for the provided params mapping.

Returns None if params cannot be serialized, and emits a warning.

Parameters:

params (dict[str, Any] | None) – The parameters to hash.

Returns:

The SHA256 hash as a hexadecimal string, or None if serialization fails.

Return type:

str | None

Functions#

cache_with(*, param=True, files=None, return_cached=False)[source]#
Parameters:
Return type:

Callable[[Callable], Callable]

Return a dependency-aware caching decorator.

param param:

Whether to include parameters in cache key. Defaults to True.

type param:

bool

param files:

Function to get file dependencies.

type files:

Callable[…, list[Path | str]] | None

param return_cached:

Whether to return cached value. Defaults to False.

type return_cached:

bool

returns:

The decorator function.

rtype:

Callable[[Callable], Callable]

Examples

>>> class Worker:
...     def __init__(self, path: Path):
...         self.path = path
...
...     @cache_with(files=lambda self: [self.path])
...     def build(self):
...         ...

Module Attributes#