lagom.experimental.integrations.click   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 100
Duplicated Lines 0 %

Test Coverage

Coverage 91.43%

Importance

Changes 0
Metric Value
wmc 7
eloc 40
dl 0
loc 100
ccs 32
cts 35
cp 0.9143
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A ClickIntegration.__init__() 0 8 1
A ClickIO.echo() 0 3 1
A ClickIO.__getattr__() 0 4 1
A ClickIntegration.command() 0 20 1
A ClickIntegration.__getattr__() 0 5 1
A ClickIntegration.argument() 0 9 1
A ClickIntegration.option() 0 9 1
1
"""
2
Integration layer for Click https://click.palletsprojects.com/
3
"""
4
5 1
from typing import Optional, List, Type, Callable
6
7 1
from click import utils, decorators
8 1
from click.core import BaseCommand
9
10 1
from lagom.interfaces import ExtendableContainer, WriteableContainer
11
12
13 1
class DecoratedCommand(BaseCommand):
14
    """
15
    Virtual class which is returned by the lagom wrapped click command
16
    decorator
17
    """
18
19 1
    plain_function: Callable
20
21
22 1
class ClickIO:
23
    """
24
    Provides an injectable hint for click IO if needed.
25
    """
26
27 1
    @staticmethod
28 1
    def echo(message=None, file=None, nl=True, err=False, color=None):
29 1
        utils.echo(message, file, nl, err, color)
30
31 1
    def __getattr__(self, item):
32
        import click
33
34
        return getattr(click, item)
35
36
37 1
class ClickIntegration:
38
    """
39
    Integration between a container and click. The ClickIntegration
40
    instance provides all the same decorators and functions as click.
41
    """
42
43 1
    _container: WriteableContainer
44
45 1
    def __init__(
46
        self,
47
        container: ExtendableContainer,
48
        execution_singletons: Optional[List[Type]] = None,
49
    ):
50 1
        self._container = container.clone()
51 1
        self._container[ClickIO] = ClickIO()
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable ClickIO does not seem to be defined.
Loading history...
52 1
        self._execution_singletons = execution_singletons or []
53
54 1
    def command(
55
        self, name=None, cls=None, **attrs
56
    ) -> Callable[[Callable], DecoratedCommand]:
57
        """
58
        Proxies click.command but binds the function to lagom
59
        so that any arguments with lagom.injectable as a default will
60
        be injected by the container
61
        :param name:
62
        :param cls:
63
        :param attrs:
64
        :return:
65
        """
66
67 1
        def _decorator(f):
68 1
            bound_f = self._container.partial(f, shared=self._execution_singletons)
69 1
            command = decorators.command(name, cls, **attrs)(bound_f)
70 1
            setattr(command, "plain_function", bound_f)
71 1
            return command
72
73 1
        return _decorator
74
75 1
    @staticmethod
76 1
    def option(*param_decls, **attrs):
77
        """
78
        Proxies click.option
79
        :param param_decls:
80
        :param attrs:
81
        :return:
82
        """
83
        return decorators.option(*param_decls, **attrs)
84
85 1
    @staticmethod
86 1
    def argument(*param_decls, **attrs):
87
        """
88
        Proxies click.argument
89
        :param param_decls:
90
        :param attrs:
91
        :return:
92
        """
93 1
        return decorators.argument(*param_decls, **attrs)
94
95 1
    def __getattr__(self, item):
96
        # Any method not explicitly code just gets passed to click
97 1
        import click
98
99
        return getattr(click, item)
100