| Total Complexity | 10 |
| Total Lines | 48 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
| 1 | import keyword |
||
| 2 | |||
| 3 | DISCARD = object() |
||
| 4 | |||
| 5 | |||
| 6 | class Pattern(tuple): |
||
| 7 | """A matcher that binds a value to a name.""" |
||
| 8 | |||
| 9 | __slots__ = () |
||
| 10 | |||
| 11 | def __new__(cls, name: str): |
||
| 12 | if name == '_': |
||
| 13 | return DISCARD |
||
| 14 | if not name.isidentifier(): |
||
| 15 | raise ValueError |
||
| 16 | if keyword.iskeyword(name): |
||
| 17 | raise ValueError |
||
| 18 | return super().__new__(cls, (name,)) |
||
| 19 | |||
| 20 | @property |
||
| 21 | def name(self): |
||
| 22 | """Return the name of the matcher.""" |
||
| 23 | return self[0] |
||
| 24 | |||
| 25 | def __matmul__(self, other): |
||
| 26 | return AsPattern(self, other) |
||
| 27 | |||
| 28 | |||
| 29 | class AsPattern(tuple): |
||
| 30 | """A matcher that contains further bindings.""" |
||
| 31 | |||
| 32 | __slots__ = () |
||
| 33 | |||
| 34 | def __new__(cls, matcher: Pattern, match): |
||
| 35 | if match is DISCARD: |
||
| 36 | return matcher |
||
| 37 | return super().__new__(cls, (matcher, match)) |
||
| 38 | |||
| 39 | @property |
||
| 40 | def matcher(self): |
||
| 41 | """Return the left-hand-side of the as-match.""" |
||
| 42 | return self[0] |
||
| 43 | |||
| 44 | @property |
||
| 45 | def match(self): |
||
| 46 | """Return the right-hand-side of the as-match.""" |
||
| 47 | return self[1] |
||
| 48 |