Completed
Pull Request — develop (#448)
by
unknown
01:41
created

_memoized_func()   A

Complexity

Conditions 4

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 0
loc 11
rs 9.2
1
# -*- coding: utf-8 -*-
2
from __future__ import absolute_import, division, print_function
3
from collections import Hashable
4
from types import GeneratorType
5
6
from six import wraps
7
8
9
def memoize(func):
10
    """
11
    Decorator to cause a function to cache it's results for each combination of
12
    inputs and return the cached result on subsequent calls.  Does not support
13
    named arguments or arg values that are not hashable.
14
15
    >>> @memoize
16
    ... def foo(x):
17
    ...     print('running function with', x)
18
    ...     return x+3
19
    ...
20
    >>> foo(10)
21
    running function with 10
22
    13
23
    >>> foo(10)
24
    13
25
    >>> foo(11)
26
    running function with 11
27
    14
28
    >>> @memoize
29
    ... def range_tuple(limit):
30
    ...     print('running function')
31
    ...     return tuple(i for i in range(limit))
32
    ...
33
    >>> range_tuple(3)
34
    running function
35
    (0, 1, 2)
36
    >>> range_tuple(3)
37
    (0, 1, 2)
38
    >>> @memoize
39
    ... def range_iter(limit):
40
    ...     print('running function')
41
    ...     return (i for i in range(limit))
42
    ...
43
    >>> range_iter(3)
44
    Traceback (most recent call last):
45
    TypeError: Can't memoize a generator or non-hashable object!
46
    """
47
    func._result_cache = {}  # pylint: disable-msg=W0212
48
49
    @wraps(func)
50
    def _memoized_func(*args, **kwargs):
51
        key = (args, tuple(sorted(kwargs.items())))
52
        if key in func._result_cache:  # pylint: disable-msg=W0212
53
            return func._result_cache[key]  # pylint: disable-msg=W0212
54
        else:
55
            result = func(*args, **kwargs)
56
            if isinstance(result, GeneratorType) or not isinstance(result, Hashable):
57
                raise TypeError("Can't memoize a generator or non-hashable object!")
58
            func._result_cache[key] = result  # pylint: disable-msg=W0212
59
            return result
60
61
    return _memoized_func
62