diff options
author | Cosmin Basca <cosmin.basca@gmail.com> | 2014-08-12 14:42:06 +0200 |
---|---|---|
committer | Cosmin Basca <cosmin.basca@gmail.com> | 2014-08-12 14:42:06 +0200 |
commit | 48c581683997c4f109402b2cb54faa336378e31b (patch) | |
tree | 4e4df9d19913457d0576b88c648b87efa43aa862 /repoze | |
parent | 6cc09af1f47b6eaa558e8b389350d5865e8f990f (diff) | |
download | repoze-lru-48c581683997c4f109402b2cb54faa336378e31b.tar.gz |
bumped version to 0.7.1
in this commit:
- test coverage for kwargs and args
- methods that have unhashable types as arguments (in args or kwargs)
are not cached via the decorator mechanisms, instead a warning is issued. (Warnings can be disabled, and perhaps later removed altoghether if decided so)
- new __version__.py file where version is defined
tests pass on my box, (py2.7 on mac os X)
Diffstat (limited to 'repoze')
-rw-r--r-- | repoze/lru/__init__.py | 34 | ||||
-rw-r--r-- | repoze/lru/__version__.py | 2 | ||||
-rw-r--r-- | repoze/lru/tests.py | 22 |
3 files changed, 50 insertions, 8 deletions
diff --git a/repoze/lru/__init__.py b/repoze/lru/__init__.py index 8e8b571..94bbe6c 100644 --- a/repoze/lru/__init__.py +++ b/repoze/lru/__init__.py @@ -5,6 +5,7 @@ from abc import ABCMeta, abstractmethod import threading import time import uuid +from warnings import warn _MARKER = object() @@ -12,6 +13,18 @@ _MARKER = object() # integers and is close enough to "never" for practical purposes. _DEFAULT_TIMEOUT = 2 ** 60 +_WARN = True + + +def disable_warnings(): + global _WARN + _WARN = False + + +def enable_warnings(): + global _WARN + _WARN = True + class Cache(object): __metaclass__ = ABCMeta @@ -170,7 +183,7 @@ class LRUCache(Cache): # We have no lock, but worst thing that can happen is that we # set another key's entry to False. self.clock_refs[entry[0]] = False - # else: key was not in cache. Nothing to do. + # else: key was not in cache. Nothing to do. class ExpiringLRUCache(Cache): @@ -305,7 +318,7 @@ class ExpiringLRUCache(Cache): # We have no lock, but worst thing that can happen is that we # set another key's entry to False. self.clock_refs[entry[0]] = False - # else: key was not in cache. Nothing to do. + # else: key was not in cache. Nothing to do. class lru_cache(object): @@ -330,12 +343,17 @@ class lru_cache(object): marker = _MARKER def cached_wrapper(*args, **kwargs): - key = (args, frozenset(kwargs.items())) - val = cache.get(key, marker) - if val is marker: - val = func(*args, **kwargs) - cache.put(key, val) - return val + try: + key = (args, frozenset(kwargs.items())) if kwargs else args + val = cache.get(key, marker) + if val is marker: + val = func(*args, **kwargs) + cache.put(key, val) + return val + except TypeError: # unhashable types in args or kwargs + if _WARN: + warn("method call could not be cached, *args and/or **kwargs contain unhashable types") + return func(*args, **kwargs) def _maybe_copy(source, target, attr): value = getattr(source, attr, source) diff --git a/repoze/lru/__version__.py b/repoze/lru/__version__.py new file mode 100644 index 0000000..27e0100 --- /dev/null +++ b/repoze/lru/__version__.py @@ -0,0 +1,2 @@ +version = (0, 7, 1) +str_version = '.'.join(['{0}'.format(v) for v in version])
\ No newline at end of file diff --git a/repoze/lru/tests.py b/repoze/lru/tests.py index 504fd9f..1408b89 100644 --- a/repoze/lru/tests.py +++ b/repoze/lru/tests.py @@ -539,6 +539,28 @@ class DecoratorTests(unittest.TestCase): self.assertEqual(result, (3, 4, 5)) self.assertEqual(len(cache), 1) + def test_multiargs_keywords(self): + cache = DummyLRUCache() + decorator = self._makeOne(0, cache) + def moreargs(*args, **kwargs): + return args, kwargs + decorated = decorator(moreargs) + result = decorated(3, 4, 5, a=1, b=2, c=3) + self.assertEqual(cache[((3, 4, 5), frozenset([ ('a',1), ('b',2), ('c',3) ]))], ((3, 4, 5), {'a':1, 'b':2, 'c':3})) + self.assertEqual(result, ((3, 4, 5), {'a':1, 'b':2, 'c':3})) + self.assertEqual(len(cache), 1) + + def test_multiargs_keywords_unhashable(self): + cache = DummyLRUCache() + decorator = self._makeOne(0, cache) + def moreargs(*args, **kwargs): + return args, kwargs + decorated = decorator(moreargs) + result = decorated(3, 4, 5, a=1, b=[1,2,3]) + self.assertEqual(len(cache), 0) + self.assertEqual(result, ((3, 4, 5), {'a':1, 'b':[1,2,3]})) + + def test_expiry(self): #When timeout is given, decorator must eventually forget entries @self._makeOne(1, None, timeout=0.1) |