Passed
Push — mpeta ( ff9ea9...522f25 )
by Konstantinos
01:42
created

SelectVariablesCommandFactory.construct()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
from abc import ABC
2
import attr
3
from typing import Callable
4
from so_magic.utils import Command, Subject
5
from .command_factory_interface import CommandFactoryInterface, CommandFactoryType
6
7
8
class DataManagerCommandFactoryBuilder(metaclass=CommandFactoryType):
9
    """[summary]
10
11
    Args:
12
        metaclass ([type], optional): [description]. Defaults to CommandFactoryType.
13
14
    Returns:
15
        [type]: [description]
16
    """
17
   
18
    @classmethod
19
    def create_factory(cls, name, callback):
20
        @DataManagerCommandFactoryBuilder.register_as_subclass(name)
21
        class DataManagerRuntimeCommandFactory(CommandFactoryInterface):
22
            def construct(self, *args, **kwargs) -> Command:
23
                receiver = args[0]
24
                def command(*runtime_args):
25
                    callback(receiver, *runtime_args)
26
                return Command(command, '__call__', *args[1:])
27
28
29
@attr.s
30
class DataManagerCommandFactory(Subject):
31
    """[summary]
32
33
    Args:
34
        Subject ([type]): [description]
35
36
    Returns:
37
        [type]: [description]
38
    """
39
    _data_manager = attr.ib(init=True)
40
    command_factory = attr.ib(init=True, default=DataManagerCommandFactoryBuilder)
41
42
    def __call__(self, command_type, *args, **kwargs):
43
        self._state, self.name = self.command_factory.create(command_type).construct(self._data_manager, *args, **kwargs), command_type
44
        self.notify()
45
        return self._state
46
47
    def build_command_prototype(self):
48
        def wrapper(a_callable: Callable) -> Callable:
49
            """Build and register a new Command given a callable object that holds the important business logic.
50
51
            Args:
52
                a_callable (Callable): the Command's important underlying business logic
53
            """
54
            if hasattr(a_callable, '__code__'):  # a_callable object has been defined with the def python keyword
55
                decorated_function_name = a_callable.__code__.co_name
56
                self.command_factory.create_factory(decorated_function_name, a_callable)
57
                self(decorated_function_name)
58
            else:
59
                raise RuntimeError(f"Expected a function to be decorated; got {type(a_callable)}")
60
            return a_callable
61
        return wrapper
62