Passed
Push — dev ( 1b3874...6a1e3c )
by Konstantinos
03:33
created

PhiFunctionRegistry.__new__()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nop 3
1
from abc import abstractmethod, ABC
2
from functools import wraps
3
import inspect
4
from green_magic.utils import Singleton, Transformer, ObjectRegistry
5
6
7
class PhiFunctionRegistry(Singleton, ObjectRegistry):
8
    def __new__(cls, *args, **kwargs):
9
        x = Singleton.__new__(cls, *args, **kwargs)
10
        x = ObjectRegistry(getattr(x, 'objects', {}))
11
        return x
12
13
    @staticmethod
14
    def get_instance():
15
        return PhiFunctionRegistry()
16
17
    @staticmethod
18
    def get_name(a_callable):
19
        if hasattr(a_callable, 'name'):
20
            return a_callable.name
21
        if hasattr(a_callable, '__code__') and hasattr(a_callable.__code__, 'co_name'):
22
            return a_callable.__code__.co_name
23
        if hasattr(type(a_callable), 'name'):
24
            return type(a_callable).name
25
        if hasattr(type(a_callable), '__name__'):
26
            return type(a_callable).__name__
27
        return ''
28
29
30
phi_registry = PhiFunctionRegistry()
31
32
33
class PhiFunctionInterface(ABC):
34
    """Each datapoint"""
35
    @abstractmethod
36
    def __call__(self, data, **kwargs):
37
        raise NotImplementedError
38
39
40
class PhiFunction(PhiFunctionInterface, Transformer):
41
42
    def __call__(self, data, **kwargs):
43
        return self.transform(data, **kwargs)
44
45
    @classmethod
46
    def register(cls, phi_name=''):
47
        def wrapper(a_callable):
48
            if hasattr(a_callable, '__code__'):  # it a function (def func_name ..)
49
                print(f"Registering input function {a_callable.__code__.co_name}")
50
                cls._register(a_callable, key_name=phi_name)
51
            else:
52
                if not hasattr(a_callable, '__call__'):
53
                    raise RuntimeError(f"Expected an class definition with a '__call__' instance method defined 1. Got {type(a_callable)}")
54
                members = inspect.getmembers(a_callable)
55
                if not ('__call__', a_callable.__call__) in members:
56
                    raise RuntimeError(f"Expected an class definition with a '__call__' instance method defined 2. Got {type(a_callable)}")
57
                print(f"Registering a class {type(a_callable).__name__}")
58
                instance = a_callable()
59
                cls._register(instance, key_name=phi_name)
60
            return a_callable
61
        return wrapper
62
63
    @classmethod
64
    def _register(cls, a_callable, key_name=None):
65
        key = key_name if key_name else PhiFunctionRegistry.get_name(a_callable)
66
        print(f"Registering object {a_callable} at key {key}.")
67
        phi_registry.add(key, a_callable)
68
69
    @classmethod
70
    def my_decorator(cls, f):
71
        print(f"Running 'my_decorator' with input type {type(f)}")
72
        @wraps(f)
73
        def wrapper(*args, **kwds):
74
            if hasattr(f, '__code__'):  # it a function (def func_name ..)
75
                print(f"Registering input function {a_callable.__code__.co_name}")
76
                cls._register(f)
77
            else:
78
                if not hasattr(f, '__call__'):
79
                    raise RuntimeError(f"Expected an class definition with a '__call__' instance method defined 1. Got {type(f)}")
80
                members = inspect.getmembers(f)
81
                if not ('__call__', f.__call__) in members:
82
                    raise RuntimeError(f"Expected an class definition with a '__call__' instance method defined 2. Got {type(f)}")
83
                print(f"Registering a class {type(a_callable).name}")
84
                instance = f()
85
                cls._register(instance)
86
            return f(*args, **kwds)
87
        return wrapper
88
89
90
if __name__ == '__main__':
91
    reg1 = PhiFunctionRegistry()
92
    reg2 = PhiFunctionRegistry()
93
    reg3 = PhiFunctionRegistry.get_instance()
94
95
    assert id(reg1) == id(reg2) == id(reg3)
96
97
    @PhiFunction.my_decorator
98
    def example():
99
        """Inherited Docstring"""
100
        print('Called example function')
101
102
103
    example()
104
105
    print(example.__name__)
106
    print('--')
107
    print(example.__doc__)
108