django_auxilium.utils.functools.cache module

class django_auxilium.utils.functools.cache.BaseCache(parent, attr)[source]

Bases: object

Base class for implementing cache implementations

Parameters:
  • parent (object) – A parent object where cache is stored
  • attr (str) – Name of the attribute under which cache will be stored in the parent object
delete(*args, **kwargs)[source]

This method must be overwritten by subclasses which should delete cache value for the given parameters

args and kwargs are the parameters passed to the cached function and can be used by the method to determine which cache value from the parent object to remove

When cache value is not found, this method should raise NotInCache

get(*args, **kwargs)[source]

This method must be overwritten by subclasses which should return cache value

args and kwargs are the parameters passed to the cached function and can be used by the method to extract the cache value from the parent object

When cache value is not found, this method should raise NotInCache

set(value, *args, **kwargs)[source]

This method must be overwritten by subclasses which should set the cache for the given parameters

args and kwargs are the parameters passed to the cached function and can be used by the method to correctly store the cache value in the parent object

class django_auxilium.utils.functools.cache.BaseCacheDecorator(is_method=None)[source]

Bases: django_auxilium.utils.functools.decorators.HybridDecorator

Base decorator for caching callables so that they only execute once and all subsequent calls return cached value

This is very useful for expensive functions

cache_class

Caching implementation to use when wrapping standalone functions. This attribute is meant to be changed in subclasses.

alias of Caching

cache_descriptor_class = None

Descriptor class to be used when caching is applied to class methods. This attribute is meant to be changed in subclasses.

get_cache_descriptor()[source]

Hook for instantiating cache descriptor class

get_wrapped_object()[source]

Main method for wrapping the given object.

This method has separate code paths for the following scenarios:

Class method:When wrapping class method descriptor is returned as created by get_cache_descriptor(). That descriptor is then responsible for maintaining cache state for the class instance.
Function:When wrapping standalone function, this method returns a wrapping function which caches the value on this decorator instance. That means that the cache becomes global since functions in Python are singletons.
pop(*args, **kwargs)[source]

Method for popping cache value corresponding to the given parameters

class django_auxilium.utils.functools.cache.CacheDecorator(as_property=False, *args, **kwargs)[source]

Bases: django_auxilium.utils.functools.cache.BaseCacheDecorator

Decorator for caching callables so that they only execute once and all subsequent calls return cached value.

Note

This caching decorator does not account function parameters to cache values. If you need to cache different calls per given parameters, please look at MemoizeDecorator

Examples

When caching standalone functions:

>>> @CacheDecorator.as_decorator()
... def compute():
...     print('computing here')
...     return 'foo'

>>> print(compute())
computing here
foo
>>> print(compute())
foo

>>> print(compute.pop())
foo

>>> print(compute())
computing here
foo

When caching class methods:

>>> class Foo(object):
...     @CacheDecorator.as_decorator()
...     def foo(self):
...         print('computing here')
...         return 'foo'

>>> f = Foo()
>>> print(f.foo())
computing here
foo
>>> print(f.foo())
foo

>>> print(f.foo.pop())
foo

>>> print(f.foo())
computing here
foo
Parameters:as_property (bool) –

Boolean whether to create a property descriptor when using it on a class method

Warning

This is only meant to be used when the wrapping method does not accept any parameters since there is no way in Python to pass parameters to properties

cache_class

Caching implementation to use when wrapping standalone functions.

alias of Caching

cache_descriptor_class

Descriptor class to be used when caching is applied to class methods

alias of CacheDescriptor

get_cache_descriptor()[source]

Custom implementation for getting the cache descriptor which allows to use as_property parameter

class django_auxilium.utils.functools.cache.CacheDescriptor(method, cache_class=None, as_property=False)[source]

Bases: object

Cache descriptor to be used to add instance-level cache to class methods.

Note

This descriptor could be used independently (and there are even some examples below) however it is meant to be used along with CacheDecorator which provides much cleaner API.

Examples

>>> def bar(self):
...     print('computing')
...     return 'bar'

>>> class Foo(object):
...     foo = CacheDescriptor(bar)

>>> f = Foo()
>>> print(f.foo())
computing
bar
>>> print(f.foo())
bar
>>> print(f.foo.pop())
bar
>>> print(f.foo())
computing
bar
>>> f.foo.push('another value')
>>> print(f.foo())
another value
Parameters:
  • method (function) – Callable which this descriptor is meant to wrap and cache
  • cache_class (type, optional) – Caching implementation cache which should be used to apply caching. By default default_cache_class is used.
  • as_property (bool, optional) –

    Whether to implement the descriptor as a property. By default it is False.

    Warning

    This option as True can only be used with some caching implementations such as Caching. Other implementations do not suppose this.

