docsig 0.52.0__tar.gz → 0.53.0__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.52.0 → docsig-0.53.0}/PKG-INFO +15 -24
- {docsig-0.52.0 → docsig-0.53.0}/README.rst +14 -22
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_config.py +15 -8
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_core.py +36 -33
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_decorators.py +23 -0
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_main.py +2 -1
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_module.py +2 -1
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_report.py +61 -15
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_stub.py +72 -52
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_version.py +1 -1
- {docsig-0.52.0 → docsig-0.53.0}/docsig/messages.py +1 -0
- {docsig-0.52.0 → docsig-0.53.0}/pyproject.toml +7 -4
- docsig-0.52.0/docsig/_display.py +0 -232
- {docsig-0.52.0 → docsig-0.53.0}/LICENSE +0 -0
- {docsig-0.52.0 → docsig-0.53.0}/docsig/__init__.py +0 -0
- {docsig-0.52.0 → docsig-0.53.0}/docsig/__main__.py +0 -0
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_directives.py +0 -0
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_hooks.py +0 -0
- {docsig-0.52.0 → docsig-0.53.0}/docsig/_utils.py +0 -0
- {docsig-0.52.0 → docsig-0.53.0}/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.53.0
|
|
4
4
|
Summary: Check signature params for proper documentation
|
|
5
5
|
Home-page: https://pypi.org/project/docsig/
|
|
6
6
|
License: MIT
|
|
@@ -17,7 +17,6 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Requires-Dist: Pygments (>=2.13.0,<3.0.0)
|
|
21
20
|
Requires-Dist: Sphinx (>=7.0.0,<8.0.0)
|
|
22
21
|
Requires-Dist: arcon (>=0.4.0)
|
|
23
22
|
Requires-Dist: astroid (>=3.0.1,<4.0.0)
|
|
@@ -108,10 +107,9 @@ Commandline
|
|
|
108
107
|
|
|
109
108
|
.. code-block:: console
|
|
110
109
|
|
|
111
|
-
usage: docsig [-h] [-V] [-l] [-c | -C] [-D] [-m] [-N] [-o] [-p] [-P] [-i] [-a]
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
[path [path ...]]
|
|
110
|
+
usage: docsig [-h] [-V] [-l] [-c | -C] [-D] [-m] [-N] [-o] [-p] [-P] [-i] [-a] [-k] [-T]
|
|
111
|
+
[-I] [-n] [-v] [-s STR] [-d LIST] [-t LIST] [-e PATTERN]
|
|
112
|
+
[path [path ...]]
|
|
115
113
|
|
|
116
114
|
Check signature params for proper documentation
|
|
117
115
|
|
|
@@ -123,41 +121,35 @@ Commandline
|
|
|
123
121
|
-V, --version show program's version number and exit
|
|
124
122
|
-l, --list-checks display a list of all checks and their messages
|
|
125
123
|
-c, --check-class check class docstrings
|
|
126
|
-
-C, --check-class-constructor check __init__ methods. Note: mutually
|
|
127
|
-
|
|
124
|
+
-C, --check-class-constructor check __init__ methods. Note: mutually incompatible
|
|
125
|
+
with -c
|
|
128
126
|
-D, --check-dunders check dunder methods
|
|
129
|
-
-m, --check-protected-class-methods check public methods belonging to protected
|
|
130
|
-
classes
|
|
127
|
+
-m, --check-protected-class-methods check public methods belonging to protected classes
|
|
131
128
|
-N, --check-nested check nested functions and classes
|
|
132
129
|
-o, --check-overridden check overridden methods
|
|
133
130
|
-p, --check-protected check protected functions and classes
|
|
134
131
|
-P, --check-property-returns check property return values
|
|
135
|
-
-i, --ignore-no-params ignore docstrings where parameters are not
|
|
136
|
-
documented
|
|
132
|
+
-i, --ignore-no-params ignore docstrings where parameters are not documented
|
|
137
133
|
-a, --ignore-args ignore args prefixed with an asterisk
|
|
138
134
|
-k, --ignore-kwargs ignore kwargs prefixed with two asterisks
|
|
139
|
-
-
|
|
140
|
-
|
|
135
|
+
-T, --ignore-typechecker ignore checking return values
|
|
136
|
+
-I, --include-ignored check files even if they match a gitignore pattern
|
|
141
137
|
-n, --no-ansi disable ansi output
|
|
142
|
-
-S, --summary print a summarised report
|
|
143
138
|
-v, --verbose increase output verbosity
|
|
144
139
|
-s STR, --string STR string to parse instead of files
|
|
145
140
|
-d LIST, --disable LIST comma separated list of rules to disable
|
|
146
141
|
-t LIST, --target LIST comma separated list of rules to target
|
|
147
|
-
-e PATTERN, --exclude PATTERN regular expression of files or dirs to exclude
|
|
148
|
-
|
|
142
|
+
-e PATTERN, --exclude PATTERN regular expression of files or dirs to exclude from
|
|
143
|
+
checks
|
|
149
144
|
|
|
150
145
|
Options can also be configured with the pyproject.toml file
|
|
151
146
|
|
|
152
|
-
If you find the output is too verbose then the report can be configured to display a summary
|
|
153
|
-
|
|
154
147
|
.. code-block:: toml
|
|
155
148
|
|
|
156
149
|
[tool.docsig]
|
|
157
150
|
check-dunders = false
|
|
158
151
|
check-overridden = false
|
|
159
152
|
check-protected = false
|
|
160
|
-
summary = true
|
|
161
153
|
disable = [
|
|
162
154
|
"E101",
|
|
163
155
|
"E102",
|
|
@@ -187,7 +179,7 @@ API
|
|
|
187
179
|
... :param param3: About param3.
|
|
188
180
|
... '''
|
|
189
181
|
... """
|
|
190
|
-
>>> docsig(string=string,
|
|
182
|
+
>>> docsig(string=string, no_ansi=True)
|
|
191
183
|
0
|
|
192
184
|
|
|
193
185
|
.. code-block:: python
|
|
@@ -201,7 +193,7 @@ API
|
|
|
201
193
|
... :param param3: About param3.
|
|
202
194
|
... '''
|
|
203
195
|
... """
|
|
204
|
-
>>> docsig(string=string,
|
|
196
|
+
>>> docsig(string=string, no_ansi=True)
|
|
205
197
|
2 in function
|
|
206
198
|
E102: includes parameters that do not exist (params-do-not-exist)
|
|
207
199
|
1
|
|
@@ -229,7 +221,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
229
221
|
|
|
230
222
|
repos:
|
|
231
223
|
- repo: https://github.com/jshwi/docsig
|
|
232
|
-
rev: v0.
|
|
224
|
+
rev: v0.53.0
|
|
233
225
|
hooks:
|
|
234
226
|
- id: docsig
|
|
235
227
|
args:
|
|
@@ -237,5 +229,4 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
237
229
|
- "--check-dunders"
|
|
238
230
|
- "--check-overridden"
|
|
239
231
|
- "--check-protected"
|
|
240
|
-
- "--summary"
|
|
241
232
|
|
|
@@ -79,10 +79,9 @@ Commandline
|
|
|
79
79
|
|
|
80
80
|
.. code-block:: console
|
|
81
81
|
|
|
82
|
-
usage: docsig [-h] [-V] [-l] [-c | -C] [-D] [-m] [-N] [-o] [-p] [-P] [-i] [-a]
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
[path [path ...]]
|
|
82
|
+
usage: docsig [-h] [-V] [-l] [-c | -C] [-D] [-m] [-N] [-o] [-p] [-P] [-i] [-a] [-k] [-T]
|
|
83
|
+
[-I] [-n] [-v] [-s STR] [-d LIST] [-t LIST] [-e PATTERN]
|
|
84
|
+
[path [path ...]]
|
|
86
85
|
|
|
87
86
|
Check signature params for proper documentation
|
|
88
87
|
|
|
@@ -94,41 +93,35 @@ Commandline
|
|
|
94
93
|
-V, --version show program's version number and exit
|
|
95
94
|
-l, --list-checks display a list of all checks and their messages
|
|
96
95
|
-c, --check-class check class docstrings
|
|
97
|
-
-C, --check-class-constructor check __init__ methods. Note: mutually
|
|
98
|
-
|
|
96
|
+
-C, --check-class-constructor check __init__ methods. Note: mutually incompatible
|
|
97
|
+
with -c
|
|
99
98
|
-D, --check-dunders check dunder methods
|
|
100
|
-
-m, --check-protected-class-methods check public methods belonging to protected
|
|
101
|
-
classes
|
|
99
|
+
-m, --check-protected-class-methods check public methods belonging to protected classes
|
|
102
100
|
-N, --check-nested check nested functions and classes
|
|
103
101
|
-o, --check-overridden check overridden methods
|
|
104
102
|
-p, --check-protected check protected functions and classes
|
|
105
103
|
-P, --check-property-returns check property return values
|
|
106
|
-
-i, --ignore-no-params ignore docstrings where parameters are not
|
|
107
|
-
documented
|
|
104
|
+
-i, --ignore-no-params ignore docstrings where parameters are not documented
|
|
108
105
|
-a, --ignore-args ignore args prefixed with an asterisk
|
|
109
106
|
-k, --ignore-kwargs ignore kwargs prefixed with two asterisks
|
|
110
|
-
-
|
|
111
|
-
|
|
107
|
+
-T, --ignore-typechecker ignore checking return values
|
|
108
|
+
-I, --include-ignored check files even if they match a gitignore pattern
|
|
112
109
|
-n, --no-ansi disable ansi output
|
|
113
|
-
-S, --summary print a summarised report
|
|
114
110
|
-v, --verbose increase output verbosity
|
|
115
111
|
-s STR, --string STR string to parse instead of files
|
|
116
112
|
-d LIST, --disable LIST comma separated list of rules to disable
|
|
117
113
|
-t LIST, --target LIST comma separated list of rules to target
|
|
118
|
-
-e PATTERN, --exclude PATTERN regular expression of files or dirs to exclude
|
|
119
|
-
|
|
114
|
+
-e PATTERN, --exclude PATTERN regular expression of files or dirs to exclude from
|
|
115
|
+
checks
|
|
120
116
|
|
|
121
117
|
Options can also be configured with the pyproject.toml file
|
|
122
118
|
|
|
123
|
-
If you find the output is too verbose then the report can be configured to display a summary
|
|
124
|
-
|
|
125
119
|
.. code-block:: toml
|
|
126
120
|
|
|
127
121
|
[tool.docsig]
|
|
128
122
|
check-dunders = false
|
|
129
123
|
check-overridden = false
|
|
130
124
|
check-protected = false
|
|
131
|
-
summary = true
|
|
132
125
|
disable = [
|
|
133
126
|
"E101",
|
|
134
127
|
"E102",
|
|
@@ -158,7 +151,7 @@ API
|
|
|
158
151
|
... :param param3: About param3.
|
|
159
152
|
... '''
|
|
160
153
|
... """
|
|
161
|
-
>>> docsig(string=string,
|
|
154
|
+
>>> docsig(string=string, no_ansi=True)
|
|
162
155
|
0
|
|
163
156
|
|
|
164
157
|
.. code-block:: python
|
|
@@ -172,7 +165,7 @@ API
|
|
|
172
165
|
... :param param3: About param3.
|
|
173
166
|
... '''
|
|
174
167
|
... """
|
|
175
|
-
>>> docsig(string=string,
|
|
168
|
+
>>> docsig(string=string, no_ansi=True)
|
|
176
169
|
2 in function
|
|
177
170
|
E102: includes parameters that do not exist (params-do-not-exist)
|
|
178
171
|
1
|
|
@@ -200,7 +193,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
200
193
|
|
|
201
194
|
repos:
|
|
202
195
|
- repo: https://github.com/jshwi/docsig
|
|
203
|
-
rev: v0.
|
|
196
|
+
rev: v0.53.0
|
|
204
197
|
hooks:
|
|
205
198
|
- id: docsig
|
|
206
199
|
args:
|
|
@@ -208,4 +201,3 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
208
201
|
- "--check-dunders"
|
|
209
202
|
- "--check-overridden"
|
|
210
203
|
- "--check-protected"
|
|
211
|
-
- "--summary"
|
|
@@ -3,10 +3,10 @@ docsig._config
|
|
|
3
3
|
==============
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
from argparse import SUPPRESS as _SUPPRESS
|
|
6
7
|
from argparse import HelpFormatter as _HelpFormatter
|
|
7
8
|
from pathlib import Path as _Path
|
|
8
9
|
|
|
9
|
-
import click as _click
|
|
10
10
|
from arcon import ArgumentParser as _ArgumentParser
|
|
11
11
|
|
|
12
12
|
from ._version import __version__
|
|
@@ -18,7 +18,6 @@ class Parser(_ArgumentParser):
|
|
|
18
18
|
def __init__(self) -> None:
|
|
19
19
|
super().__init__(
|
|
20
20
|
version=__version__,
|
|
21
|
-
prog=_click.style(__package__, fg="cyan"),
|
|
22
21
|
formatter_class=lambda prog: _HelpFormatter(
|
|
23
22
|
prog, max_help_position=45
|
|
24
23
|
),
|
|
@@ -109,6 +108,12 @@ class Parser(_ArgumentParser):
|
|
|
109
108
|
action="store_true",
|
|
110
109
|
help="ignore kwargs prefixed with two asterisks",
|
|
111
110
|
)
|
|
111
|
+
self.add_argument(
|
|
112
|
+
"-T",
|
|
113
|
+
"--ignore-typechecker",
|
|
114
|
+
action="store_true",
|
|
115
|
+
help="ignore checking return values",
|
|
116
|
+
)
|
|
112
117
|
self.add_argument(
|
|
113
118
|
"-I",
|
|
114
119
|
"--include-ignored",
|
|
@@ -121,12 +126,6 @@ class Parser(_ArgumentParser):
|
|
|
121
126
|
action="store_true",
|
|
122
127
|
help="disable ansi output",
|
|
123
128
|
)
|
|
124
|
-
self.add_argument(
|
|
125
|
-
"-S",
|
|
126
|
-
"--summary",
|
|
127
|
-
action="store_true",
|
|
128
|
-
help="print a summarised report",
|
|
129
|
-
)
|
|
130
129
|
self.add_argument(
|
|
131
130
|
"-v",
|
|
132
131
|
"--verbose",
|
|
@@ -158,3 +157,11 @@ class Parser(_ArgumentParser):
|
|
|
158
157
|
metavar="PATTERN",
|
|
159
158
|
help="regular expression of files or dirs to exclude from checks",
|
|
160
159
|
)
|
|
160
|
+
|
|
161
|
+
# deprecated
|
|
162
|
+
self.add_argument(
|
|
163
|
+
"-S",
|
|
164
|
+
"--summary",
|
|
165
|
+
action="store_true",
|
|
166
|
+
help=_SUPPRESS,
|
|
167
|
+
)
|
|
@@ -8,38 +8,36 @@ from __future__ import annotations as _
|
|
|
8
8
|
from pathlib import Path as _Path
|
|
9
9
|
|
|
10
10
|
from . import _decorators
|
|
11
|
-
from ._display import Display as _Display
|
|
12
|
-
from ._display import Failure as _Failure
|
|
13
|
-
from ._display import Failures as _Failures
|
|
14
|
-
from ._display import FuncStr as _FuncStr
|
|
15
11
|
from ._module import Function as _Function
|
|
16
12
|
from ._module import Modules as _Modules
|
|
17
13
|
from ._module import Parent as _Parent
|
|
14
|
+
from ._report import Failure as _Failure
|
|
15
|
+
from ._report import Failures as _Failures
|
|
18
16
|
from ._report import Report as _Report
|
|
19
17
|
from ._utils import print_checks as _print_checks
|
|
20
18
|
from .messages import Messages as _Messages
|
|
21
19
|
|
|
22
20
|
_DEFAULT_EXCLUDES = """\
|
|
23
21
|
(?x)^(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
|\\.?venv
|
|
23
|
+
|\\.git
|
|
24
|
+
|\\.hg
|
|
25
|
+
|\\.idea
|
|
26
|
+
|\\.mypy_cache
|
|
27
|
+
|\\.nox
|
|
28
|
+
|\\.pytest_cache
|
|
29
|
+
|\\.svn
|
|
30
|
+
|\\.tox
|
|
31
|
+
|\\.vscode
|
|
32
|
+
|_?build
|
|
33
|
+
|__pycache__
|
|
34
|
+
|dist
|
|
35
|
+
|node_modules
|
|
38
36
|
)$
|
|
39
37
|
"""
|
|
40
38
|
|
|
41
39
|
|
|
42
|
-
def _run_check( # pylint: disable=too-many-arguments
|
|
40
|
+
def _run_check( # pylint: disable=too-many-arguments,too-many-locals
|
|
43
41
|
child: _Parent,
|
|
44
42
|
parent: _Parent,
|
|
45
43
|
check_class: bool,
|
|
@@ -50,6 +48,7 @@ def _run_check( # pylint: disable=too-many-arguments
|
|
|
50
48
|
check_protected: bool,
|
|
51
49
|
check_property_returns: bool,
|
|
52
50
|
ignore_no_params: bool,
|
|
51
|
+
ignore_typechecker: bool,
|
|
53
52
|
no_ansi: bool,
|
|
54
53
|
targets: _Messages,
|
|
55
54
|
failures: _Failures,
|
|
@@ -67,11 +66,15 @@ def _run_check( # pylint: disable=too-many-arguments
|
|
|
67
66
|
and not (child.isdunder and not check_dunders)
|
|
68
67
|
and not (child.docstring.bare and ignore_no_params)
|
|
69
68
|
):
|
|
70
|
-
|
|
71
|
-
child,
|
|
69
|
+
failure = _Failure(
|
|
70
|
+
child,
|
|
71
|
+
targets,
|
|
72
|
+
child.messages,
|
|
73
|
+
check_property_returns,
|
|
74
|
+
ignore_typechecker,
|
|
72
75
|
)
|
|
73
|
-
if
|
|
74
|
-
failures.append(
|
|
76
|
+
if failure:
|
|
77
|
+
failures.append(failure)
|
|
75
78
|
|
|
76
79
|
if check_nested:
|
|
77
80
|
for func in child:
|
|
@@ -86,6 +89,7 @@ def _run_check( # pylint: disable=too-many-arguments
|
|
|
86
89
|
check_protected,
|
|
87
90
|
check_property_returns,
|
|
88
91
|
ignore_no_params,
|
|
92
|
+
ignore_typechecker,
|
|
89
93
|
no_ansi,
|
|
90
94
|
targets,
|
|
91
95
|
failures,
|
|
@@ -104,6 +108,7 @@ def _run_check( # pylint: disable=too-many-arguments
|
|
|
104
108
|
check_protected,
|
|
105
109
|
check_property_returns,
|
|
106
110
|
ignore_no_params,
|
|
111
|
+
ignore_typechecker,
|
|
107
112
|
no_ansi,
|
|
108
113
|
targets,
|
|
109
114
|
failures,
|
|
@@ -111,6 +116,7 @@ def _run_check( # pylint: disable=too-many-arguments
|
|
|
111
116
|
|
|
112
117
|
|
|
113
118
|
@_decorators.parse_msgs
|
|
119
|
+
@_decorators.handle_deprecations
|
|
114
120
|
@_decorators.validate_args
|
|
115
121
|
def docsig( # pylint: disable=too-many-locals,too-many-arguments
|
|
116
122
|
*path: str | _Path,
|
|
@@ -128,8 +134,8 @@ def docsig( # pylint: disable=too-many-locals,too-many-arguments
|
|
|
128
134
|
ignore_no_params: bool = False,
|
|
129
135
|
ignore_args: bool = False,
|
|
130
136
|
ignore_kwargs: bool = False,
|
|
137
|
+
ignore_typechecker: bool = False,
|
|
131
138
|
no_ansi: bool = False,
|
|
132
|
-
summary: bool = False,
|
|
133
139
|
verbose: bool = False,
|
|
134
140
|
targets: _Messages | None = None,
|
|
135
141
|
disable: _Messages | None = None,
|
|
@@ -163,8 +169,8 @@ def docsig( # pylint: disable=too-many-locals,too-many-arguments
|
|
|
163
169
|
documented
|
|
164
170
|
:param ignore_args: Ignore args prefixed with an asterisk.
|
|
165
171
|
:param ignore_kwargs: Ignore kwargs prefixed with two asterisks.
|
|
172
|
+
:param ignore_typechecker: Ignore checking return values.
|
|
166
173
|
:param no_ansi: Disable ANSI output.
|
|
167
|
-
:param summary: Print a summarised report.
|
|
168
174
|
:param verbose: increase output verbosity.
|
|
169
175
|
:param targets: List of errors to target.
|
|
170
176
|
:param disable: List of errors to disable.
|
|
@@ -191,7 +197,7 @@ def docsig( # pylint: disable=too-many-locals,too-many-arguments
|
|
|
191
197
|
no_ansi=no_ansi,
|
|
192
198
|
verbose=verbose,
|
|
193
199
|
)
|
|
194
|
-
|
|
200
|
+
report = _Report()
|
|
195
201
|
for module in modules:
|
|
196
202
|
for top_level in module:
|
|
197
203
|
if (
|
|
@@ -211,16 +217,13 @@ def docsig( # pylint: disable=too-many-locals,too-many-arguments
|
|
|
211
217
|
check_protected,
|
|
212
218
|
check_property_returns,
|
|
213
219
|
ignore_no_params,
|
|
220
|
+
ignore_typechecker,
|
|
214
221
|
no_ansi,
|
|
215
222
|
targets or _Messages(),
|
|
216
223
|
failures,
|
|
217
224
|
)
|
|
218
225
|
if failures:
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if summary:
|
|
222
|
-
display.summarise()
|
|
223
|
-
else:
|
|
224
|
-
display.report()
|
|
226
|
+
report[top_level.path].append(failures)
|
|
225
227
|
|
|
226
|
-
|
|
228
|
+
report.print(no_ansi)
|
|
229
|
+
return max(int(bool(report)), modules.retcode)
|
|
@@ -9,6 +9,7 @@ import functools as _functools
|
|
|
9
9
|
import sys as _sys
|
|
10
10
|
import typing as _t
|
|
11
11
|
from pathlib import Path as _Path
|
|
12
|
+
from warnings import warn as _warn
|
|
12
13
|
|
|
13
14
|
from .messages import E as _E
|
|
14
15
|
|
|
@@ -34,6 +35,28 @@ def parse_msgs(func: _WrappedFuncType) -> _WrappedFuncType:
|
|
|
34
35
|
return _wrapper
|
|
35
36
|
|
|
36
37
|
|
|
38
|
+
def handle_deprecations(func: _WrappedFuncType) -> _WrappedFuncType:
|
|
39
|
+
"""Allow, but warn, of deprecated arguments.
|
|
40
|
+
|
|
41
|
+
:param func: Function to wrap.
|
|
42
|
+
:return: Wrapped function.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
@_functools.wraps(func)
|
|
46
|
+
def _wrapper(*args: str | _Path, **kwargs: _t.Any) -> str | int:
|
|
47
|
+
if kwargs.pop("summary", None):
|
|
48
|
+
_warn(
|
|
49
|
+
"summary is deprecated and will be removed in a future"
|
|
50
|
+
" version",
|
|
51
|
+
category=DeprecationWarning,
|
|
52
|
+
stacklevel=4,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
return func(*args, **kwargs)
|
|
56
|
+
|
|
57
|
+
return _wrapper
|
|
58
|
+
|
|
59
|
+
|
|
37
60
|
def validate_args(func: _FuncType) -> _WrappedFuncType:
|
|
38
61
|
"""Confirm args passed to function are valid.
|
|
39
62
|
|
|
@@ -37,8 +37,9 @@ def main() -> str | int:
|
|
|
37
37
|
ignore_no_params=p.args.ignore_no_params,
|
|
38
38
|
ignore_args=p.args.ignore_args,
|
|
39
39
|
ignore_kwargs=p.args.ignore_kwargs,
|
|
40
|
+
ignore_typechecker=p.args.ignore_typechecker,
|
|
40
41
|
no_ansi=p.args.no_ansi,
|
|
41
|
-
summary=p.args.summary,
|
|
42
|
+
summary=p.args.summary, # deprecated
|
|
42
43
|
verbose=p.args.verbose,
|
|
43
44
|
targets=p.args.target,
|
|
44
45
|
disable=p.args.disable,
|
|
@@ -20,6 +20,7 @@ from pathspec.patterns import GitWildMatchPattern as _GitWildMatchPattern
|
|
|
20
20
|
from ._directives import Comment as _Comment
|
|
21
21
|
from ._directives import Directives as _Directives
|
|
22
22
|
from ._stub import Docstring as _Docstring
|
|
23
|
+
from ._stub import RetType as _RetType
|
|
23
24
|
from ._stub import Signature as _Signature
|
|
24
25
|
from ._utils import pretty_print_error as _pretty_print_error
|
|
25
26
|
from ._utils import vprint as _vprint
|
|
@@ -356,7 +357,7 @@ class Function(Parent):
|
|
|
356
357
|
"""Comments, if any, belonging to this function."""
|
|
357
358
|
return self._comments
|
|
358
359
|
|
|
359
|
-
def overload(self, rettype:
|
|
360
|
+
def overload(self, rettype: _RetType) -> None:
|
|
360
361
|
"""Overload function with new signature return type.
|
|
361
362
|
|
|
362
363
|
:param rettype: Return type of overloaded signature.
|
|
@@ -5,11 +5,14 @@ docsig._report
|
|
|
5
5
|
|
|
6
6
|
from __future__ import annotations as _
|
|
7
7
|
|
|
8
|
+
import sys as _sys
|
|
8
9
|
import typing as _t
|
|
9
10
|
|
|
11
|
+
import click as _click
|
|
12
|
+
|
|
10
13
|
from ._module import Function as _Function
|
|
11
|
-
from ._stub import RETURN as _RETURN
|
|
12
14
|
from ._stub import Param as _Param
|
|
15
|
+
from ._stub import RetType as _RetType
|
|
13
16
|
from ._utils import almost_equal as _almost_equal
|
|
14
17
|
from .messages import TEMPLATE as _TEMPLATE
|
|
15
18
|
from .messages import E as _E
|
|
@@ -20,21 +23,23 @@ _MIN_MATCH = 0.8
|
|
|
20
23
|
_MAX_MATCH = 1.0
|
|
21
24
|
|
|
22
25
|
|
|
23
|
-
class
|
|
26
|
+
class Failure(_t.List[str]):
|
|
24
27
|
"""Compile and produce report.
|
|
25
28
|
|
|
26
29
|
:param func: Function object.
|
|
27
30
|
:param targets: List of errors to target.
|
|
28
31
|
:param disable: List of errors to disable.
|
|
29
32
|
:param check_property_returns: Run return checks on properties.
|
|
33
|
+
:param ignore_typechecker: Ignore checking return values.
|
|
30
34
|
"""
|
|
31
35
|
|
|
32
|
-
def __init__(
|
|
36
|
+
def __init__( # pylint: disable=too-many-arguments
|
|
33
37
|
self,
|
|
34
38
|
func: _Function,
|
|
35
39
|
targets: _Messages,
|
|
36
40
|
disable: _Messages,
|
|
37
41
|
check_property_returns: bool,
|
|
42
|
+
ignore_typechecker: bool,
|
|
38
43
|
) -> None:
|
|
39
44
|
super().__init__()
|
|
40
45
|
self._disable = list(disable)
|
|
@@ -47,8 +52,14 @@ class Report(_t.List[str]):
|
|
|
47
52
|
|
|
48
53
|
self._errors = _Messages()
|
|
49
54
|
self._func = func
|
|
50
|
-
self._no_prop_return =
|
|
51
|
-
|
|
55
|
+
self._no_prop_return = (
|
|
56
|
+
func.isproperty
|
|
57
|
+
and not check_property_returns
|
|
58
|
+
and not ignore_typechecker
|
|
59
|
+
)
|
|
60
|
+
self._no_returns = (
|
|
61
|
+
func.isinit or self._no_prop_return or ignore_typechecker
|
|
62
|
+
)
|
|
52
63
|
self._invalid_directive()
|
|
53
64
|
self._invalid_directive_options()
|
|
54
65
|
self._missing_class_docstring()
|
|
@@ -116,7 +127,7 @@ class Report(_t.List[str]):
|
|
|
116
127
|
def _extra_return(self) -> None:
|
|
117
128
|
if (
|
|
118
129
|
self._func.docstring.returns
|
|
119
|
-
and self._func.signature.rettype ==
|
|
130
|
+
and self._func.signature.rettype == _RetType.NONE
|
|
120
131
|
and not self._no_returns
|
|
121
132
|
):
|
|
122
133
|
self._add(_E[104])
|
|
@@ -126,8 +137,11 @@ class Report(_t.List[str]):
|
|
|
126
137
|
self._add(_E[108], hint=True)
|
|
127
138
|
|
|
128
139
|
def _return_not_typed(self) -> None:
|
|
129
|
-
if
|
|
130
|
-
self.
|
|
140
|
+
if (
|
|
141
|
+
self._func.signature.rettype == _RetType.UNTYPED
|
|
142
|
+
and not self._no_returns
|
|
143
|
+
):
|
|
144
|
+
self._add(_E[109], hint=True)
|
|
131
145
|
|
|
132
146
|
def _missing_return(self) -> None:
|
|
133
147
|
hint = False
|
|
@@ -137,7 +151,7 @@ class Report(_t.List[str]):
|
|
|
137
151
|
and not self._no_returns
|
|
138
152
|
):
|
|
139
153
|
docstring = self._func.docstring.string
|
|
140
|
-
if docstring is not None and
|
|
154
|
+
if docstring is not None and "return" in docstring:
|
|
141
155
|
hint = True
|
|
142
156
|
|
|
143
157
|
self._add(_E[105], hint=hint)
|
|
@@ -188,11 +202,43 @@ class Report(_t.List[str]):
|
|
|
188
202
|
option=rule.description,
|
|
189
203
|
)
|
|
190
204
|
|
|
191
|
-
|
|
192
|
-
|
|
205
|
+
@property
|
|
206
|
+
def func(self) -> _Function:
|
|
207
|
+
"""Function this failure belongs to."""
|
|
208
|
+
return self._func
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class Failures(_t.List[Failure]):
|
|
212
|
+
"""Sequence of failed functions."""
|
|
193
213
|
|
|
194
|
-
|
|
195
|
-
|
|
214
|
+
|
|
215
|
+
class Report(_t.Dict[str, _t.List[Failures]]):
|
|
216
|
+
"""Collect and display report."""
|
|
217
|
+
|
|
218
|
+
def __getitem__(self, key: str) -> list[Failures]:
|
|
219
|
+
if key not in super().__iter__():
|
|
220
|
+
super().__setitem__(key, [])
|
|
221
|
+
|
|
222
|
+
return super().__getitem__(key)
|
|
223
|
+
|
|
224
|
+
def print(self, no_ansi: bool) -> None:
|
|
225
|
+
"""Display report summary if any checks have failed.
|
|
226
|
+
|
|
227
|
+
:param no_ansi: Disable ANSI output.
|
|
196
228
|
"""
|
|
197
|
-
|
|
198
|
-
|
|
229
|
+
for key, value in self.items():
|
|
230
|
+
for failures in value:
|
|
231
|
+
for failure in failures:
|
|
232
|
+
header = f"{key}{failure.func.lineno}"
|
|
233
|
+
function = failure.func.name
|
|
234
|
+
if failure.func.parent.name:
|
|
235
|
+
function = f"{failure.func.parent.name}.{function}"
|
|
236
|
+
|
|
237
|
+
header += f" in {function}"
|
|
238
|
+
_click.echo(
|
|
239
|
+
"{}\n {}".format(
|
|
240
|
+
_click.style(header, fg="magenta"),
|
|
241
|
+
"\n ".join(failure),
|
|
242
|
+
),
|
|
243
|
+
color=not no_ansi and _sys.stdout.isatty(),
|
|
244
|
+
)
|
|
@@ -9,16 +9,11 @@ import re as _re
|
|
|
9
9
|
import textwrap as _textwrap
|
|
10
10
|
import typing as _t
|
|
11
11
|
from collections import Counter as _Counter
|
|
12
|
+
from enum import Enum as _Enum
|
|
12
13
|
|
|
13
14
|
import astroid as _ast
|
|
14
15
|
import sphinx.ext.napoleon as _s
|
|
15
16
|
|
|
16
|
-
PARAM = "param"
|
|
17
|
-
KEYWORD = "keyword"
|
|
18
|
-
KEY = "key"
|
|
19
|
-
RETURN = "return"
|
|
20
|
-
ARG = "arg"
|
|
21
|
-
|
|
22
17
|
|
|
23
18
|
# noinspection PyTypeChecker
|
|
24
19
|
class _GoogleDocstring(str):
|
|
@@ -51,10 +46,66 @@ class _RawDocstring(str):
|
|
|
51
46
|
)
|
|
52
47
|
|
|
53
48
|
|
|
49
|
+
class RetType(_Enum):
|
|
50
|
+
"""Defines the possible types of a return annotation."""
|
|
51
|
+
|
|
52
|
+
NONE = 1
|
|
53
|
+
SOME = 2
|
|
54
|
+
UNTYPED = 3
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def from_ast(cls, returns: _ast.NodeNG | None) -> RetType:
|
|
58
|
+
"""Construct a return type object from an AST node.
|
|
59
|
+
|
|
60
|
+
:param returns: Ast node or None.
|
|
61
|
+
:return: Constructed return type.
|
|
62
|
+
"""
|
|
63
|
+
if isinstance(returns, _ast.Const) and returns.value is None:
|
|
64
|
+
return cls.NONE
|
|
65
|
+
|
|
66
|
+
if isinstance(
|
|
67
|
+
returns,
|
|
68
|
+
(
|
|
69
|
+
_ast.Const,
|
|
70
|
+
_ast.Name,
|
|
71
|
+
_ast.Attribute,
|
|
72
|
+
_ast.Subscript,
|
|
73
|
+
_ast.BinOp,
|
|
74
|
+
),
|
|
75
|
+
):
|
|
76
|
+
return cls.SOME
|
|
77
|
+
|
|
78
|
+
return cls.UNTYPED
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class DocType(_Enum):
|
|
82
|
+
"""Defines the possible types of a docstring."""
|
|
83
|
+
|
|
84
|
+
PARAM = 1
|
|
85
|
+
ARG = 2
|
|
86
|
+
KWARG = 3
|
|
87
|
+
UNKNOWN = 4
|
|
88
|
+
|
|
89
|
+
@classmethod
|
|
90
|
+
def from_str(cls, docstring: str) -> DocType:
|
|
91
|
+
"""Construct a doc type object from a docstring.
|
|
92
|
+
|
|
93
|
+
:param docstring: Docstring string.
|
|
94
|
+
:return: Constructed doc type.
|
|
95
|
+
"""
|
|
96
|
+
try:
|
|
97
|
+
return cls[docstring.upper()]
|
|
98
|
+
except KeyError:
|
|
99
|
+
if docstring in ("key", "keyword"):
|
|
100
|
+
return cls.KWARG
|
|
101
|
+
|
|
102
|
+
return cls.UNKNOWN
|
|
103
|
+
|
|
104
|
+
|
|
54
105
|
class Param(_t.NamedTuple):
|
|
55
106
|
"""A tuple of param types and their names."""
|
|
56
107
|
|
|
57
|
-
kind:
|
|
108
|
+
kind: DocType = DocType.PARAM
|
|
58
109
|
name: str | None = None
|
|
59
110
|
description: str | None = None
|
|
60
111
|
indent: int = 0
|
|
@@ -64,7 +115,7 @@ class Param(_t.NamedTuple):
|
|
|
64
115
|
return False
|
|
65
116
|
|
|
66
117
|
args = self, other
|
|
67
|
-
return all(i.kind ==
|
|
118
|
+
return all(i.kind == DocType.KWARG for i in args) or (
|
|
68
119
|
self.name == other.name and all(i.name is not None for i in args)
|
|
69
120
|
)
|
|
70
121
|
|
|
@@ -79,7 +130,6 @@ class Param(_t.NamedTuple):
|
|
|
79
130
|
|
|
80
131
|
class _Matches(_t.List[Param]):
|
|
81
132
|
_pattern = _re.compile(":(.*?):")
|
|
82
|
-
_normalize = {KEYWORD: KEY}
|
|
83
133
|
|
|
84
134
|
def __init__(self, string: str) -> None:
|
|
85
135
|
super().__init__()
|
|
@@ -90,9 +140,7 @@ class _Matches(_t.List[Param]):
|
|
|
90
140
|
name = description = None
|
|
91
141
|
kinds = match[0].split()
|
|
92
142
|
if kinds:
|
|
93
|
-
kind = kinds[0]
|
|
94
|
-
for substring, replace in self._normalize.items():
|
|
95
|
-
kind = kind.replace(substring, replace)
|
|
143
|
+
kind = DocType.from_str(kinds[0])
|
|
96
144
|
|
|
97
145
|
if len(kinds) > 1:
|
|
98
146
|
name = kinds[1]
|
|
@@ -121,12 +169,12 @@ class _Params(_t.List[Param]):
|
|
|
121
169
|
# pylint: disable=too-many-boolean-expressions
|
|
122
170
|
def append(self, value: Param) -> None:
|
|
123
171
|
if not value.isprotected and (
|
|
124
|
-
value.kind == PARAM
|
|
125
|
-
or (value.kind == ARG and not self._ignore_args)
|
|
172
|
+
value.kind == DocType.PARAM
|
|
173
|
+
or (value.kind == DocType.ARG and not self._ignore_args)
|
|
126
174
|
or (
|
|
127
|
-
value.kind ==
|
|
175
|
+
value.kind == DocType.KWARG
|
|
128
176
|
and not self._ignore_kwargs
|
|
129
|
-
and not any(i.kind ==
|
|
177
|
+
and not any(i.kind == DocType.KWARG for i in self)
|
|
130
178
|
)
|
|
131
179
|
):
|
|
132
180
|
super().append(value)
|
|
@@ -203,45 +251,19 @@ class Signature(_Stub):
|
|
|
203
251
|
for a in [
|
|
204
252
|
*arguments.posonlyargs,
|
|
205
253
|
*arguments.args,
|
|
206
|
-
Param(ARG, name=arguments.vararg),
|
|
254
|
+
Param(DocType.ARG, name=arguments.vararg),
|
|
207
255
|
*arguments.kwonlyargs,
|
|
208
|
-
Param(
|
|
256
|
+
Param(DocType.KWARG, name=arguments.kwarg),
|
|
209
257
|
]
|
|
210
258
|
if a is not None and a.name
|
|
211
259
|
]:
|
|
212
260
|
self.args.append(i)
|
|
213
261
|
|
|
214
|
-
self._rettype = (
|
|
215
|
-
|
|
216
|
-
)
|
|
217
|
-
self._returns = str(self._rettype) != "None"
|
|
218
|
-
|
|
219
|
-
def _get_rettype(self, returns: _ast.NodeNG | None) -> str | None:
|
|
220
|
-
if isinstance(returns, _ast.Name):
|
|
221
|
-
return returns.name
|
|
222
|
-
|
|
223
|
-
if isinstance(returns, _ast.Attribute):
|
|
224
|
-
return returns.attrname
|
|
225
|
-
|
|
226
|
-
if isinstance(returns, _ast.Const):
|
|
227
|
-
return str(returns.value)
|
|
228
|
-
|
|
229
|
-
if isinstance(returns, _ast.Subscript):
|
|
230
|
-
return "{}[{}]".format(
|
|
231
|
-
self._get_rettype(returns.value),
|
|
232
|
-
self._get_rettype(returns.slice),
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
if isinstance(returns, _ast.BinOp):
|
|
236
|
-
return "{} | {}".format(
|
|
237
|
-
self._get_rettype(returns.left),
|
|
238
|
-
self._get_rettype(returns.right),
|
|
239
|
-
)
|
|
240
|
-
|
|
241
|
-
return None
|
|
262
|
+
self._rettype = RetType.from_ast(returns)
|
|
263
|
+
self._returns = self._rettype == RetType.SOME
|
|
242
264
|
|
|
243
265
|
@property
|
|
244
|
-
def rettype(self) ->
|
|
266
|
+
def rettype(self) -> RetType:
|
|
245
267
|
"""Function's return value.
|
|
246
268
|
|
|
247
269
|
If a function is typed to return None, return str(None). If no
|
|
@@ -249,15 +271,13 @@ class Signature(_Stub):
|
|
|
249
271
|
"""
|
|
250
272
|
return self._rettype
|
|
251
273
|
|
|
252
|
-
def overload(self, rettype:
|
|
274
|
+
def overload(self, rettype: RetType) -> None:
|
|
253
275
|
"""Overload signature with a ret type.
|
|
254
276
|
|
|
255
277
|
:param rettype: Return type of overloaded signature.
|
|
256
278
|
"""
|
|
257
|
-
self._rettype =
|
|
258
|
-
|
|
259
|
-
)
|
|
260
|
-
self._returns = str(rettype) != "None"
|
|
279
|
+
self._rettype = rettype
|
|
280
|
+
self._returns = rettype != RetType.NONE
|
|
261
281
|
|
|
262
282
|
|
|
263
283
|
class Docstring(_Stub):
|
|
@@ -16,6 +16,9 @@ exclude = '''
|
|
|
16
16
|
'''
|
|
17
17
|
line-length = 79
|
|
18
18
|
|
|
19
|
+
[tool.codespell]
|
|
20
|
+
ignore-words-list = "astroid"
|
|
21
|
+
|
|
19
22
|
[tool.coverage.report]
|
|
20
23
|
exclude_lines = [
|
|
21
24
|
"@_t.overload"
|
|
@@ -31,7 +34,6 @@ omit = [
|
|
|
31
34
|
[tool.docsig]
|
|
32
35
|
check-class = true
|
|
33
36
|
check-protected-class-methods = true
|
|
34
|
-
summary = true
|
|
35
37
|
|
|
36
38
|
[tool.isort]
|
|
37
39
|
ensure_newline_before_comments = true
|
|
@@ -63,10 +65,9 @@ maintainers = [
|
|
|
63
65
|
name = "docsig"
|
|
64
66
|
readme = "README.rst"
|
|
65
67
|
repository = "https://github.com/jshwi/docsig"
|
|
66
|
-
version = "0.
|
|
68
|
+
version = "0.53.0"
|
|
67
69
|
|
|
68
70
|
[tool.poetry.dependencies]
|
|
69
|
-
Pygments = "^2.13.0"
|
|
70
71
|
Sphinx = "^7.0.0"
|
|
71
72
|
arcon = ">=0.4.0"
|
|
72
73
|
astroid = "^3.0.1"
|
|
@@ -82,11 +83,12 @@ pre-commit = "^3.3.3"
|
|
|
82
83
|
pyaud = "^7.5.0"
|
|
83
84
|
pytest-randomly = "^3.13.0"
|
|
84
85
|
pytest-sugar = "^1.0.0"
|
|
85
|
-
pytest-xdist = "^3.
|
|
86
|
+
pytest-xdist = "^3.6.1"
|
|
86
87
|
restview = "^3.0.0"
|
|
87
88
|
sphinx-immaterial = "^0.11.9"
|
|
88
89
|
sphinx-toolbox = "^3.5.0"
|
|
89
90
|
templatest = "^0.10.1"
|
|
91
|
+
tox = "^4.15.0"
|
|
90
92
|
|
|
91
93
|
[tool.poetry.scripts]
|
|
92
94
|
docsig = "docsig.__main__:main"
|
|
@@ -110,6 +112,7 @@ exclude = '''
|
|
|
110
112
|
(?x)^(
|
|
111
113
|
| docs\/conf\.py
|
|
112
114
|
| whitelist\.py
|
|
115
|
+
| scripts\/update_readme\.py
|
|
113
116
|
)$
|
|
114
117
|
'''
|
|
115
118
|
|
docsig-0.52.0/docsig/_display.py
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
docsig._display
|
|
3
|
-
===============
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
from __future__ import annotations as _
|
|
7
|
-
|
|
8
|
-
import sys as _sys
|
|
9
|
-
import typing as _t
|
|
10
|
-
from collections import UserString as _UserString
|
|
11
|
-
|
|
12
|
-
import click as _click
|
|
13
|
-
from pygments import highlight as _highlight
|
|
14
|
-
from pygments.formatters.terminal256 import (
|
|
15
|
-
Terminal256Formatter as _Terminal256Formatter,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
# noinspection PyUnresolvedReferences
|
|
19
|
-
from pygments.lexers.python import PythonLexer as _PythonLexer
|
|
20
|
-
|
|
21
|
-
from ._module import Function as _Function
|
|
22
|
-
from ._report import Report as _Report
|
|
23
|
-
from ._stub import ARG as _ARG
|
|
24
|
-
from ._stub import KEY as _KEY
|
|
25
|
-
from ._stub import Param as _Param
|
|
26
|
-
|
|
27
|
-
TAB = " "
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def syntax(obj: _t.Any) -> str:
|
|
31
|
-
"""Get code representation with syntax highlighting.
|
|
32
|
-
|
|
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()
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
class FuncStr(_UserString):
|
|
42
|
-
"""String representation for function.
|
|
43
|
-
|
|
44
|
-
:param func: Represents a function with signature and docstring
|
|
45
|
-
parameters.
|
|
46
|
-
"""
|
|
47
|
-
|
|
48
|
-
CHECK = "\u2713"
|
|
49
|
-
CROSS = "\u2716"
|
|
50
|
-
TRIPLE_QUOTES = '"""'
|
|
51
|
-
|
|
52
|
-
def __init__(self, func: _Function) -> None:
|
|
53
|
-
super().__init__(func.name)
|
|
54
|
-
self._parent_name = func.parent.name
|
|
55
|
-
self._isinit = func.isinit
|
|
56
|
-
self.data = ""
|
|
57
|
-
self._is_string = func.docstring.string is not None
|
|
58
|
-
if self._isinit:
|
|
59
|
-
self.data += TAB
|
|
60
|
-
|
|
61
|
-
self.data += syntax(f"def {func.name}(")
|
|
62
|
-
if self._is_string:
|
|
63
|
-
self._docstring = syntax(f"{TAB}{self.TRIPLE_QUOTES}")
|
|
64
|
-
else:
|
|
65
|
-
self._docstring = f"{TAB}{_click.style('...', fg='red')}\n"
|
|
66
|
-
|
|
67
|
-
self._mark = _click.style(self.CHECK, fg="green")
|
|
68
|
-
for index in range(len(func)):
|
|
69
|
-
arg = func.signature.args.get(index)
|
|
70
|
-
doc = func.docstring.args.get(index)
|
|
71
|
-
self.add_param(arg, doc, arg != doc)
|
|
72
|
-
if index + 1 != len(func):
|
|
73
|
-
self.add_comma()
|
|
74
|
-
|
|
75
|
-
self.set_mark()
|
|
76
|
-
if func.docstring.returns and func.signature.returns:
|
|
77
|
-
self.add_return()
|
|
78
|
-
elif (
|
|
79
|
-
func.docstring.returns
|
|
80
|
-
and not func.signature.returns
|
|
81
|
-
or func.signature.returns
|
|
82
|
-
and not func.docstring.returns
|
|
83
|
-
):
|
|
84
|
-
self.add_return(failed=True)
|
|
85
|
-
|
|
86
|
-
self.close_sig(func.signature.rettype)
|
|
87
|
-
self.close_docstring()
|
|
88
|
-
self.render()
|
|
89
|
-
|
|
90
|
-
def _cat_docstring(self, string: str) -> None:
|
|
91
|
-
if self._is_string:
|
|
92
|
-
self._docstring += string
|
|
93
|
-
|
|
94
|
-
def set_mark(self, failed: bool = False) -> None:
|
|
95
|
-
"""Set mark to a cross or a check.
|
|
96
|
-
|
|
97
|
-
:param failed: Boolean to test that check failed.
|
|
98
|
-
"""
|
|
99
|
-
self._mark = (
|
|
100
|
-
_click.style(self.CROSS, fg="red")
|
|
101
|
-
if failed
|
|
102
|
-
else _click.style(self.CHECK, fg="green")
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
def add_param(
|
|
106
|
-
self, sig: _Param, doc: _Param, failed: bool = False
|
|
107
|
-
) -> None:
|
|
108
|
-
"""Add parameters to docstring.
|
|
109
|
-
|
|
110
|
-
:param sig: Signature argument.
|
|
111
|
-
:param doc: Docstring argument.
|
|
112
|
-
:param failed: Boolean to test that check failed.
|
|
113
|
-
"""
|
|
114
|
-
self.set_mark(failed)
|
|
115
|
-
sig_name = sig.name
|
|
116
|
-
if sig.kind == _KEY:
|
|
117
|
-
sig_name = f"**{sig_name}"
|
|
118
|
-
|
|
119
|
-
if sig.kind == _ARG:
|
|
120
|
-
sig_name = f"*{sig_name}"
|
|
121
|
-
|
|
122
|
-
self.data += f"{self._mark}{sig_name}"
|
|
123
|
-
doc_name = doc.name
|
|
124
|
-
if doc.kind == _KEY:
|
|
125
|
-
doc_name = "(**)"
|
|
126
|
-
|
|
127
|
-
self._cat_docstring(f"\n{TAB}:{doc.kind} {doc_name}: {self._mark}")
|
|
128
|
-
|
|
129
|
-
def add_return(self, failed: bool = False) -> None:
|
|
130
|
-
"""Add return statement to docstring.
|
|
131
|
-
|
|
132
|
-
:param failed: Boolean to test that check failed.
|
|
133
|
-
"""
|
|
134
|
-
self.set_mark(failed)
|
|
135
|
-
self._cat_docstring(f"\n{TAB}:return: {self._mark}")
|
|
136
|
-
|
|
137
|
-
def close_sig(self, arg: str | None) -> None:
|
|
138
|
-
"""Close function signature.
|
|
139
|
-
|
|
140
|
-
:param arg: Signature argument.
|
|
141
|
-
"""
|
|
142
|
-
if arg is not None:
|
|
143
|
-
self.data += f"{syntax(') -> ')}{self._mark}{arg}{syntax(':')}"
|
|
144
|
-
else:
|
|
145
|
-
self.data += "{}{}{}".format(
|
|
146
|
-
syntax(")"),
|
|
147
|
-
_click.style("?", fg="red"),
|
|
148
|
-
syntax(":"),
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
def add_comma(self) -> None:
|
|
152
|
-
"""Add comma between parenthesis."""
|
|
153
|
-
self.data += syntax(", ")
|
|
154
|
-
|
|
155
|
-
def close_docstring(self) -> None:
|
|
156
|
-
"""Close docstring."""
|
|
157
|
-
self._cat_docstring(f"\n{TAB}{syntax(self.TRIPLE_QUOTES)}\n")
|
|
158
|
-
|
|
159
|
-
def render(self) -> None:
|
|
160
|
-
"""Render final string by adding docstring to function."""
|
|
161
|
-
if self._isinit:
|
|
162
|
-
self.data = (
|
|
163
|
-
syntax(f"class {self._parent_name}:")
|
|
164
|
-
+ f"\n{self._docstring}"
|
|
165
|
-
+ f"\n{self.data}\n"
|
|
166
|
-
)
|
|
167
|
-
else:
|
|
168
|
-
self.data += f"\n{self._docstring}"
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class Failure(_t.NamedTuple):
|
|
172
|
-
"""Failed function data."""
|
|
173
|
-
|
|
174
|
-
func: _Function
|
|
175
|
-
func_str: FuncStr
|
|
176
|
-
report: _Report
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
class Failures(_t.List[Failure]):
|
|
180
|
-
"""Sequence of failed functions."""
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
class Display(_t.Dict[str, _t.List[Failures]]):
|
|
184
|
-
"""Collect and display report.
|
|
185
|
-
|
|
186
|
-
:param no_ansi: Disable ANSI output.
|
|
187
|
-
"""
|
|
188
|
-
|
|
189
|
-
def __init__(self, no_ansi: bool = False) -> None:
|
|
190
|
-
super().__init__()
|
|
191
|
-
self._ansi = not no_ansi and _sys.stdout.isatty()
|
|
192
|
-
|
|
193
|
-
def __getitem__(self, key: str) -> list[Failures]:
|
|
194
|
-
if key not in super().__iter__():
|
|
195
|
-
super().__setitem__(key, [])
|
|
196
|
-
|
|
197
|
-
return super().__getitem__(key)
|
|
198
|
-
|
|
199
|
-
def report(self) -> None:
|
|
200
|
-
"""Display report if any checks have failed."""
|
|
201
|
-
for key, value in self.items():
|
|
202
|
-
for failures in value:
|
|
203
|
-
for failure in failures:
|
|
204
|
-
header = f"{key}{failure.func.lineno}"
|
|
205
|
-
if failure.func.parent.name:
|
|
206
|
-
header += f" in {failure.func.parent.name}"
|
|
207
|
-
|
|
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)
|
|
214
|
-
|
|
215
|
-
def summarise(self) -> None:
|
|
216
|
-
"""Display report summary if any checks have failed."""
|
|
217
|
-
for key, value in self.items():
|
|
218
|
-
for failures in value:
|
|
219
|
-
for failure in failures:
|
|
220
|
-
header = f"{key}{failure.func.lineno}"
|
|
221
|
-
function = failure.func.name
|
|
222
|
-
if failure.func.parent.name:
|
|
223
|
-
function = f"{failure.func.parent.name}.{function}"
|
|
224
|
-
|
|
225
|
-
header += f" in {function}"
|
|
226
|
-
_click.echo(
|
|
227
|
-
"{}\n {}".format(
|
|
228
|
-
_click.style(header, fg="magenta"),
|
|
229
|
-
failure.report.get_report(" ").strip(),
|
|
230
|
-
),
|
|
231
|
-
color=self._ansi,
|
|
232
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|