|
1
|
|
|
import inspect |
|
2
|
|
|
import types |
|
3
|
|
|
import attr |
|
4
|
|
|
|
|
5
|
|
|
from so_magic.data.backend.engine_specs import EngineTabularRetriever, EngineTabularIterator, EngineTabularMutator |
|
6
|
|
|
from .client_code import PDTabularRetrieverDelegate, PDTabularIteratorDelegate, PDTabularMutatorDelegate |
|
7
|
|
|
|
|
8
|
|
|
|
|
9
|
|
|
__all__ = ['PDTabularRetriever', 'PDTabularIterator', 'PDTabularMutator'] |
|
10
|
|
|
|
|
11
|
|
|
|
|
12
|
|
|
# INFRASTRUCTURE |
|
13
|
|
|
|
|
14
|
|
|
def with_self(function): |
|
15
|
|
|
def _function(_self, *args, **kwargs): |
|
16
|
|
|
return function(*args, **kwargs) |
|
17
|
|
|
return _function |
|
18
|
|
|
|
|
19
|
|
|
|
|
20
|
|
|
class Delegate: |
|
21
|
|
|
def __init__(self, tabular_operator): |
|
22
|
|
|
for _member_name, member in inspect.getmembers( |
|
23
|
|
|
tabular_operator, predicate=lambda x: any([inspect.ismethod(x), inspect.isfunction(x)])): |
|
24
|
|
|
if isinstance(member, types.FunctionType): # if no decorator is used |
|
25
|
|
|
setattr(self, member.__name__, types.MethodType(member, self)) |
|
26
|
|
|
if isinstance(member, types.MethodType): # if @classmethod is used |
|
27
|
|
|
setattr(self, member.__name__, types.MethodType(with_self(member), self)) |
|
28
|
|
|
|
|
29
|
|
|
|
|
30
|
|
|
tabular_operators = { |
|
31
|
|
|
'retriever': { |
|
32
|
|
|
'implementations': { |
|
33
|
|
|
'pd': PDTabularRetrieverDelegate, |
|
34
|
|
|
}, |
|
35
|
|
|
'class_registry': EngineTabularRetriever, |
|
36
|
|
|
}, |
|
37
|
|
|
'iterator': { |
|
38
|
|
|
'implementations': { |
|
39
|
|
|
'pd': PDTabularIteratorDelegate, |
|
40
|
|
|
}, |
|
41
|
|
|
'class_registry': EngineTabularIterator, |
|
42
|
|
|
}, |
|
43
|
|
|
'mutator': { |
|
44
|
|
|
'implementations': { |
|
45
|
|
|
'pd': PDTabularMutatorDelegate, |
|
46
|
|
|
}, |
|
47
|
|
|
'class_registry': EngineTabularMutator, |
|
48
|
|
|
} |
|
49
|
|
|
} |
|
50
|
|
|
|
|
51
|
|
|
|
|
52
|
|
|
def get_operator(backend_id: str, operator_type: str): |
|
53
|
|
|
class_registry = tabular_operators[operator_type]['class_registry'] |
|
54
|
|
|
|
|
55
|
|
|
@attr.s |
|
56
|
|
|
@class_registry.register_as_subclass(backend_id) |
|
57
|
|
|
class OperatorClass(class_registry): |
|
58
|
|
|
_delegate = attr.ib( |
|
59
|
|
|
default=attr.Factory(lambda: Delegate(tabular_operators[operator_type]['implementations'][backend_id]))) |
|
60
|
|
|
|
|
61
|
|
|
def __getattr__(self, name: str): |
|
62
|
|
|
return getattr(self._delegate, name) |
|
63
|
|
|
|
|
64
|
|
|
return OperatorClass |
|
65
|
|
|
|
|
66
|
|
|
|
|
67
|
|
|
# CONCRETE IMPLEMENTATIONS |
|
68
|
|
|
|
|
69
|
|
|
PDTabularRetriever = get_operator('pd', 'retriever') |
|
70
|
|
|
PDTabularIterator = get_operator('pd', 'iterator') |
|
71
|
|
|
PDTabularMutator = get_operator('pd', 'mutator') |
|
72
|
|
|
|