cache_attribute_pattern = u'{name}_cache_{hash}'

String pattern for constructing the cache attribute name under which cache will be stored on the instance. This attribute is meant to be changed in subclasses to customize the functionality.

default_cache_class

Cache implementation class which will be used for the caching. This attribute is meant to be changed in subclasses to customize the functionality.

alias of Caching

get_cache(instance)[source]

Helper method which given returns cache implementation instance for the given instance with given parameters

getter(instance, *args, **kwargs)[source]

Wrapper method around the decorator-wrapped callable (method parameter) which returns cache value when available or otherwise computes and stores the value in cache by evaluating wrapped method

pop(instance, *args, **kwargs)[source]

Method for popping cache value corresponding to the given parameters from the instance as implemented by the caching implementation

push(instance, value, *args, **kwargs)[source]

Method for setting custom cache value given function parameters

class django_auxilium.utils.functools.cache.Caching(parent, attr)[source]

Bases: django_auxilium.utils.functools.cache.BaseCache

Caching implementation which stores single cache value on the parent object

The cache is simply stored on the given attribute. When the attribute is present on the parent object, that indicates that the cache was set and that value is used for cache. When not present, that means cache is missing and hence NotInCache is raised in most use-cases.

delete(*args, **kwargs)[source]

Delete the cache value from the parent object

Raises:NotInCache – When the cache is not set and so cannot be deleted
get(*args, **kwargs)[source]

Get the cache value from the parent object

Raises:NotInCache – When the cache is not set
set(value, *args, **kwargs)[source]

Store the cache value on the parent object

class django_auxilium.utils.functools.cache.MemoizeDecorator(is_method=None)[source]

Bases: django_auxilium.utils.functools.cache.BaseCacheDecorator

Decorator for memoizing functions so that they only execute once and all subsequent calls with same parameters

This is very useful for expensive functions which accept parameters

Examples

When caching standalone functions:

>>> @MemoizeDecorator.as_decorator()
... def compute(x):
...     print('computing for', x)
...     return x + 'foo'

>>> print(compute('bar'))
computing for bar
barfoo
>>> print(compute('awesome'))
computing for awesome
awesomefoo
>>> print(compute('bar'))
barfoo

>>> print(compute.pop('bar'))
barfoo

>>> print(compute('bar'))
computing for bar
barfoo
>>> print(compute('awesome'))
awesomefoo

When caching class methods:

>>> class Foo(object):
...     @MemoizeDecorator.as_decorator()
...     def foo(self, x):
...         print('computing for', x)
...         return x + 'foo'

>>> f = Foo()
>>> print(f.foo('bar'))
computing for bar
barfoo
>>> print(f.foo('awesome'))
computing for awesome
awesomefoo

>>> print(f.foo('bar'))
barfoo
>>> print(f.foo('awesome'))
awesomefoo

>>> print(f.foo.pop('bar'))
barfoo

>>> print(f.foo('bar'))
computing for bar
barfoo
>>> print(f.foo('awesome'))
awesomefoo
cache_class

Caching implementation to use when wrapping standalone functions.

alias of Memoizing

cache_descriptor_class

Descriptor class to be used when caching is applied to class methods

alias of MemoizeDescriptor

class django_auxilium.utils.functools.cache.MemoizeDescriptor(method, cache_class=None, as_property=False)[source]

Bases: django_auxilium.utils.functools.cache.CacheDescriptor

Cache descriptor to be used to add instance-level cache to class methods which considers method parameters when caching values.

In other words, this descriptor caches method results per given parameters.

Note

This descriptor could be used independently (and there are even some examples below) however it is meant to be used along with MemoizeDecorator which provides much cleaner API.

Examples

>>> def bar(self, x):
...     print('computing for', x)
...     return x + 'bar'

>>> class Foo(object):
...     foo = MemoizeDescriptor(bar)

>>> f = Foo()
>>> print(f.foo('foo'))
computing for foo
foobar
>>> print(f.foo('awesome'))
computing for awesome
awesomebar
>>> print(f.foo('foo'))
foobar
>>> print(f.foo.pop('foo'))
foobar
>>> print(f.foo('foo'))
computing for foo
foobar
>>> print(f.foo('awesome'))
awesomebar
cache_attribute_pattern = u'{name}_memoize_{hash}'

