mirror of
https://github.com/django-components/django-components.git
synced 2025-08-14 11:17:59 +00:00
refactor: Fix template caching, expose cached_template
, Component.template API changes (#647)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
parent
589e802625
commit
841dd77e91
14 changed files with 347 additions and 56 deletions
|
@ -1,7 +1,8 @@
|
|||
import functools
|
||||
import sys
|
||||
import typing
|
||||
from pathlib import Path
|
||||
from typing import Any, Callable, List, Mapping, Sequence, Tuple, Union, get_type_hints
|
||||
from typing import Any, Callable, List, Mapping, Sequence, Tuple, TypeVar, Union, cast, get_type_hints
|
||||
|
||||
from django.utils.autoreload import autoreload_started
|
||||
|
||||
|
@ -166,3 +167,47 @@ def validate_typed_dict(value: Mapping[str, Any], dict_type: Any, prefix: str, k
|
|||
# `Component 'name' got unexpected slot keys 'invalid_key'`
|
||||
# `Component 'name' got unexpected data keys 'invalid_key'`
|
||||
raise TypeError(f"{prefix} got unexpected {kind} keys {formatted_keys}")
|
||||
|
||||
|
||||
TFunc = TypeVar("TFunc", bound=Callable)
|
||||
|
||||
|
||||
def lazy_cache(
|
||||
make_cache: Callable[[], Callable[[Callable], Callable]],
|
||||
) -> Callable[[TFunc], TFunc]:
|
||||
"""
|
||||
Decorator that caches the given function similarly to `functools.lru_cache`.
|
||||
But the cache is instantiated only at first invocation.
|
||||
|
||||
`cache` argument is a function that generates the cache function,
|
||||
e.g. `functools.lru_cache()`.
|
||||
"""
|
||||
_cached_fn = None
|
||||
|
||||
def decorator(fn: TFunc) -> TFunc:
|
||||
@functools.wraps(fn)
|
||||
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
||||
# Lazily initialize the cache
|
||||
nonlocal _cached_fn
|
||||
if not _cached_fn:
|
||||
# E.g. `lambda: functools.lru_cache(maxsize=app_settings.TEMPLATE_CACHE_SIZE)`
|
||||
cache = make_cache()
|
||||
_cached_fn = cache(fn)
|
||||
|
||||
return _cached_fn(*args, **kwargs)
|
||||
|
||||
# Allow to access the LRU cache methods
|
||||
# See https://stackoverflow.com/a/37654201/9788634
|
||||
wrapper.cache_info = lambda: _cached_fn.cache_info() # type: ignore
|
||||
wrapper.cache_clear = lambda: _cached_fn.cache_clear() # type: ignore
|
||||
|
||||
# And allow to remove the cache instance (mostly for tests)
|
||||
def cache_remove() -> None:
|
||||
nonlocal _cached_fn
|
||||
_cached_fn = None
|
||||
|
||||
wrapper.cache_remove = cache_remove # type: ignore
|
||||
|
||||
return cast(TFunc, wrapper)
|
||||
|
||||
return decorator
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue