Skip to content

Commit 0bf0428

Browse files
committed
feat(cache): add argument filtering for cache key generation
- Introduce `ignore_positional_args` and `ignore_keyword_args` parameters to exclude specific arguments from cache key generation - Update `wrapper` and `awrapper` functions to filter out ignored arguments before cache operations - Improve type checking for `user_func` and `user_args` - Update docstring to reflect new functionality
1 parent ec89562 commit 0bf0428

File tree

1 file changed

+49
-15
lines changed

1 file changed

+49
-15
lines changed

src/redis_func_cache/cache.py

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,9 @@ def decorate(
515515
user_function: Optional[CallableTV] = None,
516516
/,
517517
serializer: Optional[SerializerSetterValueT] = None,
518-
**keywords,
518+
ignore_positional_args: Optional[Sequence[int]] = None,
519+
ignore_keyword_args: Optional[Sequence[str]] = None,
520+
**options,
519521
) -> CallableTV:
520522
"""Decorate the given function with caching.
521523
@@ -524,9 +526,22 @@ def decorate(
524526
525527
serializer: serialize/deserialize name or function pair for return value of what decorated.
526528
527-
If defined, it overrides the first element of :attr:`serializer`.
529+
It accepts either:
530+
- A string key mapping to predefined serializers (like "yaml" or "json")
531+
- A tuple of (`serialize_func`, `deserialize_func`) functions
532+
533+
If defined, it overrides the :attr:`serializer` property of the cache instance.
534+
535+
536+
ignore_positional_args: A list of positional argument indices to exclude from cache key generation.
537+
538+
These arguments will be filtered out before cache operations.
528539
529-
**keywords: Additional options passed to :meth:`exec`, they will encoded to json, then pass to redis lua script.
540+
ignore_keyword_args: A list of keyword argument names to exclude from cache key generation.
541+
542+
These parameters will be filtered out before cache operations.
543+
544+
**options: Additional options passed to :meth:`exec`, they will encoded to json, then pass to redis lua script.
530545
531546
This method is equivalent to :attr:`__call__`.
532547
@@ -585,25 +600,44 @@ def my_func(a, b):
585600
elif serializer is not None:
586601
serialize_func, deserialize_func = serializer
587602

588-
def decorator(f: CallableTV):
589-
@wraps(f)
590-
def wrapper(*args, **kwargs):
591-
return self.exec(f, args, kwargs, serialize_func, deserialize_func, **keywords)
592-
593-
@wraps(f)
594-
async def awrapper(*args, **kwargs):
595-
return await self.aexec(f, args, kwargs, serialize_func, deserialize_func, **keywords)
596-
597-
if not callable(f):
603+
if ignore_positional_args is None:
604+
ignore_positional_args = []
605+
if ignore_keyword_args is None:
606+
ignore_keyword_args = []
607+
608+
def decorator(user_func: CallableTV):
609+
@wraps(user_func)
610+
def wrapper(*user_args, **user_kwargs):
611+
return self.exec(
612+
user_func,
613+
[x for i, x in enumerate(user_args) if i not in ignore_positional_args],
614+
{k: v for k, v in user_kwargs.items() if k not in ignore_keyword_args},
615+
serialize_func,
616+
deserialize_func,
617+
**options,
618+
)
619+
620+
@wraps(user_func)
621+
async def awrapper(*user_args, **user_kwargs):
622+
return await self.aexec(
623+
user_func,
624+
[x for i, x in enumerate(user_args) if i not in ignore_positional_args],
625+
{k: v for k, v in user_kwargs.items() if k not in ignore_keyword_args},
626+
serialize_func,
627+
deserialize_func,
628+
**options,
629+
)
630+
631+
if not callable(user_func):
598632
raise TypeError("Can not decorate a non-callable object.")
599633
if self.asynchronous:
600-
if not iscoroutinefunction(f):
634+
if not iscoroutinefunction(user_func):
601635
raise TypeError(
602636
"The decorated function or method must be a coroutine when using an asynchronous redis client."
603637
)
604638
return cast(CallableTV, awrapper)
605639
else:
606-
if iscoroutinefunction(f):
640+
if iscoroutinefunction(user_func):
607641
raise TypeError(
608642
"The decorated function or method cannot be a coroutine when using a asynchronous redis client."
609643
)

0 commit comments

Comments
 (0)