Passed
Push — master ( bcf14c...4a1f1b )
by Max
57s
created

structured_data._match.descriptor.property_   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 83
dl 0
loc 107
rs 10
c 0
b 0
f 0
wmc 28

13 Methods

Rating   Name   Duplication   Size   Complexity  
A Property.setter() 0 7 1
A Property.__init__() 0 11 2
A Property.set_when() 0 3 1
A Property.deleter() 0 7 1
A Property.__delattr__() 0 4 3
A Property.__delete__() 0 9 4
A Property.__get__() 0 10 5
A Property.__setattr__() 0 4 3
A Property.__new__() 0 3 1
A Property.get_when() 0 3 1
A Property.delete_when() 0 3 1
A Property.getter() 0 7 1
A Property.__set__() 0 9 4
1
from ... import _doc_wrapper
2
from .. import matchable
3
from . import common
4
5
6
@_doc_wrapper.DocWrapper.wrap_class
7
class Property(common.Descriptor):
8
    """Decorator with value-based dispatch. Acts as a property."""
9
10
    fset = None
11
    fdel = None
12
13
    protected = False
14
15
    def __new__(cls, func=None, fset=None, fdel=None, doc=None, *args, **kwargs):
16
        del fset, fdel, doc
17
        return super().__new__(cls, func, *args, **kwargs)
18
19
    def __init__(self, func=None, fset=None, fdel=None, doc=None, *args, **kwargs):
20
        del func
21
        super().__init__(*args, **kwargs)
22
        self.fset = fset
23
        self.fdel = fdel
24
        if doc is not None:
25
            self.__doc__ = doc
26
        self.get_matchers = []
27
        self.set_matchers = []
28
        self.delete_matchers = []
29
        self.protected = True
30
31
    def __setattr__(self, name, value):
32
        if self.protected and name != "__doc__":
33
            raise AttributeError
34
        super().__setattr__(name, value)
35
36
    def __delattr__(self, name):
37
        if self.protected and name != "__doc__":
38
            raise AttributeError
39
        super().__delattr__(name)
40
41
    def getter(self, getter):
42
        """Return a copy of self with the getter replaced."""
43
        new = Property(getter, self.fset, self.fdel, self.__doc__)
44
        new.get_matchers.extend(self.get_matchers)
45
        new.set_matchers.extend(self.set_matchers)
46
        new.delete_matchers.extend(self.delete_matchers)
47
        return new
48
49
    def setter(self, setter):
50
        """Return a copy of self with the setter replaced."""
51
        new = Property(self.__wrapped__, setter, self.fdel, self.__doc__)
52
        new.get_matchers.extend(self.get_matchers)
53
        new.set_matchers.extend(self.set_matchers)
54
        new.delete_matchers.extend(self.delete_matchers)
55
        return new
56
57
    def deleter(self, deleter):
58
        """Return a copy of self with the deleter replaced."""
59
        new = Property(self.__wrapped__, self.fset, deleter, self.__doc__)
60
        new.get_matchers.extend(self.get_matchers)
61
        new.set_matchers.extend(self.set_matchers)
62
        new.delete_matchers.extend(self.delete_matchers)
63
        return new
64
65
    def __get__(self, instance, owner):
66
        if instance is None:
67
            return self
68
        matchable_ = matchable.Matchable(instance)
69
        for (structure, func) in self.get_matchers:
70
            if matchable_(structure):
71
                return func(**matchable_.matches)
72
        if self.__wrapped__ is None:
73
            raise ValueError(self)
74
        return self.__wrapped__(instance)
75
76
    def __set__(self, instance, value):
77
        matchable_ = matchable.Matchable((instance, value))
78
        for (structure, func) in self.set_matchers:
79
            if matchable_(structure):
80
                func(**matchable_.matches)
81
                return
82
        if self.fset is None:
83
            raise ValueError((instance, value))
84
        self.fset(instance, value)
85
86
    def __delete__(self, instance):
87
        matchable_ = matchable.Matchable(instance)
88
        for (structure, func) in self.delete_matchers:
89
            if matchable_(structure):
90
                func(**matchable_.matches)
91
                return
92
        if self.fdel is None:
93
            raise ValueError(instance)
94
        self.fdel(instance)
95
96
    def get_when(self, instance):
97
        """Add a binding to the getter."""
98
        return common.decorate(self.get_matchers, instance)
99
100
    def set_when(self, instance, value):
101
        """Add a binding to the setter."""
102
        return common.decorate(self.set_matchers, (instance, value))
103
104
    def delete_when(self, instance):
105
        """Add a binding to the deleter."""
106
        return common.decorate(self.delete_matchers, instance)
107