Skip to content

decorators

Class info

🛈 DocStrings

cache_with_transforms

cache_with_transforms(
    *,
    arg_transformers: dict[int, Callable[[Any], Any]] | None = None,
    kwarg_transformers: dict[str, Callable[[Any], Any]] | None = None
) -> Callable[[Callable[P, R]], Callable[P, R]]

A caching decorator with transformation functions for args and kwargs.

Can be used to make specific args / kwargs hashable. Also adds cache and cache_info objects to the decorated function.

Parameters:

Name Type Description Default
arg_transformers dict[int, Callable[[Any], Any]] | None

Dict mapping positional args indices to transformer functions

None
kwarg_transformers dict[str, Callable[[Any], Any]] | None

Dict mapping kwargs names to transformer functions

None

Returns:

Type Description
Callable[[Callable[P, R]], Callable[P, R]]

A decorator function that caches results based on transformed arguments

Source code in src/jinjarope/decorators.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
def cache_with_transforms(
    *,
    arg_transformers: dict[int, Callable[[Any], Any]] | None = None,
    kwarg_transformers: dict[str, Callable[[Any], Any]] | None = None,
) -> Callable[[Callable[P, R]], Callable[P, R]]:
    """A caching decorator with transformation functions for args and kwargs.

    Can be used to make specific args / kwargs hashable.
    Also adds cache and cache_info objects to the decorated function.

    Args:
        arg_transformers: Dict mapping positional args indices to transformer functions
        kwarg_transformers: Dict mapping kwargs names to transformer functions

    Returns:
        A decorator function that caches results based on transformed arguments
    """
    arg_transformers = arg_transformers or {}
    kwarg_transformers = kwarg_transformers or {}

    def decorator(func: Callable[P, R]) -> Callable[P, R]:
        cache: dict[tuple[Any, ...], R] = {}

        @wraps(func)
        def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
            # Transform positional arguments
            transformed_args = tuple(
                arg_transformers.get(i, lambda x: x)(arg) for i, arg in enumerate(args)
            )

            # Transform keyword arguments
            transformed_kwargs = {
                key: kwarg_transformers.get(key, lambda x: x)(value)
                for key, value in sorted(kwargs.items())
            }

            # Create cache key from transformed arguments
            cache_key = (transformed_args, tuple(transformed_kwargs.items()))

            if cache_key not in cache:
                cache[cache_key] = func(*args, **kwargs)
            return cache[cache_key]

        def cache_info() -> dict[str, int]:
            """Return information about cache hits and size."""
            return {"cache_size": len(cache)}

        wrapper.cache_info = cache_info  # type: ignore
        wrapper.cache = cache  # type: ignore

        return wrapper

    return decorator

read_file_content

read_file_content(filepath: str | UPath) -> str

Read and return the content of a file.

Source code in src/jinjarope/decorators.py
74
75
76
77
78
@cache_with_transforms(arg_transformers={0: lambda p: upath.UPath(p).resolve()})
def read_file_content(filepath: str | upath.UPath) -> str:
    """Read and return the content of a file."""
    with upath.UPath(filepath).open() as f:
        return f.read()