Commits

Mikhail Korobov committed 96fa235

Fix invalidation of methods

Comments (0)

Files changed (4)

cache_utils/decorators.py

 #coding: utf-8
 from django.core.cache import cache
 from django.utils.functional import wraps
-from cache_utils.utils import readable_cache_key
+from cache_utils.utils import _cache_key, _func_info, _func_type
 
 def cached(timeout, group=None):
     """ Caching decorator. Can be applied to function, method or classmethod.
 
     def _cached(func):
 
-        def cache_key(*args, **kwargs):
-            ''' returns cache key for given arguments '''
-            return readable_cache_key(func, args, kwargs)
-
-        def invalidate(*args, **kwargs):
-            ''' invalidates cache result for function called with passed arguments '''
-            key = cache_key(*args, **kwargs)
-            cache.delete(key, **backend_kwargs)
+        func_type = _func_type(func)
 
         @wraps(func)
         def wrapper(*args, **kwargs):
 
+            # full name is stored as attribute on first call
+            if not hasattr(wrapper, '_full_name'):
+                name, _args = _func_info(func, args)
+                wrapper._full_name = name
+
             # try to get the value from cache
-            key = cache_key(*args, **kwargs)
+            key = _cache_key(wrapper._full_name, func_type, args, kwargs)
             value = cache.get(key, **backend_kwargs)
 
             # in case of cache miss recalculate the value and put it to the cache
                 cache.set(key, value, timeout, **backend_kwargs)
             return value
 
-        wrapper.cache_key = cache_key
+        def invalidate(*args, **kwargs):
+            ''' invalidates cache result for function called with passed arguments '''
+            key = _cache_key(wrapper._full_name, 'function', args, kwargs)
+            cache.delete(key, **backend_kwargs)
+
         wrapper.invalidate = invalidate
-
         return wrapper
     return _cached

cache_utils/tests.py

 
 from django.core.cache import cache
 from cache_utils.decorators import cached
-from cache_utils.utils import sanitize_memcached_key, _func_type, _func_info,\
-    readable_cache_key
+from cache_utils.utils import sanitize_memcached_key, _func_type, _func_info
 
 def foo(a,b):
     pass
         self.assertTrue(len(key) <= 40)
 
 
-class ReadableKeysTest(TestCase):
-
-    def test_key_is_readable(self):
-        key = readable_cache_key(foo, [1], {'b': 'foo'})
-        self.assertEqual(key, u"[cached]cache_utils.tests.foo([1]{'b': 'foo'})")
-
-
 class ClearMemcachedTest(TestCase):
     def tearDown(self):
         cache._cache.flush_all()

cache_utils/utils.py

     return ".".join([func.__module__, class_name, func.__name__]), args[1:]
 
 
-def readable_cache_key(func, args, kwargs):
-    """ Construct readable cache key using callable's full name and
-    passed parameters """
-    func_name, normalized_args = _func_info(func, args)
-    args_string = _args_to_unicode(normalized_args, kwargs)
+def _cache_key(func_name, func_type, args, kwargs):
+    """ Construct readable cache key """
+    if func_type == 'function':
+        args_string = _args_to_unicode(args, kwargs)
+    else:
+        args_string = _args_to_unicode(args[1:], kwargs)
     return '[cached]%s(%s)' % (func_name, args_string,)
-
 #!/usr/bin/env python
 from distutils.core import setup
 
-version='0.6.0'
+version='0.6.1'
 
 setup(
     name='django-cache-utils',