diff options
author | Thomas Kemmer <tkemmer@computer.org> | 2015-06-06 14:24:51 +0200 |
---|---|---|
committer | Thomas Kemmer <tkemmer@computer.org> | 2015-06-06 15:20:24 +0200 |
commit | ec80673eb18a43f2f0299235e4b625b30322b664 (patch) | |
tree | 9bd31d0acffb86cfab013312fa2df2e6ce8352ac | |
parent | 7827ec015a551f11c3ac55e3583b8592c4ae88d4 (diff) | |
download | cachetools-ec80673eb18a43f2f0299235e4b625b30322b664.tar.gz |
Fix #33: Code cleanup for improved PEP 8 conformance.
-rw-r--r-- | cachetools/__init__.py | 11 | ||||
-rw-r--r-- | cachetools/cache.py | 6 | ||||
-rw-r--r-- | cachetools/decorators.py | 97 | ||||
-rw-r--r-- | cachetools/func.py | 120 | ||||
-rw-r--r-- | cachetools/lfu.py | 11 | ||||
-rw-r--r-- | cachetools/lock.py | 6 | ||||
-rw-r--r-- | cachetools/lru.py | 11 | ||||
-rw-r--r-- | cachetools/method.py | 42 | ||||
-rw-r--r-- | cachetools/rr.py | 12 | ||||
-rw-r--r-- | cachetools/ttl.py | 11 | ||||
-rw-r--r-- | tests/test_cache.py | 3 | ||||
-rw-r--r-- | tests/test_lfu.py | 3 | ||||
-rw-r--r-- | tests/test_lru.py | 3 | ||||
-rw-r--r-- | tests/test_method.py (renamed from tests/test_cachedmethod.py) | 2 | ||||
-rw-r--r-- | tests/test_rr.py | 5 | ||||
-rw-r--r-- | tests/test_ttl.py | 3 |
16 files changed, 181 insertions, 165 deletions
diff --git a/cachetools/__init__.py b/cachetools/__init__.py index 6093731..14a068c 100644 --- a/cachetools/__init__.py +++ b/cachetools/__init__.py @@ -1,11 +1,12 @@ """Extensible memoizing collections and decorators""" from .cache import Cache -from .decorators import cachedmethod -from .lfu import LFUCache, lfu_cache -from .lru import LRUCache, lru_cache -from .rr import RRCache, rr_cache -from .ttl import TTLCache, ttl_cache +from .func import lfu_cache, lru_cache, rr_cache, ttl_cache +from .lfu import LFUCache +from .lru import LRUCache +from .method import cachedmethod +from .rr import RRCache +from .ttl import TTLCache __all__ = ( 'Cache', diff --git a/cachetools/cache.py b/cachetools/cache.py index 0c692f9..edb4986 100644 --- a/cachetools/cache.py +++ b/cachetools/cache.py @@ -1,10 +1,6 @@ import collections -def one(value): - return 1 - - class Cache(collections.MutableMapping): """Mutable mapping to serve as a simple cache or cache base class.""" @@ -13,7 +9,7 @@ class Cache(collections.MutableMapping): self.__currsize = 0 self.__maxsize = maxsize self.__missing = missing - self.__getsizeof = getsizeof or one + self.__getsizeof = getsizeof or (lambda x: 1) def __repr__(self): return '%s(%r, maxsize=%d, currsize=%d)' % ( diff --git a/cachetools/decorators.py b/cachetools/decorators.py deleted file mode 100644 index 7299251..0000000 --- a/cachetools/decorators.py +++ /dev/null @@ -1,97 +0,0 @@ -import collections -import functools - -CacheInfo = collections.namedtuple('CacheInfo', 'hits misses maxsize currsize') - - -class NullContext: - def __enter__(self): - pass - - def __exit__(self, exc_type, exc_val, exc_tb): - pass - -nullcontext = NullContext() - - -def makekey_untyped(args, kwargs): - return (args, tuple(sorted(kwargs.items()))) - - -def makekey_typed(args, kwargs): - key = makekey_untyped(args, kwargs) - key += tuple(type(v) for v in args) - key += tuple(type(v) for _, v in sorted(kwargs.items())) - return key - - -def cachedfunc(cache, typed=False, lock=None): - makekey = makekey_typed if typed else makekey_untyped - context = lock() if lock else nullcontext - - def decorator(func): - stats = [0, 0] - - def wrapper(*args, **kwargs): - key = makekey(args, kwargs) - with context: - try: - result = cache[key] - stats[0] += 1 - return result - except KeyError: - stats[1] += 1 - result = func(*args, **kwargs) - with context: - try: - cache[key] = result - except ValueError: - pass # value too large - return result - - def cache_info(): - with context: - hits, misses = stats - maxsize = cache.maxsize - currsize = cache.currsize - return CacheInfo(hits, misses, maxsize, currsize) - - def cache_clear(): - with context: - cache.clear() - - wrapper.cache_info = cache_info - wrapper.cache_clear = cache_clear - return functools.update_wrapper(wrapper, func) - - return decorator - - -def cachedmethod(cache, typed=False): - """Decorator to wrap a class or instance method with a memoizing - callable that saves results in a (possibly shared) cache. - - """ - makekey = makekey_typed if typed else makekey_untyped - - def decorator(method): - def wrapper(self, *args, **kwargs): - mapping = cache(self) - if mapping is None: - return method(self, *args, **kwargs) - key = makekey((method,) + args, kwargs) - try: - return mapping[key] - except KeyError: - pass - result = method(self, *args, **kwargs) - try: - mapping[key] = result - except ValueError: - pass # value too large - return result - - wrapper.cache = cache - return functools.update_wrapper(wrapper, method) - - return decorator diff --git a/cachetools/func.py b/cachetools/func.py new file mode 100644 index 0000000..4d88a78 --- /dev/null +++ b/cachetools/func.py @@ -0,0 +1,120 @@ +import collections +import functools +import random +import time + +from .lfu import LFUCache +from .lru import LRUCache +from .rr import RRCache +from .ttl import TTLCache + +try: + from threading import RLock +except ImportError: + from dummy_threading import RLock + + +_CacheInfo = collections.namedtuple('CacheInfo', [ + 'hits', 'misses', 'maxsize', 'currsize' +]) + + +class _NullContext: + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_val, exc_tb): + pass + + +_nullcontext = _NullContext() + + +def _makekey_untyped(args, kwargs): + return (args, tuple(sorted(kwargs.items()))) + + +def _makekey_typed(args, kwargs): + key = _makekey_untyped(args, kwargs) + key += tuple(type(v) for v in args) + key += tuple(type(v) for _, v in sorted(kwargs.items())) + return key + + +def _cachedfunc(cache, typed=False, lock=None): + makekey = _makekey_typed if typed else _makekey_untyped + context = lock() if lock else _nullcontext + + def decorator(func): + stats = [0, 0] + + def wrapper(*args, **kwargs): + key = makekey(args, kwargs) + with context: + try: + result = cache[key] + stats[0] += 1 + return result + except KeyError: + stats[1] += 1 + result = func(*args, **kwargs) + with context: + try: + cache[key] = result + except ValueError: + pass # value too large + return result + + def cache_info(): + with context: + hits, misses = stats + maxsize = cache.maxsize + currsize = cache.currsize + return _CacheInfo(hits, misses, maxsize, currsize) + + def cache_clear(): + with context: + cache.clear() + + wrapper.cache_info = cache_info + wrapper.cache_clear = cache_clear + return functools.update_wrapper(wrapper, func) + + return decorator + + +def lfu_cache(maxsize=128, typed=False, getsizeof=None, lock=RLock): + """Decorator to wrap a function with a memoizing callable that saves + up to `maxsize` results based on a Least Frequently Used (LFU) + algorithm. + + """ + return _cachedfunc(LFUCache(maxsize, getsizeof), typed, lock) + + +def lru_cache(maxsize=128, typed=False, getsizeof=None, lock=RLock): + """Decorator to wrap a function with a memoizing callable that saves + up to `maxsize` results based on a Least Recently Used (LRU) + algorithm. + + """ + return _cachedfunc(LRUCache(maxsize, getsizeof), typed, lock) + + +def rr_cache(maxsize=128, choice=random.choice, typed=False, getsizeof=None, + lock=RLock): + """Decorator to wrap a function with a memoizing callable that saves + up to `maxsize` results based on a Random Replacement (RR) + algorithm. + + """ + return _cachedfunc(RRCache(maxsize, choice, getsizeof), typed, lock) + + +def ttl_cache(maxsize=128, ttl=600, timer=time.time, typed=False, + getsizeof=None, lock=RLock): + """Decorator to wrap a function with a memoizing callable that saves + up to `maxsize` results based on a Least Recently Used (LRU) + algorithm with a per-item time-to-live (TTL) value. + """ + return _cachedfunc(TTLCache(maxsize, ttl, timer, getsizeof), typed, lock) diff --git a/cachetools/lfu.py b/cachetools/lfu.py index 0afa9c9..d163cba 100644 --- a/cachetools/lfu.py +++ b/cachetools/lfu.py @@ -2,8 +2,6 @@ import collections import operator from .cache import Cache -from .decorators import cachedfunc -from .lock import RLock class LFUCache(Cache): @@ -33,12 +31,3 @@ class LFUCache(Cache): except ValueError: raise KeyError('cache is empty') return key, self.pop(key) - - -def lfu_cache(maxsize=128, typed=False, getsizeof=None, lock=RLock): - """Decorator to wrap a function with a memoizing callable that saves - up to `maxsize` results based on a Least Frequently Used (LFU) - algorithm. - - """ - return cachedfunc(LFUCache(maxsize, getsizeof), typed, lock) diff --git a/cachetools/lock.py b/cachetools/lock.py deleted file mode 100644 index 33c7c89..0000000 --- a/cachetools/lock.py +++ /dev/null @@ -1,6 +0,0 @@ -# flake8: noqa - -try: - from threading import RLock -except ImportError: - from dummy_threading import RLock diff --git a/cachetools/lru.py b/cachetools/lru.py index dbc9786..67ac797 100644 --- a/cachetools/lru.py +++ b/cachetools/lru.py @@ -1,6 +1,4 @@ from .cache import Cache -from .decorators import cachedfunc -from .lock import RLock class Link(object): @@ -85,12 +83,3 @@ class LRUCache(Cache): Cache.__delitem__(self, key) link.unlink() return (key, link.value) - - -def lru_cache(maxsize=128, typed=False, getsizeof=None, lock=RLock): - """Decorator to wrap a function with a memoizing callable that saves - up to `maxsize` results based on a Least Recently Used (LRU) - algorithm. - - """ - return cachedfunc(LRUCache(maxsize, getsizeof), typed, lock) diff --git a/cachetools/method.py b/cachetools/method.py new file mode 100644 index 0000000..2d04f44 --- /dev/null +++ b/cachetools/method.py @@ -0,0 +1,42 @@ +import functools + + +def _makekey_untyped(method, args, kwargs): + return (method, args, tuple(sorted(kwargs.items()))) + + +def _makekey_typed(method, args, kwargs): + key = _makekey_untyped(method, args, kwargs) + key += tuple(type(v) for v in args) + key += tuple(type(v) for _, v in sorted(kwargs.items())) + return key + + +def cachedmethod(cache, typed=False): + """Decorator to wrap a class or instance method with a memoizing + callable that saves results in a (possibly shared) cache. + + """ + makekey = _makekey_typed if typed else _makekey_untyped + + def decorator(method): + def wrapper(self, *args, **kwargs): + mapping = cache(self) + if mapping is None: + return method(self, *args, **kwargs) + key = makekey(method, args, kwargs) + try: + return mapping[key] + except KeyError: + pass + result = method(self, *args, **kwargs) + try: + mapping[key] = result + except ValueError: + pass # value too large + return result + + wrapper.cache = cache + return functools.update_wrapper(wrapper, method) + + return decorator diff --git a/cachetools/rr.py b/cachetools/rr.py index 5119c48..143223b 100644 --- a/cachetools/rr.py +++ b/cachetools/rr.py @@ -1,8 +1,6 @@ import random from .cache import Cache -from .decorators import cachedfunc -from .lock import RLock class RRCache(Cache): @@ -25,13 +23,3 @@ class RRCache(Cache): def choice(self): """The `choice` function used by the cache.""" return self.__choice - - -def rr_cache(maxsize=128, choice=random.choice, typed=False, getsizeof=None, - lock=RLock): - """Decorator to wrap a function with a memoizing callable that saves - up to `maxsize` results based on a Random Replacement (RR) - algorithm. - - """ - return cachedfunc(RRCache(maxsize, choice, getsizeof), typed, lock) diff --git a/cachetools/ttl.py b/cachetools/ttl.py index db35aa3..73c545a 100644 --- a/cachetools/ttl.py +++ b/cachetools/ttl.py @@ -2,8 +2,6 @@ import functools import time from .cache import Cache -from .decorators import cachedfunc -from .lock import RLock class Link(object): @@ -225,12 +223,3 @@ class TTLCache(Cache): get = __nested(Cache.get) pop = __nested(Cache.pop) setdefault = __nested(Cache.setdefault) - - -def ttl_cache(maxsize=128, ttl=600, timer=time.time, typed=False, - getsizeof=None, lock=RLock): - """Decorator to wrap a function with a memoizing callable that saves - up to `maxsize` results based on a Least Recently Used (LRU) - algorithm with a per-item time-to-live (TTL) value. - """ - return cachedfunc(TTLCache(maxsize, ttl, timer, getsizeof), typed, lock) diff --git a/tests/test_cache.py b/tests/test_cache.py index 433a733..3b78515 100644 --- a/tests/test_cache.py +++ b/tests/test_cache.py @@ -1,8 +1,9 @@ import unittest -from . import CacheTestMixin from cachetools import Cache +from . import CacheTestMixin + class CacheTest(unittest.TestCase, CacheTestMixin): diff --git a/tests/test_lfu.py b/tests/test_lfu.py index 3b69647..1c4741b 100644 --- a/tests/test_lfu.py +++ b/tests/test_lfu.py @@ -1,8 +1,9 @@ import unittest -from . import CacheTestMixin, DecoratorTestMixin from cachetools import LFUCache, lfu_cache +from . import CacheTestMixin, DecoratorTestMixin + class LFUCacheTest(unittest.TestCase, CacheTestMixin, DecoratorTestMixin): diff --git a/tests/test_lru.py b/tests/test_lru.py index f21170d..5eea036 100644 --- a/tests/test_lru.py +++ b/tests/test_lru.py @@ -1,8 +1,9 @@ import unittest -from . import CacheTestMixin, DecoratorTestMixin from cachetools import LRUCache, lru_cache +from . import CacheTestMixin, DecoratorTestMixin + class LRUCacheTest(unittest.TestCase, CacheTestMixin, DecoratorTestMixin): diff --git a/tests/test_cachedmethod.py b/tests/test_method.py index 1440352..82337e0 100644 --- a/tests/test_cachedmethod.py +++ b/tests/test_method.py @@ -1,5 +1,5 @@ -import unittest import operator +import unittest from cachetools import LRUCache, cachedmethod diff --git a/tests/test_rr.py b/tests/test_rr.py index 7af9863..b6d2f2c 100644 --- a/tests/test_rr.py +++ b/tests/test_rr.py @@ -1,9 +1,10 @@ -import unittest import random +import unittest -from . import CacheTestMixin, DecoratorTestMixin from cachetools import RRCache, rr_cache +from . import CacheTestMixin, DecoratorTestMixin + class RRCacheTest(unittest.TestCase, CacheTestMixin, DecoratorTestMixin): diff --git a/tests/test_ttl.py b/tests/test_ttl.py index d562c1c..c6253c2 100644 --- a/tests/test_ttl.py +++ b/tests/test_ttl.py @@ -1,8 +1,9 @@ import unittest -from . import CacheTestMixin, DecoratorTestMixin from cachetools import TTLCache, ttl_cache +from . import CacheTestMixin, DecoratorTestMixin + class Timer: def __init__(self, auto=False): |