Example #1
0
def _get_namespace_prefix(namespace):
    '''
    Gets (or sets if uninitialized) the key prefix for the given namespace 
    string. The return value will prepend any keys that belong to the namespace.
    '''
    ns_key = cache.get(namespace)
    if not ns_key:
        ns_key = _make_namespace_prefix()
        cache.set(namespace, ns_key)

    # Compact the key before returning it to save space when using it.
    return pack_int(ns_key)
Example #2
0
def _get_namespace_prefix(namespace):
    '''
    Gets (or sets if uninitialized) the key prefix for the given namespace 
    string. The return value will prepend any keys that belong to the namespace.
    '''
    ns_key = cache.get(namespace)
    if not ns_key:
        ns_key = _make_namespace_prefix()
        cache.set(namespace, ns_key)

    # Compact the key before returning it to save space when using it.
    return pack_int(ns_key)
Example #3
0
def _make_key_args_from_function(func, *args, **kwargs):
    '''
    Add a bunch of hopefully uniquely identifying parameters to a list to be 
    passed to `make_key`. It's pretty crafty in finding distinguishing params
    to use, but it is slightly conservative so as to not overrun the memcached 
    key length limit, which results in a non-human-readable hash for a key.
    '''
    key_args = ['cached_func', func.__name__]

    # This works on both functions and class methods.
    signature_args = inspect.getargspec(func).args
    if (inspect.ismethod(func)
            or (signature_args and signature_args[0] in ['self', 'cls'])):
        # Method, probably.
        #
        # If ismethod returns True, it's definitely a method. Otherwise,
        # we have to guess based on the first arg of the function's signature.
        # This is the best guess we can have in Python, because the way a
        # function is passed to a decorator inside a class definition, the
        # decorated function is as yet neither a bound nor unbound method. It's
        # just a regular function. So we must guess from its args.
        #
        # A guess is good enough, since it only means that we add some extra
        # fields from the first arg. If we're wrong, the key is more
        # conservative (more detailed) than need be. We could wrongly call it a
        # function when it's actually a method, but only if they're doing
        # unsightly things like naming the "self" or "cls" arg something else.
        self = args[0]
        key_args.append(self.__class__.__name__)
        if hasattr(self,
                   'pk'):  # django model? `pk` is a great differentiator!
            key_args.append(self.pk)
        key_args.extend(args[1:])
    else:
        # Function.
        key_args.extend(args)
    key_args.extend(kwargs.values())

    # To be extra safe! (unreadable, so at end of key.)
    # If this results in any collisions, it actually won't make a difference.
    # It's fine to memoize functions that collide on this as if
    # they are one, since they're identical if their codeblock hash is the same.
    key_args.append(pack_int(func.__code__.__hash__()))
    return key_args
Example #4
0
def _make_key_args_from_function(func, *args, **kwargs):
    '''
    Add a bunch of hopefully uniquely identifying parameters to a list to be 
    passed to `make_key`. It's pretty crafty in finding distinguishing params
    to use, but it is slightly conservative so as to not overrun the memcached 
    key length limit, which results in a non-human-readable hash for a key.
    '''
    key_args = ['cached_func', func.__name__]

    # This works on both functions and class methods.
    signature_args = inspect.getargspec(func).args
    if (inspect.ismethod(func)
        or (signature_args and signature_args[0] in ['self', 'cls'])):
        # Method, probably. 
        #
        # If ismethod returns True, it's definitely a method. Otherwise,
        # we have to guess based on the first arg of the function's signature.
        # This is the best guess we can have in Python, because the way a 
        # function is passed to a decorator inside a class definition, the
        # decorated function is as yet neither a bound nor unbound method. It's
        # just a regular function. So we must guess from its args.
        #
        # A guess is good enough, since it only means that we add some extra
        # fields from the first arg. If we're wrong, the key is more
        # conservative (more detailed) than need be. We could wrongly call it a
        # function when it's actually a method, but only if they're doing 
        # unsightly things like naming the "self" or "cls" arg something else.
        self = args[0]
        key_args.append(self.__class__.__name__)
        if hasattr(self, 'pk'): # django model? `pk` is a great differentiator!
            key_args.append(self.pk)
        key_args.extend(args[1:])
    else:
        # Function.
        key_args.extend(args)
    key_args.extend(kwargs.values())

    # To be extra safe! (unreadable, so at end of key.)
    # If this results in any collisions, it actually won't make a difference.
    # It's fine to memoize functions that collide on this as if
    # they are one, since they're identical if their codeblock hash is the same.
    key_args.append(pack_int(func.__code__.__hash__()))
    return key_args