diff --git a/src/cache_memoize/__init__.py b/src/cache_memoize/__init__.py index 3ab5c34..f7921aa 100644 --- a/src/cache_memoize/__init__.py +++ b/src/cache_memoize/__init__.py @@ -1,5 +1,6 @@ from functools import wraps +import inspect import hashlib from urllib.parse import quote @@ -20,6 +21,7 @@ def cache_memoize( store_result=True, cache_exceptions=(), cache_alias=DEFAULT_CACHE_ALIAS, + unless=None ): """Decorator for memoizing function calls where we use the "local cache" to store the result. @@ -96,6 +98,26 @@ def noop(*args): args_rewrite = noop + def _bypass_cache(self, *args, **kwargs): + """Determines whether or not to bypass the cache by calling unless(). + Supports both unless() that takes in arguments and unless() + that doesn't. + """ + bypass_cache = False + + if callable(unless): + argspec = inspect.getfullargspec(unless) + has_args = len(argspec.args) > 0 or argspec.varargs or argspec.varkw + + # If unless() takes args, pass them in. + if has_args: + if unless(*args, **kwargs) is True: + bypass_cache = True + elif unless() is True: + bypass_cache = True + + return bypass_cache + def decorator(func): def _default_make_cache_key(*args, **kwargs): cache_key = ":".join( @@ -131,6 +153,9 @@ def inner(*args, **kwargs): except cache_exceptions as exception: result = exception + if _bypass_cache(*args, **kwargs): + return result + if not store_result: # Then the result isn't valuable/important to store but # we want to store something. Just to remember that