decorateme._Utils.gen_str()   A
last analyzed

Complexity

Conditions 4

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 19
rs 9.6
c 0
b 0
f 0
cc 4
nop 7
1
"""
2
Code for decorateme.
3
"""
4
from __future__ import annotations
5
6
import enum
7
import html as _html
8
import logging
9
10
# noinspection PyUnresolvedReferences
11
from abc import abstractmethod
12
from collections.abc import Callable, Collection
13
14
# noinspection PyUnresolvedReferences
15
from functools import total_ordering, wraps
16
from importlib.metadata import PackageNotFoundError
0 ignored issues
show
Bug introduced by
The name metadata does not seem to exist in module importlib.
Loading history...
introduced by
Unable to import 'importlib.metadata'
Loading history...
17
from importlib.metadata import metadata as __load
0 ignored issues
show
Bug introduced by
The name metadata does not seem to exist in module importlib.
Loading history...
introduced by
Unable to import 'importlib.metadata'
Loading history...
18
from pathlib import Path
19
20
# noinspection PyUnresolvedReferences
21
from typing import Literal, TypeVar, final
0 ignored issues
show
Bug introduced by
The name final does not seem to exist in module typing.
Loading history...
Bug introduced by
The name Literal does not seem to exist in module typing.
Loading history...
22
from warnings import warn
23
24
pkg = Path(__file__).absolute().parent.name
25
logger = logging.getLogger(pkg)
26
metadata = None
0 ignored issues
show
Coding Style Naming introduced by
Constant name "metadata" doesn't conform to UPPER_CASE naming style ('([^\\W\\da-z][^\\Wa-z]*|__.*__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
27
try:
28
    metadata = __load(pkg)
29
    __status__ = "Stable"
30
    __copyright__ = "Copyright 2017–2022"
31
    __date__ = "2020-08-24"
32
    __uri__ = metadata["home-page"]
33
    __title__ = metadata["name"]
34
    __summary__ = metadata["summary"]
35
    __license__ = metadata["license"]
36
    __version__ = metadata["version"]
37
    __author__ = metadata["author"]
38
    __maintainer__ = metadata["maintainer"]
39
    __contact__ = metadata["maintainer"]
40
except PackageNotFoundError:  # pragma: no cover
41
    logger.error(f"Could not load package metadata for {pkg}. Is it installed?")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
42
43
44
T = TypeVar("T", bound=type)
0 ignored issues
show
Coding Style Naming introduced by
Class name "T" doesn't conform to PascalCase naming style ('[^\\W\\da-z][^\\W_]+$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
45
46
47
def reserved(cls: T) -> T:
48
    """
49
    Empty but is declared for future use.
50
    """
51
    return cls
52
53
54
class CodeIncompleteError(NotImplementedError):
55
    """The code is not finished."""
56
57
58
class CodeRemovedError(NotImplementedError):
59
    """The code was removed."""
60
61
62
class PreviewWarning(UserWarning):
63
    """The code being called is a preview, unstable. or immature."""
64
65
66
@enum.unique
67
class CodeStatus(enum.Enum):
68
    """
69
    An enum for the quality/maturity of code,
70
    ranging from incomplete to deprecated.
71
    """
72
73
    INCOMPLETE = -2
74
    PREVIEW = -1
75
    STABLE = 0
76
    PENDING_DEPRECATION = 1
77
    DEPRECATED = 2
78
    REMOVED = 3
79
80
    @classmethod
81
    def of(cls, x: int | str | CodeStatus) -> CodeStatus:
0 ignored issues
show
Coding Style Naming introduced by
Method name "of" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Argument name "x" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
82
        if isinstance(x, str):
83
            return cls[x.lower().strip()]
84
        if isinstance(x, CodeStatus):
85
            return x
86
        if isinstance(x, int):
87
            return cls(x)
88
        raise TypeError(f"Invalid type {type(x)} for {x}")
89
90
91
def status(
0 ignored issues
show
Coding Style Naming introduced by
Argument name "vr" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
92
    level: int | str | CodeStatus,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
93
    vr: str | None = "",
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
94
    msg: str | None = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
95
):
96
    """
97
    Annotate code quality. Emits a warning if bad code is called.
98
99
    Args:
100
        level: The quality / maturity
101
        vr: First version the status / warning applies to
102
        msg: Explanation and/or when it will be removed or completed
103
    """
104
105
    level = CodeStatus.of(level)
106
107
    @wraps(status)
108
    def dec(func):
109
        func.__status__ = level
110
        if level is CodeStatus.STABLE:
0 ignored issues
show
unused-code introduced by
Unnecessary "elif" after "return"
Loading history...
111
            return func
112
        elif level is CodeStatus.REMOVED:
113
114
            def my_fn(*_, **__):
115
                raise CodeRemovedError(f"{func.__name__} was removed (as of version: {vr}). {msg}")
116
117
            return wraps(func)(my_fn)
118
119
        elif level is CodeStatus.INCOMPLETE:
120
121
            def my_fn(*_, **__):
122
                raise CodeIncompleteError(
123
                    f"{func.__name__} is incomplete (as of version: {vr}). {msg}"
124
                )
125
126
            return wraps(func)(my_fn)
127
        elif level is CodeStatus.PREVIEW:
128
129
            def my_fn(*args, **kwargs):
130
                warn(
131
                    f"{func.__name__} is a preview or immature (as of version: {vr}). {msg}",
132
                    PreviewWarning,
133
                )
134
                return func(*args, **kwargs)
135
136
            return wraps(func)(my_fn)
137
        elif level is CodeStatus.PENDING_DEPRECATION:
138
139
            def my_fn(*args, **kwargs):
140
                warn(
141
                    f"{func.__name__} is pending deprecation (as of version: {vr}). {msg}",
142
                    PendingDeprecationWarning,
143
                )
144
                return func(*args, **kwargs)
145
146
            return wraps(func)(my_fn)
147
        elif level is CodeStatus.DEPRECATED:
148
149
            def my_fn(*args, **kwargs):
150
                warn(
151
                    f"{func.__name__} is deprecated (as of version: {vr}). {msg}",
152
                    DeprecationWarning,
153
                )
154
                return func(*args, **kwargs)
155
156
            return wraps(func)(my_fn)
157
        raise AssertionError(f"What is {level}?")
158
159
    return dec
160
161
162
def incomplete(
0 ignored issues
show
Coding Style Naming introduced by
Argument name "vr" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
163
    vr: str | None = "",
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
164
    msg: str | None = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
165
):
166
    return status(CodeStatus.INCOMPLETE, vr, msg)
167
168
169
def preview(
0 ignored issues
show
Coding Style Naming introduced by
Argument name "vr" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
170
    vr: str | None = "",
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
171
    msg: str | None = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
172
):
173
    return status(CodeStatus.PREVIEW, vr, msg)
174
175
176
def pending_deprecation(
0 ignored issues
show
Coding Style Naming introduced by
Argument name "vr" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
177
    vr: str | None = "",
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
178
    msg: str | None = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
179
):
180
    return status(CodeStatus.PENDING_DEPRECATION, vr, msg)
181
182
183
def deprecated(
0 ignored issues
show
Coding Style Naming introduced by
Argument name "vr" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
184
    vr: str | None = "",
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
185
    msg: str | None = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
186
):
187
    return status(CodeStatus.DEPRECATED, vr, msg)
188
189
190
def removed(
0 ignored issues
show
Coding Style Naming introduced by
Argument name "vr" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
introduced by
Missing function or method docstring
Loading history...
191
    vr: str | None = "",
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
192
    msg: str | None = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
193
):
194
    return status(CodeStatus.REMOVED, vr, msg)
195
196
197
class _SpecialStr(str):
198
    """
199
    A string that can be displayed with Jupyter with line breaks and tabs.
200
    """
201
202
    def _repr_html_(self):
203
        return str(self.replace("\n", "<br />").replace("\t", "&emsp;&emsp;&emsp;&emsp;"))
204
205
206
class _Utils:
207
    @classmethod
208
    def exclude_fn(cls, *items) -> Callable[str, bool]:
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
209
        fns = [cls._exclude_fn(x) for x in items]
210
211
        def exclude(s: str):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "s" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
212
            return any((fn(s) for fn in fns))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable fn does not seem to be defined.
Loading history...
213
214
        return exclude
215
216
    @classmethod
217
    def _exclude_fn(cls, exclude) -> Callable[str, bool]:
0 ignored issues
show
introduced by
Value 'Callable' is unsubscriptable
Loading history...
218
        if exclude is None or exclude is False:
219
            return lambda s: False
220
        if isinstance(exclude, str):
0 ignored issues
show
unused-code introduced by
Unnecessary "elif" after "return"
Loading history...
221
            return lambda s: s == exclude
222
        elif isinstance(exclude, Collection):
223
            return lambda s: s in exclude
224
        elif callable(exclude):
225
            return exclude
226
        else:
227
            raise TypeError(str(exclude))
228
229
    @classmethod
230
    def gen_str(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
231
        cls,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
232
        obj,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
233
        fields: Collection[str] = None,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
234
        *,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
235
        exclude: Callable[[str], bool] = lambda _: False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
236
        address: bool = False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
237
        angular: bool = False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
238
    ):
239
        _name = obj.__class__.__name__
240
        _fields = ", ".join(
241
            k + "=" + ('"' + v + '"' if isinstance(v, str) else str(v))
242
            for k, v in cls.gen_list(obj, fields, exclude=exclude, address=address)
243
        )
244
        if angular:
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
245
            return f"<{_name} {_fields}>"
246
        else:
247
            return f"{_name}({_fields})"
248
249
    @classmethod
250
    def gen_html(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
251
        cls,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
252
        obj,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
253
        fields: Collection[str] = None,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
254
        *,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
255
        exclude: Callable[[str], bool] = lambda _: False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
256
        address: bool = True,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
257
        angular: bool = True,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
258
    ):
259
        _name = obj.__class__.__name__
260
        _fields = ", ".join(
261
            f"{k}={_html.escape(v)}"
262
            for k, v in cls.gen_list(obj, fields, exclude=exclude, address=address)
263
        )
264
        if angular:
0 ignored issues
show
unused-code introduced by
Unnecessary "else" after "return"
Loading history...
265
            return f"&lt;<strong>{_name}</strong> {_fields}&gt;"
266
        else:
267
            return f"{_name}({_fields})"
268
269
    @classmethod
270
    def gen_list(
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
271
        cls,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
272
        obj,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
273
        fields: Collection[str] = None,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
274
        *,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
275
        exclude: Callable[[str], bool] = lambda _: False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
276
        address: bool = False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
277
    ):
278
        yield from _Utils.var_items(obj, fields, exclude=exclude)
279
        if address:
280
            yield "@", str(hex(id(obj)))
281
282
    @classmethod
283
    def var_items(cls, obj, fields, exclude):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
284
        yield from [
285
            (key, value)
286
            for key, value in vars(obj).items()
287
            if (fields is None) or (key in fields)
288
            if not key.startswith(f"_{obj.__class__.__name__}__")  # imperfect exclude mangled
289
            and not exclude(key)
290
        ]
291
292
293
def add_reprs(
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (16/15).
Loading history...
294
    fields: Collection[str] | None = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
295
    *,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
296
    exclude: Collection[str] | Callable[[str], bool] | None | Literal[False] = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
297
    exclude_from_str: Collection[str] | Callable[[str], bool] | None | Literal[False] = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
298
    exclude_from_repr: Collection[str] | Callable[[str], bool] | None | Literal[False] = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
299
    exclude_html: Collection[str] | Callable[[str], bool] | None | Literal[False] = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
300
    exclude_rich: Collection[str] | Callable[[str], bool] | None | Literal[False] = None,
0 ignored issues
show
Coding Style introduced by
No space allowed around keyword argument assignment
Loading history...
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
introduced by
Value 'Collection' is unsubscriptable
Loading history...
introduced by
Value 'Callable' is unsubscriptable
Loading history...
301
    address: bool = False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
302
    angular: bool = False,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
303
    html: bool = True,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
304
    rich: bool = True,
0 ignored issues
show
Coding Style introduced by
Wrong hanging indentation before block (add 4 spaces).
Loading history...
305
):
306
    """
307
    Auto-adds ``__repr__``, ``__str__``, ``_repr_html``, and ``__rich_repr__``
308
    that use instances' attributes (``vars``).
309
    """
310
    exclude_from_repr = _Utils.exclude_fn(exclude, exclude_from_repr)
311
    exclude_from_str = _Utils.exclude_fn(exclude, exclude_from_str)
312
    exclude_html = _Utils.exclude_fn(exclude, exclude_html)
313
    exclude_rich = _Utils.exclude_fn(exclude, exclude_rich)
314
315
    def __repr(self) -> str:
316
        return _Utils.gen_str(self, fields, exclude=exclude_from_repr, address=address)
317
318
    def __str(self) -> str:
319
        return _Utils.gen_str(self, fields, exclude=exclude_from_str)
320
321
    def __html(self) -> str:
322
        return _Utils.gen_html(self, fields, exclude=exclude_html)
323
324
    if rich:
325
        from rich.repr import RichReprResult
0 ignored issues
show
introduced by
Unable to import 'rich.repr'
Loading history...
introduced by
Import outside toplevel (rich.repr.RichReprResult)
Loading history...
326
327
        def __rich(self) -> RichReprResult:
328
            yield from _Utils.gen_list(self, fields, exclude=exclude_rich)
329
330
    @wraps(add_reprs)
331
    def dec(cls):
332
        if cls.__str__ is object.__str__:
333
            cls.__str__ = __str
334
        if cls.__repr__ is object.__repr__:
335
            cls.__repr__ = __repr
336
        if not hasattr(cls, "_repr_html") and html:
337
            cls._repr_html_ = __html
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like _repr_html_ was declared protected and should not be accessed from this context.

Prefixing a member variable _ is usually regarded as the equivalent of declaring it with protected visibility that exists in other languages. Consequentially, such a member should only be accessed from the same class or a child class:

class MyParent:
    def __init__(self):
        self._x = 1;
        self.y = 2;

class MyChild(MyParent):
    def some_method(self):
        return self._x    # Ok, since accessed from a child class

class AnotherClass:
    def some_method(self, instance_of_my_child):
        return instance_of_my_child._x   # Would be flagged as AnotherClass is not
                                         # a child class of MyParent
Loading history...
338
        if not hasattr(cls, "__rich_repr__") and rich:
339
            cls.__rich_repr__ = __rich
0 ignored issues
show
introduced by
The variable __rich does not seem to be defined in case rich on line 324 is False. Are you sure this can never be the case?
Loading history...
340
            cls.__rich_repr__.angular = angular
341
        return cls
342
343
    return dec
344
345
346
__all__ = [
347
    "abstractmethod",
348
    "total_ordering",
349
    "final",
350
    "CodeStatus",
351
    "status",
352
    "CodeIncompleteError",
353
    "PreviewWarning",
354
    "CodeRemovedError",
355
    "repr_str",
0 ignored issues
show
Bug introduced by
Undefined variable name 'repr_str' in __all__
Loading history...
356
    "deprecated",
357
    "pending_deprecation",
358
    "incomplete",
359
    "preview",
360
    "removed",
361
]
362