Skip to content
Create a gist now

Instantly share code, notes, and snippets.

Cache key generator, can be used for things like dogpile.cache
Based on code of dogpile.cache.util.function_key_generator(...) but adds support for kw.
Related dogpile.cache bug:
from dogpile.cache import make_region
my_region = make_region(
def make_key_generator(namespace, fn, value_mangler=str, arg_blacklist=('self', 'cls')):
Create a cache key generator for function calls of fn.
:param namespace:
Value to prefix all keys with. Useful for differentiating methods with
the same name but in different classes.
:param fn:
Function to create a key generator for.
:param value_mangler:
Each value passed to the function is run through this mangler.
Default: str
:param arg_blacklist:
Iterable of arguments to ignore when creating a key.
Returns a function which can be called with the same arguments as fn but
returns a corresponding key for that call.
Note: Ingores fn(..., *arg, **kw) parameters.
# TODO: Include parent class in name?
# TODO: Handle undefined vararg and kw?
# TODO: Better default value_mangler?
fn_args = inspect.getargspec(fn).args
arg_blacklist = arg_blacklist or []
if namespace is None:
namespace = '%s:%s' % (fn.__module__, fn.__name__)
namespace = '%s:%s|%s' % (fn.__module__, fn.__name__, namespace)
def generate_key(*arg, **kw):
kw.update(zip(fn_args, arg))
for arg in arg_blacklist:
kw.pop(arg, None)
key = namespace + '|' + ' '.join(value_mangler(kw[k]) for k in sorted(kw))
return key
return generate_key
>>> def generate_key(*arg, **kw):     
        kw.update(zip(fn_args, arg))
        return ' '.join(str(kw[k]) for k in sorted(kw))

>>> fn_args = ('self', 'arg1', 'arg2')

>>> generate_key(None, 2, 3, kw1='kw1', kw3='kw3')
>>> '2 3 kw1 kw3 None'

>>> generate_key(None, 2, 3, kw1='kw1', kw2='kw3')
>>> '2 3 kw1 kw3 None'

sorted(kw) makes the same key in two different cases when keyword argument names differ but their sorting order is the same.

I think keyword argument names should be included in the key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.