Passed
Push — master ( b636f8...bb23a2 )
by Max
56s
created

Pattern.__new__()   A

Complexity

Conditions 4

Size

Total Lines 8
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
import keyword
2
3
from .compound_match import CompoundMatch
4
5
DISCARD = object()
6
7
8
class Pattern(tuple):
9
    """A matcher that binds a value to a name."""
10
11
    __slots__ = ()
12
13
    def __new__(cls, name: str):
14
        if name == "_":
15
            return DISCARD
16
        if not name.isidentifier():
17
            raise ValueError
18
        if keyword.iskeyword(name):
19
            raise ValueError
20
        return super().__new__(cls, (name,))
21
22
    @property
23
    def name(self):
24
        """Return the name of the matcher."""
25
        return tuple.__getitem__(self, 0)
26
27
    def __getitem__(self, other):
28
        return AsPattern(self, other)
29
30
31
class AsPattern(CompoundMatch, tuple):
32
    """A matcher that contains further bindings."""
33
34
    __slots__ = ()
35
36
    def __new__(cls, matcher: Pattern, match):
37
        if match is DISCARD:
38
            return matcher
39
        return super().__new__(cls, (matcher, match))
40
41
    @property
42
    def matcher(self):
43
        """Return the left-hand-side of the as-match."""
44
        return self[0]
45
46
    @property
47
    def match(self):
48
        """Return the right-hand-side of the as-match."""
49
        return self[1]
50
51
    def destructure(self, value):
52
        if isinstance(value, AsPattern):
53
            if value is self:
54
                return (self.match, self.matcher)
55
            return (value.match, value)
56
        return (value, value)
57