summaryrefslogtreecommitdiffstats
path: root/gitlint/cache.py
diff options
context:
space:
mode:
Diffstat (limited to 'gitlint/cache.py')
-rw-r--r--gitlint/cache.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/gitlint/cache.py b/gitlint/cache.py
new file mode 100644
index 0000000..b7f9e6c
--- /dev/null
+++ b/gitlint/cache.py
@@ -0,0 +1,57 @@
+class PropertyCache(object):
+ """ Mixin class providing a simple cache. """
+
+ def __init__(self):
+ self._cache = {}
+
+ def _try_cache(self, cache_key, cache_populate_func):
+ """ Tries to get a value from the cache identified by `cache_key`.
+ If no value is found in the cache, do a function call to `cache_populate_func` to populate the cache
+ and then return the value from the cache. """
+ if cache_key not in self._cache:
+ cache_populate_func()
+ return self._cache[cache_key]
+
+
+def cache(original_func=None, cachekey=None):
+ """ Cache decorator. Caches function return values.
+ Requires the parent class to extend and initialize PropertyCache.
+ Usage:
+ # Use function name as cache key
+ @cache
+ def myfunc(args):
+ ...
+
+ # Specify cache key
+ @cache(cachekey="foobar")
+ def myfunc(args):
+ ...
+ """
+
+ # Decorators with optional arguments are a bit convoluted in python, especially if you want to support both
+ # Python 2 and 3. See some of the links below for details.
+
+ def cache_decorator(func):
+
+ # If no specific cache key is given, use the function name as cache key
+ if not cache_decorator.cachekey:
+ cache_decorator.cachekey = func.__name__
+
+ def wrapped(*args):
+ def cache_func_result():
+ # Call decorated function and store its result in the cache
+ args[0]._cache[cache_decorator.cachekey] = func(*args)
+ return args[0]._try_cache(cache_decorator.cachekey, cache_func_result)
+
+ return wrapped
+
+ # Passing parent function variables to child functions requires special voodoo in python2:
+ # https://stackoverflow.com/a/14678445/381010
+ cache_decorator.cachekey = cachekey # attribute on the function
+
+ # To support optional kwargs for decorators, we need to check if a function is passed as first argument or not.
+ # https://stackoverflow.com/a/24617244/381010
+ if original_func:
+ return cache_decorator(original_func)
+
+ return cache_decorator