ProxyWrapper.wrap_class()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 1
nop 2
1
"""Wrapper to control documentation visibility."""
2
3
from __future__ import annotations
4
5
import typing
6
7
T = typing.TypeVar("T")
8
9
10
class DocWrapper:
11
    """Custom descriptor that hides class doc on instances."""
12
13
    def __init__(self, doc: typing.Optional[str] = None) -> None:
14
        self.doc = doc
15
16
    @classmethod
17
    def wrap_class(
18
        cls: typing.Type[DocWrapper], klass: typing.Type[T]
19
    ) -> typing.Type[T]:
20
        """Wrap a class's docstring to conceal it from instances."""
21
        klass.__doc__ = cls(klass.__doc__)  # type: ignore
22
        return klass
23
24
    def __get__(
25
        self, instance: typing.Optional[T], owner: typing.Type[T]
26
    ) -> typing.Optional[str]:
27
        if instance is None:
28
            return self.doc
29
        return vars(instance).get("__doc__")
30
31
    def __set__(self, instance: T, value: typing.Optional[str]) -> None:
32
        vars(instance)["__doc__"] = value
33
34
    def __delete__(self, instance: T) -> None:
35
        vars(instance).pop("__doc__", None)
36
37
38
class ProxyWrapper:
39
    """Custom descriptor that forwards instance doc to an attribute."""
40
41
    def __init__(self, name: str, doc: typing.Optional[str]) -> None:
42
        self.name = name
43
        self.doc = doc
44
45
    @classmethod
46
    def wrap_class(cls, name: str) -> typing.Callable[[typing.Type[T]], typing.Type[T]]:
47
        """Wrap a proxy's docstring to forward it for instances."""
48
49
        def decorator(klass: typing.Type[T]) -> typing.Type[T]:
50
            klass.__doc__ = cls(name, klass.__doc__)  # type: ignore
51
            return klass
52
53
        return decorator
54
55
    def __get__(
56
        self, instance: typing.Optional[T], owner: typing.Type[T]
57
    ) -> typing.Optional[str]:
58
        if instance is None:
59
            return self.doc
60
        return getattr(instance, self.name).__doc__
61