Passed
Pull Request — dev (#30)
by Konstantinos
03:15 queued 01:38
created

so_magic.utils.memoize.ObjectsPool.get_object()   A

Complexity

Conditions 2

Size

Total Lines 15
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nop 3
dl 0
loc 15
rs 10
c 0
b 0
f 0
1
"""Implementation of the object pool"""
2
import types
3
import attr
4
5
__all__ = ['ObjectsPool']
6
7
8
def build_hash(*args, **kwargs):
9
    r"""Construct a unique string out of the input \*args and \*\*kwargs."""
10
    return hash('-'.join([str(_) for _ in args] + ['{key}={value}'.format(key=k, value=str(v)) for k, v in kwargs]))
11
12
13
def _convert_to_method(function):
14
    def _function(_self, *args, **kwargs):
15
        return function(*args, **kwargs)
16
    return _function
17
18
19
@attr.s
20
class ObjectsPool:
21
    """Class of objects that are able to return a reference to an object upon request.
22
23
    Whenever an object is requested, it is checked whether it exists in the pool.
24
    Then if it exists, a reference is returned, otherwise a new object is
25
    constructed (given the provided callable) and its reference is returned.
26
27
    Arguments:
28
        constructor (callable): able to construct the object given arguments
29
        objects (dict): the data structure representing the object pool
30
    """
31
    constructor = attr.ib(init=True)
32
    _objects = attr.ib(init=True, default={})
33
    _build_hash = attr.ib(default=attr.Factory(lambda self: types.MethodType(_convert_to_method(build_hash), self),
34
                                               takes_self=True))
35
36
    def get_object(self, *args, **kwargs):
37
        r"""Request an object from the pool.
38
39
        Get or create an object given the input parameters. Existence in the pool is done using the
40
        python-build-in hash function. The input \*args and \*\*kwargs serve as
41
        input in the hash function to create unique keys with which to "query" the object pool.
42
43
        Returns:
44
            object: the reference to the object that corresponds to the input
45
            arguments, regardless of whether it was found in the pool or not
46
        """
47
        key = self._build_hash(*args, **kwargs)
48
        if key not in self._objects:
49
            self._objects[key] = self.constructor(*args, **kwargs)
50
        return self._objects[key]
51