1. Nicolas Perriault
  2. django-cache-utils

Source

django-cache-utils / cache_utils / utils.py

from hashlib import md5
from django.utils.encoding  import smart_unicode


def _args_to_unicode(args, kwargs):
    """Transforms passed args and kwargs to unicode string."""
    key = u""
    if args:
        key += smart_unicode(args)
    if kwargs:
        key += smart_unicode(kwargs)
    return key


def _encode_key(key):
    """Encodes a key using hash() to prevent problems with Unicode
       @see http://bugs.python.org/issue2948
    """
    return md5(str(hash(key))).hexdigest()


def _func_type(func):
    """ returns if callable is a function, method or a classmethod """
    argnames = func.func_code.co_varnames[:func.func_code.co_argcount]
    if len(argnames) > 0:
        if argnames[0] == 'self':
            return 'method'
        if argnames[0] == 'cls':
            return 'classmethod'
    return 'function'


def _func_info(func, args):
    """ introspect function's or method's full name.
    Returns a tuple (name, normalized_args,) with
    'cls' and 'self' removed from normalized_args 
    """
    func_type = _func_type(func)
    if func_type == 'function':
        return ".".join([func.__module__, func.__name__]), args
    class_name = args[0].__class__.__name__
    if func_type == 'classmethod':
        class_name = args[0].__name__

    return ".".join([func.__module__, class_name, func.__name__]), args[1:]


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, _encode_key(args_string),)