Skip to content
Browse files

move the default setting into the decorator

  • Loading branch information...
1 parent 63082c1 commit 121d2ce951d768e33de13682ef92bde801a9f4e7 @jneen committed
Showing with 41 additions and 19 deletions.
  1. +4 −3 README.md
  2. +16 −13 src/cache/__init__.py
  3. +21 −3 test/cache_test.py
View
7 README.md
@@ -29,10 +29,8 @@ some_expensive_method()
some_expensive_method.refresh()
# get the cached value or throw an error
+# (unless default= was passed to @cache(...))
some_expensive_method.cached()
-
-# get the cached value or return 3
-some_expensive_method.cached(default=3)
```
## Options
@@ -50,6 +48,9 @@ Options can be passed to either the `Cache` constructor or the decorator. Optio
over the old values.
Default: False
+ default If given, `.cached()` will return the given value instead
+ of raising a KeyError.
+
The remaining options, if given, will be passed as keyword arguments to the backend's `set` method. This is useful for things like expiration times - for example, using pylibmc:
``` python
View
29 src/cache/__init__.py
@@ -84,38 +84,41 @@ class CacheWrapper:
"""
def __init__(self, backend, key, calculate,
- bust=False, enabled=True, **kw):
+ bust=False, enabled=True, default='__absent__', **kw):
self.backend = backend
self.key = key
self.calculate = calculate
+ self.default = default
self.bust = bust
self.enabled = enabled
self.options = kw
- def cached(self, *a, **kw):
+ def _has_default(self):
+ return self.default != '__absent__'
+
+ def _get_cached(self, *a, **kw):
if not self.enabled:
return self.calculate()
- default_given = False
- default_val = None
-
- if 'default' in kw:
- default_given = True
- default_val = kw.pop('default')
-
key = _prepare_key(self.key, *a, **kw)
cached = self.backend.get(key)
if cached is None:
- if default_given:
- return default_val
-
raise KeyError
return _unprepare_value(cached)
+ def cached(self, *a, **kw):
+ try:
+ return self._get_cached(*a, **kw)
+ except KeyError as e:
+ if self._has_default():
+ return self.default
+ else:
+ raise e
+
def refresh(self, *a, **kw):
fresh = self.calculate()
if self.enabled:
@@ -130,7 +133,7 @@ def get(self, *a, **kw):
return self.refresh(*a, **kw)
try:
- return self.cached(*a, **kw)
+ return self._get_cached(*a, **kw)
except KeyError:
return self.refresh(*a, **kw)
View
24 test/cache_test.py
@@ -51,16 +51,34 @@ def test_null():
backend = NullCache()
cache = Cache(backend)
- c = cache("counter")(CallCounter())
+ cc = CallCounter()
+
+ c = cache("counter")(cc)
assert c() == 1
assert c() == 2
- assert c.cached(default=42) == 42
try:
c.cached()
- assert False, 'should raise an error'
except KeyError:
pass
+ else:
+ assert False, "should raise KeyError"
+
+
+def test_default():
+ backend = NullCache()
+ cache = Cache(backend)
+
+ cc = CallCounter()
+
+ c = cache("counter", default=42)(cc)
+
+ assert c() == 1
+ assert c() == 2
+
+ # because we're using NullCache, the cache should always be
+ # empty.
+ assert c.cached() == 42
assert not backend.get("counter")

0 comments on commit 121d2ce

Please sign in to comment.
Something went wrong with that request. Please try again.