structured_data.match   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 52
dl 0
loc 98
rs 10
c 0
b 0
f 0

2 Functions

Rating   Name   Duplication   Size   Complexity  
A decorate_in_order() 0 9 2
A function() 0 3 4
1
"""Utilities for destructuring values using matchables and match targets.
2
3
Given a value to destructure, called ``value``:
4
5
- Construct a matchable: ``matchable = Matchable(value)``
6
- The matchable is initially falsy, but it will become truthy if it is passed a
7
  **match target** that matches ``value``:
8
  ``assert matchable(some_pattern_that_matches)`` (Matchable returns itself
9
  from the call, so you can put the calls in an if-elif block, and only make a
10
  given call at most once.)
11
- When the matchable is truthy, it can be indexed to access bindings created by
12
  the target.
13
"""
14
15
from __future__ import annotations
16
17
import typing
18
19
from . import _attribute_constructor
20
from ._class_placeholder import Placeholder
21
from ._match.descriptor import common
22
from ._match.descriptor import function as function_
23
from ._match.descriptor import property_
24
from ._match.destructure import names
25
from ._match.match_dict import MatchDict
26
from ._match.matchable import Matchable
27
from ._match.patterns.basic_patterns import Pattern
28
from ._match.patterns.bind import Bind
29
from ._match.patterns.mapping_match import AttrPattern
30
from ._match.patterns.mapping_match import DictPattern
31
32
# In lower-case for aesthetics.
33
pat = _attribute_constructor.AttributeConstructor(  # pylint: disable=invalid-name
34
    Pattern
35
)
36
37
38
@typing.overload
39
def function(func: typing.Callable) -> function_.Function:
40
    """Normal functions and methods go to Functions"""
41
42
43
@typing.overload
44
def function(func: staticmethod) -> function_.StaticMethod:
45
    """Static methods go to StaticMethods"""
46
47
48
@typing.overload
49
def function(func: classmethod) -> function_.ClassMethod:
50
    """Class methods go to ClassMethods."""
51
52
53
@typing.overload
54
def function(func: property) -> property_.Property:
55
    """And properties go to Properties."""
56
57
58
def function(func: typing.Any) -> common.Descriptor:
59
    """Convert a function to dispatch by value.
60
61
    The original function is not called when the dispatch function is invoked.
62
    """
63
    if isinstance(func, staticmethod):
64
        return function_.StaticMethod(func.__func__)
65
    if isinstance(func, classmethod):
66
        return function_.ClassMethod(func.__func__)
67
    if isinstance(func, property):
68
        return property_.Property(func.fget, func.fset, func.fdel, func.__doc__)
69
    return function_.Function(func)
70
71
72
Deco = typing.Callable[[typing.Callable], typing.Callable]
73
74
75
def decorate_in_order(*args: Deco) -> Deco:
76
    """Apply decorators in the order they're passed to the function."""
77
78
    def decorator(func: typing.Callable) -> typing.Callable:
79
        for arg in args:
80
            func = arg(func)
81
        return func
82
83
    return decorator
84
85
86
__all__ = [
87
    "AttrPattern",
88
    "Bind",
89
    "DictPattern",
90
    "MatchDict",
91
    "Matchable",
92
    "Pattern",
93
    "Placeholder",
94
    "decorate_in_order",
95
    "function",
96
    "names",
97
    "pat",
98
]
99