Completed
Push — master ( a73913...a94802 )
by Max
13s queued 11s
created

Descriptor._matchers()   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
import functools
2
import typing
3
4
from ... import _class_placeholder
5
from .. import destructure
6
7
8
def _check_structure(structure):
9
    destructure.names(structure)  # Raise ValueError if there are duplicates
10
11
12
def decorate(matchers, structure):
13
    if not _class_placeholder.is_placeholder(structure):
14
        _check_structure(structure)
15
16
    def decorator(func):
17
        matchers.append((structure, func))
18
        return func
19
20
    return decorator
21
22
23
class Descriptor:
24
    """Base class for decorator classes."""
25
26
    __wrapped__ = None
27
28
    def __new__(cls, func, *args, **kwargs):
29
        new = super().__new__(cls, *args, **kwargs)
30
        new.__doc__ = None
31
        if func is None:
32
            return new
33
        return functools.wraps(func)(new)
34
35
    def _matchers(self) -> typing.Iterator[typing.List[typing.Tuple[typing.Any, typing.Callable]]]:
36
        raise NotImplementedError
37
38
    def for_class(self, cls: type) -> None:
39
        for matchers in self._matchers():
40
            for index, (structure_, func) in enumerate(matchers[:]):
41
                if _class_placeholder.is_placeholder(structure_):
42
                    structure = structure_(cls)
43
                    matchers[index] = (structure, func)
44
45
46
def for_class(cls: type) -> None:
47
    for attr in vars(cls).values():
48
        if isinstance(attr, Descriptor):
49
            attr.for_class(cls)
50