String pattern for constructing the cache attribute name under which cache will be stored on the instance. This attribute is meant to be changed in subclasses to customize the functionality.

default_cache_class

Cache implementation class which will be used for the caching. This attribute is meant to be changed in subclasses to customize the functionality.

alias of Memoizing

class django_auxilium.utils.functools.cache.Memoizing(parent, attr)[source]

Bases: django_auxilium.utils.functools.cache.BaseCache

Caching implementation which stores single cache value for a set of given parameters on the parent object hence is called memoization

The cache is stored on the given attribute as a dictionary. Keys are string representations of the given parameters to the cached function and the values are their corresponding cache values. When the key is in the dictionary, that is used as cache value. Otherwise, in most cases NotInCache is raised.

delete(*args, **kwargs)[source]

Delete the cache value from the parent object for the key as computed by the given parameters

Raises:NotInCache – When the cache is not set and so cannot be deleted
get(*args, **kwargs)[source]

Get the cache value from the parent object by computing the key from the given parameters

Raises:NotInCache – When the cache is not set
set(value, *args, **kwargs)[source]

Store the cache value on the parent object for the key as computed for the given parameters

exception django_auxilium.utils.functools.cache.NotInCache[source]

Bases: exceptions.Exception

Exception for when a value is not present in cache.

Primary purpose of the exception is to normalize various exception types from different cache implementations.

django_auxilium.utils.functools.cache.cache(*args, **kwargs)

Decorator for caching callables so that they only execute once and all subsequent calls return cached value.

Note

This caching decorator does not account function parameters to cache values. If you need to cache different calls per given parameters, please look at MemoizeDecorator

Examples

When caching standalone functions:

>>> @CacheDecorator.as_decorator()
... def compute():
...     print('computing here')
...     return 'foo'

>>> print(compute())
computing here
foo
>>> print(compute())
foo

>>> print(compute.pop())
foo

>>> print(compute())
computing here
foo

When caching class methods:

>>> class Foo(object):
...     @CacheDecorator.as_decorator()
...     def foo(self):
...         print('computing here')
...         return 'foo'

>>> f = Foo()
>>> print(f.foo())
computing here
foo
>>> print(f.foo())
foo

>>> print(f.foo.pop())
foo

>>> print(f.foo())
computing here
foo
Parameters:as_property (bool) –

Boolean whether to create a property descriptor when using it on a class method

Warning

This is only meant to be used when the wrapping method does not accept any parameters since there is no way in Python to pass parameters to properties

django_auxilium.utils.functools.cache.cache_method(*args, **kwargs)

Shortcut for cache which automatically indicates that the cached object is a method.

These are equivalent:

class Foo(object):
    @cache(is_method=True)
    def foo(self): pass

class Foo(object):
    @cache_method
    def bar(self): pass
django_auxilium.utils.functools.cache.cache_property(*args, **kwargs)

Shortcut for cache which automatically creates properties when used on class methods.

These are equivalent:

@cache(as_property=True)
def foo(self): pass

@cache_property
def bar(self): pass
django_auxilium.utils.functools.cache.memoize(*args, **kwargs)

Decorator for memoizing functions so that they only execute once and all subsequent calls with same parameters

This is very useful for expensive functions which accept parameters

Examples

When caching standalone functions:

>>> @MemoizeDecorator.as_decorator()
... def compute(x):
...     print('computing for', x)
...     return x + 'foo'

>>> print(compute('bar'))
computing for bar
barfoo
>>> print(compute('awesome'))
computing for awesome
awesomefoo
>>> print(compute('bar'))
barfoo

>>> print(compute.pop('bar'))
barfoo

>>> print(compute('bar'))
computing for bar
barfoo
>>> print(compute('awesome'))
awesomefoo

When caching class methods:

>>> class Foo(object):
...     @MemoizeDecorator.as_decorator()
...     def foo(self, x):
...         print('computing for', x)
...         return x + 'foo'

>>> f = Foo()
>>> print(f.foo('bar'))
computing for bar
barfoo
>>> print(f.foo('awesome'))
computing for awesome
awesomefoo

>>> print(f.foo('bar'))
barfoo
>>> print(f.foo('awesome'))
awesomefoo

>>> print(f.foo.pop('bar'))
barfoo

>>> print(f.foo('bar'))
computing for bar
barfoo
>>> print(f.foo('awesome'))
awesomefoo