1 from hashlib import md5
3 CONTROL_CHARACTERS = set([chr(i) for i in range(0,33)])
4 CONTROL_CHARACTERS.add(chr(127))
6 def sanitize_memcached_key(key, max_length=250):
7 """ Removes control characters and ensures that key will
8 not hit the memcached key length limit by replacing
9 the key tail with md5 hash if key is too long.
11 key = ''.join([c for c in key if c not in CONTROL_CHARACTERS])
12 if len(key) > max_length:
13 hash = md5(key).hexdigest()
14 key = key[:max_length-33]+'-'+hash
17 def _args_to_unicode(args, kwargs):
22 key += unicode(kwargs)
27 """ returns if callable is a function, method or a classmethod """
28 argnames = func.func_code.co_varnames[:func.func_code.co_argcount]
30 if argnames[0] == 'self':
32 if argnames[0] == 'cls':
37 def _func_info(func, args):
38 ''' introspect function's or method's full name.
39 Returns a tuple (name, normalized_args,) with
40 'cls' and 'self' removed from normalized_args '''
42 func_type = _func_type(func)
44 if func_type == 'function':
45 return ".".join([func.__module__, func.__name__]), args
47 class_name = args[0].__class__.__name__
48 if func_type == 'classmethod':
49 class_name = args[0].__name__
51 return ".".join([func.__module__, class_name, func.__name__]), args[1:]
54 def _cache_key(func_name, func_type, args, kwargs):
55 """ Construct readable cache key """
56 if func_type == 'function':
57 args_string = _args_to_unicode(args, kwargs)
59 args_string = _args_to_unicode(args[1:], kwargs)
60 return sanitize_memcached_key('[cached]%s(%s)' % (func_name, args_string,))