summaryrefslogtreecommitdiff
path: root/repoze
diff options
context:
space:
mode:
authorCosmin Basca <cosmin.basca@gmail.com>2014-08-12 14:42:06 +0200
committerCosmin Basca <cosmin.basca@gmail.com>2014-08-12 14:42:06 +0200
commit48c581683997c4f109402b2cb54faa336378e31b (patch)
tree4e4df9d19913457d0576b88c648b87efa43aa862 /repoze
parent6cc09af1f47b6eaa558e8b389350d5865e8f990f (diff)
downloadrepoze-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__.py34
-rw-r--r--repoze/lru/__version__.py2
-rw-r--r--repoze/lru/tests.py22
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)