docsig 0.48.0__tar.gz → 0.49.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {docsig-0.48.0 → docsig-0.49.1}/PKG-INFO +7 -16
- {docsig-0.48.0 → docsig-0.49.1}/README.rst +5 -14
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_config.py +2 -2
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_core.py +4 -4
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_display.py +35 -61
- docsig-0.49.1/docsig/_hooks.py +22 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_main.py +1 -1
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_stub.py +4 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_utils.py +3 -1
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_version.py +1 -1
- {docsig-0.48.0 → docsig-0.49.1}/pyproject.toml +3 -2
- docsig-0.48.0/docsig/_hooks.py +0 -17
- {docsig-0.48.0 → docsig-0.49.1}/LICENSE +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/__init__.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/__main__.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_decorators.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_directives.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_message.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_module.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/_report.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/messages.py +0 -0
- {docsig-0.48.0 → docsig-0.49.1}/docsig/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: docsig
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.49.1
|
|
4
4
|
Summary: Check signature params for proper documentation
|
|
5
5
|
Home-page: https://pypi.org/project/docsig/
|
|
6
6
|
License: MIT
|
|
@@ -21,7 +21,7 @@ Requires-Dist: Pygments (>=2.13.0,<3.0.0)
|
|
|
21
21
|
Requires-Dist: Sphinx (>=7.0.0,<8.0.0)
|
|
22
22
|
Requires-Dist: arcon (>=0.4.0)
|
|
23
23
|
Requires-Dist: astroid (>=3.0.1,<4.0.0)
|
|
24
|
-
Requires-Dist:
|
|
24
|
+
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
25
25
|
Project-URL: Documentation, https://docsig.readthedocs.io/en/latest
|
|
26
26
|
Project-URL: Repository, https://github.com/jshwi/docsig
|
|
27
27
|
Description-Content-Type: text/x-rst
|
|
@@ -181,7 +181,7 @@ API
|
|
|
181
181
|
... :param param3: About param3.
|
|
182
182
|
... '''
|
|
183
183
|
... """
|
|
184
|
-
>>> docsig(string=string, no_ansi=True)
|
|
184
|
+
>>> docsig(string=string, summary=True, no_ansi=True)
|
|
185
185
|
0
|
|
186
186
|
|
|
187
187
|
.. code-block:: python
|
|
@@ -195,18 +195,9 @@ API
|
|
|
195
195
|
... :param param3: About param3.
|
|
196
196
|
... '''
|
|
197
197
|
... """
|
|
198
|
-
>>> docsig(string=string, no_ansi=True)
|
|
199
|
-
2
|
|
200
|
-
|
|
201
|
-
def function(✓param1, ✓param2, ✖None) -> ✓None:
|
|
202
|
-
"""
|
|
203
|
-
:param param1: ✓
|
|
204
|
-
:param param2: ✓
|
|
205
|
-
:param param3: ✖
|
|
206
|
-
"""
|
|
207
|
-
<BLANKLINE>
|
|
208
|
-
E102: includes parameters that do not exist (params-do-not-exist)
|
|
209
|
-
<BLANKLINE>
|
|
198
|
+
>>> docsig(string=string, summary=True, no_ansi=True)
|
|
199
|
+
2 in function
|
|
200
|
+
E102: includes parameters that do not exist (params-do-not-exist)
|
|
210
201
|
1
|
|
211
202
|
|
|
212
203
|
A full list of checks can be found `here <https://docsig.readthedocs.io/en/latest/docsig.html#docsig-messages>`__
|
|
@@ -232,7 +223,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
232
223
|
|
|
233
224
|
repos:
|
|
234
225
|
- repo: https://github.com/jshwi/docsig
|
|
235
|
-
rev: v0.
|
|
226
|
+
rev: v0.49.1
|
|
236
227
|
hooks:
|
|
237
228
|
- id: docsig
|
|
238
229
|
args:
|
|
@@ -153,7 +153,7 @@ API
|
|
|
153
153
|
... :param param3: About param3.
|
|
154
154
|
... '''
|
|
155
155
|
... """
|
|
156
|
-
>>> docsig(string=string, no_ansi=True)
|
|
156
|
+
>>> docsig(string=string, summary=True, no_ansi=True)
|
|
157
157
|
0
|
|
158
158
|
|
|
159
159
|
.. code-block:: python
|
|
@@ -167,18 +167,9 @@ API
|
|
|
167
167
|
... :param param3: About param3.
|
|
168
168
|
... '''
|
|
169
169
|
... """
|
|
170
|
-
>>> docsig(string=string, no_ansi=True)
|
|
171
|
-
2
|
|
172
|
-
|
|
173
|
-
def function(✓param1, ✓param2, ✖None) -> ✓None:
|
|
174
|
-
"""
|
|
175
|
-
:param param1: ✓
|
|
176
|
-
:param param2: ✓
|
|
177
|
-
:param param3: ✖
|
|
178
|
-
"""
|
|
179
|
-
<BLANKLINE>
|
|
180
|
-
E102: includes parameters that do not exist (params-do-not-exist)
|
|
181
|
-
<BLANKLINE>
|
|
170
|
+
>>> docsig(string=string, summary=True, no_ansi=True)
|
|
171
|
+
2 in function
|
|
172
|
+
E102: includes parameters that do not exist (params-do-not-exist)
|
|
182
173
|
1
|
|
183
174
|
|
|
184
175
|
A full list of checks can be found `here <https://docsig.readthedocs.io/en/latest/docsig.html#docsig-messages>`__
|
|
@@ -204,7 +195,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
204
195
|
|
|
205
196
|
repos:
|
|
206
197
|
- repo: https://github.com/jshwi/docsig
|
|
207
|
-
rev: v0.
|
|
198
|
+
rev: v0.49.1
|
|
208
199
|
hooks:
|
|
209
200
|
- id: docsig
|
|
210
201
|
args:
|
|
@@ -6,9 +6,9 @@ docsig._config
|
|
|
6
6
|
from argparse import HelpFormatter as _HelpFormatter
|
|
7
7
|
from pathlib import Path as _Path
|
|
8
8
|
|
|
9
|
+
import click as _click
|
|
9
10
|
from arcon import ArgumentParser as _ArgumentParser
|
|
10
11
|
|
|
11
|
-
from ._display import color as _color
|
|
12
12
|
from ._version import __version__
|
|
13
13
|
|
|
14
14
|
|
|
@@ -18,7 +18,7 @@ class Parser(_ArgumentParser):
|
|
|
18
18
|
def __init__(self) -> None:
|
|
19
19
|
super().__init__(
|
|
20
20
|
version=__version__,
|
|
21
|
-
prog=
|
|
21
|
+
prog=_click.style(__package__, fg="cyan"),
|
|
22
22
|
formatter_class=lambda prog: _HelpFormatter(
|
|
23
23
|
prog, max_help_position=45
|
|
24
24
|
),
|
|
@@ -7,6 +7,8 @@ from __future__ import annotations as _
|
|
|
7
7
|
|
|
8
8
|
from pathlib import Path as _Path
|
|
9
9
|
|
|
10
|
+
import click as _click
|
|
11
|
+
|
|
10
12
|
from . import _decorators
|
|
11
13
|
from ._display import Display as _Display
|
|
12
14
|
from ._display import Failure as _Failure
|
|
@@ -42,7 +44,7 @@ _DEFAULT_EXCLUDES = """\
|
|
|
42
44
|
|
|
43
45
|
def _print_checks() -> None:
|
|
44
46
|
for msg in _E.values():
|
|
45
|
-
|
|
47
|
+
_click.echo(msg.fstring(_TEMPLATE))
|
|
46
48
|
|
|
47
49
|
|
|
48
50
|
def _run_check( # pylint: disable=too-many-arguments
|
|
@@ -77,9 +79,7 @@ def _run_check( # pylint: disable=too-many-arguments
|
|
|
77
79
|
child, targets, child.disabled, check_property_returns
|
|
78
80
|
)
|
|
79
81
|
if report:
|
|
80
|
-
failures.append(
|
|
81
|
-
_Failure(child, _FuncStr(child, no_ansi), report)
|
|
82
|
-
)
|
|
82
|
+
failures.append(_Failure(child, _FuncStr(child), report))
|
|
83
83
|
|
|
84
84
|
if check_nested:
|
|
85
85
|
for func in child:
|
|
@@ -5,10 +5,11 @@ docsig._display
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations as _
|
|
7
7
|
|
|
8
|
+
import sys as _sys
|
|
8
9
|
import typing as _t
|
|
9
10
|
from collections import UserString as _UserString
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
import click as _click
|
|
12
13
|
from pygments import highlight as _highlight
|
|
13
14
|
from pygments.formatters.terminal256 import (
|
|
14
15
|
Terminal256Formatter as _Terminal256Formatter,
|
|
@@ -23,39 +24,18 @@ from ._stub import ARG as _ARG
|
|
|
23
24
|
from ._stub import KEY as _KEY
|
|
24
25
|
from ._stub import Param as _Param
|
|
25
26
|
|
|
26
|
-
color = _Color()
|
|
27
|
-
|
|
28
|
-
color.populate_colors()
|
|
29
|
-
|
|
30
27
|
TAB = " "
|
|
31
28
|
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
self._no_ansi = no_ansi
|
|
36
|
-
|
|
37
|
-
def color(self, obj: _t.Any, color_obj: _Color) -> str:
|
|
38
|
-
"""Get string with selected color.
|
|
39
|
-
|
|
40
|
-
:param obj: Any object, represented as ``__str__``.
|
|
41
|
-
:param color_obj: Instantiated ``Color`` object.
|
|
42
|
-
:return: Colored string or string as was supplied.
|
|
43
|
-
"""
|
|
44
|
-
return str(obj) if self._no_ansi else color_obj.get(obj)
|
|
45
|
-
|
|
46
|
-
def syntax(self, obj: _t.Any) -> str:
|
|
47
|
-
"""Get code representation with syntax highlighting.
|
|
30
|
+
def syntax(obj: _t.Any) -> str:
|
|
31
|
+
"""Get code representation with syntax highlighting.
|
|
48
32
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
else _highlight(
|
|
56
|
-
obj, _PythonLexer(), _Terminal256Formatter(style="monokai")
|
|
57
|
-
).strip()
|
|
58
|
-
)
|
|
33
|
+
:param obj: Any object, represented as ``__str__``.
|
|
34
|
+
:return: Colored string or string as was supplied.
|
|
35
|
+
"""
|
|
36
|
+
return _highlight(
|
|
37
|
+
obj, _PythonLexer(), _Terminal256Formatter(style="monokai")
|
|
38
|
+
).strip()
|
|
59
39
|
|
|
60
40
|
|
|
61
41
|
class FuncStr(_UserString):
|
|
@@ -63,16 +43,14 @@ class FuncStr(_UserString):
|
|
|
63
43
|
|
|
64
44
|
:param func: Represents a function with signature and docstring
|
|
65
45
|
parameters.
|
|
66
|
-
:param no_ansi: Disable ANSI output.
|
|
67
46
|
"""
|
|
68
47
|
|
|
69
48
|
CHECK = "\u2713"
|
|
70
49
|
CROSS = "\u2716"
|
|
71
50
|
TRIPLE_QUOTES = '"""'
|
|
72
51
|
|
|
73
|
-
def __init__(self, func: _Function
|
|
52
|
+
def __init__(self, func: _Function) -> None:
|
|
74
53
|
super().__init__(func.name)
|
|
75
|
-
self._ansi = _ANSI(no_ansi)
|
|
76
54
|
self._parent_name = func.parent.name
|
|
77
55
|
self._isinit = func.isinit
|
|
78
56
|
self.data = ""
|
|
@@ -80,13 +58,13 @@ class FuncStr(_UserString):
|
|
|
80
58
|
if self._isinit:
|
|
81
59
|
self.data += TAB
|
|
82
60
|
|
|
83
|
-
self.data +=
|
|
61
|
+
self.data += syntax(f"def {func.name}(")
|
|
84
62
|
if self._is_string:
|
|
85
|
-
self._docstring =
|
|
63
|
+
self._docstring = syntax(f"{TAB}{self.TRIPLE_QUOTES}")
|
|
86
64
|
else:
|
|
87
|
-
self._docstring = f"{TAB}{
|
|
65
|
+
self._docstring = f"{TAB}{_click.style('...', fg='red')}\n"
|
|
88
66
|
|
|
89
|
-
self._mark =
|
|
67
|
+
self._mark = _click.style(self.CHECK, fg="green")
|
|
90
68
|
for index in range(len(func)):
|
|
91
69
|
arg = func.signature.args.get(index)
|
|
92
70
|
doc = func.docstring.args.get(index)
|
|
@@ -119,9 +97,9 @@ class FuncStr(_UserString):
|
|
|
119
97
|
:param failed: Boolean to test that check failed.
|
|
120
98
|
"""
|
|
121
99
|
self._mark = (
|
|
122
|
-
|
|
100
|
+
_click.style(self.CROSS, fg="red")
|
|
123
101
|
if failed
|
|
124
|
-
else
|
|
102
|
+
else _click.style(self.CHECK, fg="green")
|
|
125
103
|
)
|
|
126
104
|
|
|
127
105
|
def add_param(
|
|
@@ -162,34 +140,27 @@ class FuncStr(_UserString):
|
|
|
162
140
|
:param arg: Signature argument.
|
|
163
141
|
"""
|
|
164
142
|
if arg is not None:
|
|
165
|
-
self.data += "{}{}{}{}"
|
|
166
|
-
self._ansi.syntax(") -> "),
|
|
167
|
-
self._mark,
|
|
168
|
-
arg,
|
|
169
|
-
self._ansi.syntax(":"),
|
|
170
|
-
)
|
|
143
|
+
self.data += f"{syntax(') -> ')}{self._mark}{arg}{syntax(':')}"
|
|
171
144
|
else:
|
|
172
145
|
self.data += "{}{}{}".format(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
146
|
+
syntax(")"),
|
|
147
|
+
_click.style("?", fg="red"),
|
|
148
|
+
syntax(":"),
|
|
176
149
|
)
|
|
177
150
|
|
|
178
151
|
def add_comma(self) -> None:
|
|
179
152
|
"""Add comma between parenthesis."""
|
|
180
|
-
self.data +=
|
|
153
|
+
self.data += syntax(", ")
|
|
181
154
|
|
|
182
155
|
def close_docstring(self) -> None:
|
|
183
156
|
"""Close docstring."""
|
|
184
|
-
self._cat_docstring(
|
|
185
|
-
f"\n{TAB}{self._ansi.syntax(self.TRIPLE_QUOTES)}\n"
|
|
186
|
-
)
|
|
157
|
+
self._cat_docstring(f"\n{TAB}{syntax(self.TRIPLE_QUOTES)}\n")
|
|
187
158
|
|
|
188
159
|
def render(self) -> None:
|
|
189
160
|
"""Render final string by adding docstring to function."""
|
|
190
161
|
if self._isinit:
|
|
191
162
|
self.data = (
|
|
192
|
-
|
|
163
|
+
syntax(f"class {self._parent_name}:")
|
|
193
164
|
+ f"\n{self._docstring}"
|
|
194
165
|
+ f"\n{self.data}\n"
|
|
195
166
|
)
|
|
@@ -217,7 +188,7 @@ class Display(_t.Dict[str, _t.List[Failures]]):
|
|
|
217
188
|
|
|
218
189
|
def __init__(self, no_ansi: bool = False) -> None:
|
|
219
190
|
super().__init__()
|
|
220
|
-
self._ansi =
|
|
191
|
+
self._ansi = not no_ansi and _sys.stdout.isatty()
|
|
221
192
|
|
|
222
193
|
def __getitem__(self, key: str) -> list[Failures]:
|
|
223
194
|
if key not in super().__iter__():
|
|
@@ -234,10 +205,12 @@ class Display(_t.Dict[str, _t.List[Failures]]):
|
|
|
234
205
|
if failure.func.parent.name:
|
|
235
206
|
header += f" in {failure.func.parent.name}"
|
|
236
207
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
208
|
+
_click.echo(
|
|
209
|
+
_click.style(header, fg="magenta"), color=self._ansi
|
|
210
|
+
)
|
|
211
|
+
_click.echo(len(header) * "-", color=self._ansi)
|
|
212
|
+
_click.echo(failure.func_str, color=self._ansi)
|
|
213
|
+
_click.echo(failure.report.get_report(), color=self._ansi)
|
|
241
214
|
|
|
242
215
|
def summarise(self) -> None:
|
|
243
216
|
"""Display report summary if any checks have failed."""
|
|
@@ -250,9 +223,10 @@ class Display(_t.Dict[str, _t.List[Failures]]):
|
|
|
250
223
|
function = f"{failure.func.parent.name}.{function}"
|
|
251
224
|
|
|
252
225
|
header += f" in {function}"
|
|
253
|
-
|
|
226
|
+
_click.echo(
|
|
254
227
|
"{}\n {}".format(
|
|
255
|
-
|
|
228
|
+
_click.style(header, fg="magenta"),
|
|
256
229
|
failure.report.get_report(" ").strip(),
|
|
257
|
-
)
|
|
230
|
+
),
|
|
231
|
+
color=self._ansi,
|
|
258
232
|
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
docsig._hooks
|
|
3
|
+
=============
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import sys as _sys
|
|
7
|
+
from os import environ as _e
|
|
8
|
+
|
|
9
|
+
import click as _click
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def pretty_print_error(no_ansi: bool = False) -> None:
|
|
13
|
+
"""Print user friendly commandline error if debug not enabled.
|
|
14
|
+
|
|
15
|
+
:param no_ansi: Disable ANSI output.
|
|
16
|
+
"""
|
|
17
|
+
if _e.get("DOCSIG_DEBUG", None) != "1":
|
|
18
|
+
_sys.excepthook = lambda x, y, _: _click.echo(
|
|
19
|
+
f"{_click.style(x.__name__, fg='red', bold=True)}: {y}",
|
|
20
|
+
file=_sys.stderr,
|
|
21
|
+
color=not no_ansi and _sys.stderr.isatty(),
|
|
22
|
+
)
|
|
@@ -20,16 +20,19 @@ RETURN = "return"
|
|
|
20
20
|
ARG = "arg"
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
# noinspection PyTypeChecker
|
|
23
24
|
class _GoogleDocstring(str):
|
|
24
25
|
def __new__(cls, string: str) -> _GoogleDocstring:
|
|
25
26
|
return super().__new__(cls, str(_s.GoogleDocstring(string)))
|
|
26
27
|
|
|
27
28
|
|
|
29
|
+
# noinspection PyTypeChecker
|
|
28
30
|
class _NumpyDocstring(str):
|
|
29
31
|
def __new__(cls, string: str) -> _NumpyDocstring:
|
|
30
32
|
return super().__new__(cls, str(_s.NumpyDocstring(string)))
|
|
31
33
|
|
|
32
34
|
|
|
35
|
+
# noinspection PyTypeChecker
|
|
33
36
|
class _DocFmt(str):
|
|
34
37
|
def __new__(cls, string: str) -> _DocFmt:
|
|
35
38
|
return super().__new__(
|
|
@@ -40,6 +43,7 @@ class _DocFmt(str):
|
|
|
40
43
|
)
|
|
41
44
|
|
|
42
45
|
|
|
46
|
+
# noinspection PyTypeChecker
|
|
43
47
|
class _RawDocstring(str):
|
|
44
48
|
def __new__(cls, string: str) -> _RawDocstring:
|
|
45
49
|
return super().__new__(
|
|
@@ -7,6 +7,8 @@ from __future__ import annotations as _
|
|
|
7
7
|
|
|
8
8
|
from difflib import SequenceMatcher as _SequenceMatcher
|
|
9
9
|
|
|
10
|
+
import click as _click
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
def almost_equal(str1: str, str2: str, mini: float, maxi: float) -> bool:
|
|
12
14
|
"""Show result for more than the minimum but less than the maximum.
|
|
@@ -28,4 +30,4 @@ def vprint(msg: str, verbose: bool = False) -> None:
|
|
|
28
30
|
:param verbose: Whether verbose mode is enabled.
|
|
29
31
|
"""
|
|
30
32
|
if verbose:
|
|
31
|
-
|
|
33
|
+
_click.echo(msg)
|
|
@@ -19,6 +19,7 @@ line-length = 79
|
|
|
19
19
|
[tool.constcheck]
|
|
20
20
|
ignore_strings = [
|
|
21
21
|
"disable",
|
|
22
|
+
"red",
|
|
22
23
|
"store",
|
|
23
24
|
"store_true",
|
|
24
25
|
"targets",
|
|
@@ -72,14 +73,14 @@ maintainers = [
|
|
|
72
73
|
name = "docsig"
|
|
73
74
|
readme = "README.rst"
|
|
74
75
|
repository = "https://github.com/jshwi/docsig"
|
|
75
|
-
version = "0.
|
|
76
|
+
version = "0.49.1"
|
|
76
77
|
|
|
77
78
|
[tool.poetry.dependencies]
|
|
78
79
|
Pygments = "^2.13.0"
|
|
79
80
|
Sphinx = "^7.0.0"
|
|
80
81
|
arcon = ">=0.4.0"
|
|
81
82
|
astroid = "^3.0.1"
|
|
82
|
-
|
|
83
|
+
click = "^8.1.7"
|
|
83
84
|
python = "^3.8"
|
|
84
85
|
|
|
85
86
|
[tool.poetry.dev-dependencies]
|
docsig-0.48.0/docsig/_hooks.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
docsig._hooks
|
|
3
|
-
=============
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import sys as _sys
|
|
7
|
-
from os import environ as _e
|
|
8
|
-
|
|
9
|
-
from ._display import color as _color
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def pretty_print_error() -> None:
|
|
13
|
-
"""Print user friendly commandline error if debug not enabled."""
|
|
14
|
-
if _e.get("DOCSIG_DEBUG", None) != "1":
|
|
15
|
-
_sys.excepthook = lambda x, y, _: print(
|
|
16
|
-
f"{_color.red.bold.get(x.__name__)}: {y}"
|
|
17
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|