diff --git a/checkpy/caches.py b/checkpy/caches.py index 635ea05..4ff35bc 100644 --- a/checkpy/caches.py +++ b/checkpy/caches.py @@ -1,58 +1,42 @@ import sys +from functools import wraps _caches = [] -class _Cache(object): - def __init__(self): - self._cache = {} - _caches.append(self) - def __setitem__(self, key, value): - self._cache[key] = value +class _Cache(dict): + """A dict() subclass that appends a self-reference to _caches""" + def __init__(self, *args, **kwargs): + super(_Cache, self).__init__(*args, **kwargs) + _caches.append(self) - def __getitem__(self, key): - return self._cache.get(key, None) - def __contains__(self, key): - return key in self._cache +def cache(*keys): + """cache decorator - def delete(self, key): - if key not in self._cache: - return False - del self._cache[key] - return True + Caches input and output of a function. If arguments are passed to + the decorator, take those as key for the cache. Otherwise use the + function arguments and sys.argv as key. - def clear(self): - self._cache.clear() + """ + def cacheWrapper(func): + localCache = _Cache() -""" -cache decorator -Caches input and output of a function. If arguments are passed to -the decorator, take those as key for the cache, otherwise the -function arguments. -""" -def cache(*keys): - def cacheWrapper(func, localCache = _Cache()): + @wraps(func) def cachedFuncWrapper(*args, **kwargs): if keys: - key = keys + key = str(keys) else: - # treat all collections in kwargs as tuples for hashing purposes - values = list(kwargs.values()) - for i in range(len(values)): - try: - values[i] = tuple(values[i]) - except TypeError: - pass - key = args + tuple(values) + tuple(sys.argv) + key = str(args) + str(kwargs) + str(sys.argv) if key not in localCache: localCache[key] = func(*args, **kwargs) - return localCache[key] return cachedFuncWrapper + return cacheWrapper + def clearAllCaches(): for cache in _caches: cache.clear()