structured_data._conditional_method   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 27
dl 0
loc 50
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A ConditionalMethod.__set_name__() 0 3 1
A ConditionalMethod.__get__() 0 5 3
A ConditionalMethod.__init__() 0 3 1
A ConditionalMethod.__set__() 0 3 1

2 Functions

Rating   Name   Duplication   Size   Complexity  
A conditional_method() 0 8 1
A _manual_partial() 0 5 1
1
"""Utilities for conditionally proxying method access to another class."""
2
3
import typing
4
5
from . import _attribute_constructor
6
7
_T = typing.TypeVar("_T")
8
9
10
class ConditionalMethod(typing.Generic[_T]):
11
    """Based on the value of the given attribute, forwards to the superclass or the source class."""
12
13
    name: str
14
    __objclass__: typing.Type[_T]
15
16
    def __init__(self, source: type, field_check: str):
17
        self.source = source
18
        self.field_check = field_check
19
20
    def __set_name__(self, owner: typing.Type[_T], name: str) -> None:
21
        self.__objclass__ = owner
22
        self.name = name
23
24
    def __get__(self, instance: _T, owner: typing.Type[_T]) -> typing.Any:
25
        if getattr(owner, self.field_check):
26
            return getattr(self.source, self.name).__get__(instance, owner)
27
        target = owner if instance is None else instance
28
        return getattr(super(self.__objclass__, target), self.name)
29
30
    def __set__(self, instance: _T, value: typing.Any) -> None:
31
        # Don't care about this coverage
32
        raise AttributeError  # pragma: nocover
33
34
35
def _manual_partial(source: type) -> typing.Callable[[str], ConditionalMethod]:
36
    def wrapped(field_check: str) -> ConditionalMethod:
37
        return ConditionalMethod(source, field_check)
38
39
    return wrapped
40
41
42
def conditional_method(
43
    source: type,
44
) -> _attribute_constructor.AttributeConstructor[ConditionalMethod[_T]]:
45
    """Given a source class, return an attribute constructor that makes ConditionalMethods
46
47
    It is not recommended to reuse the return value of this function.
48
    """
49
    return _attribute_constructor.AttributeConstructor(_manual_partial(source))
50