docsig 0.52.0__tar.gz → 0.53.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.52.0 → docsig-0.53.1}/PKG-INFO +14 -22
- {docsig-0.52.0 → docsig-0.53.1}/README.rst +13 -20
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_config.py +15 -8
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_core.py +36 -33
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_decorators.py +23 -0
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_main.py +2 -1
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_module.py +8 -2
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_report.py +61 -15
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_stub.py +72 -52
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_version.py +1 -1
- {docsig-0.52.0 → docsig-0.53.1}/docsig/messages.py +1 -0
- {docsig-0.52.0 → docsig-0.53.1}/pyproject.toml +7 -4
- docsig-0.52.0/docsig/_display.py +0 -232
- {docsig-0.52.0 → docsig-0.53.1}/LICENSE +0 -0
- {docsig-0.52.0 → docsig-0.53.1}/docsig/__init__.py +0 -0
- {docsig-0.52.0 → docsig-0.53.1}/docsig/__main__.py +0 -0
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_directives.py +0 -0
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_hooks.py +0 -0
- {docsig-0.52.0 → docsig-0.53.1}/docsig/_utils.py +0 -0
- {docsig-0.52.0 → docsig-0.53.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.53.1
|
|
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,11 +121,10 @@ 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
|
|
@@ -136,28 +133,24 @@ Commandline
|
|
|
136
133
|
documented
|
|
137
134
|
-a, --ignore-args ignore args prefixed with an asterisk
|
|
138
135
|
-k, --ignore-kwargs ignore kwargs prefixed with two asterisks
|
|
139
|
-
-
|
|
140
|
-
|
|
136
|
+
-T, --ignore-typechecker ignore checking return values
|
|
137
|
+
-I, --include-ignored check files even if they match a gitignore pattern
|
|
141
138
|
-n, --no-ansi disable ansi output
|
|
142
|
-
-S, --summary print a summarised report
|
|
143
139
|
-v, --verbose increase output verbosity
|
|
144
140
|
-s STR, --string STR string to parse instead of files
|
|
145
141
|
-d LIST, --disable LIST comma separated list of rules to disable
|
|
146
142
|
-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
|
-
|
|
143
|
+
-e PATTERN, --exclude PATTERN regular expression of files or dirs to exclude from
|
|
144
|
+
checks
|
|
149
145
|
|
|
150
146
|
Options can also be configured with the pyproject.toml file
|
|
151
147
|
|
|
152
|
-
If you find the output is too verbose then the report can be configured to display a summary
|
|
153
|
-
|
|
154
148
|
.. code-block:: toml
|
|
155
149
|
|
|
156
150
|
[tool.docsig]
|
|
157
151
|
check-dunders = false
|
|
158
152
|
check-overridden = false
|
|
159
153
|
check-protected = false
|
|
160
|
-
summary = true
|
|
161
154
|
disable = [
|
|
162
155
|
"E101",
|
|
163
156
|
"E102",
|
|
@@ -187,7 +180,7 @@ API
|
|
|
187
180
|
... :param param3: About param3.
|
|
188
181
|
... '''
|
|
189
182
|
... """
|
|
190
|
-
>>> docsig(string=string,
|
|
183
|
+
>>> docsig(string=string, no_ansi=True)
|
|
191
184
|
0
|
|
192
185
|
|
|
193
186
|
.. code-block:: python
|
|
@@ -201,7 +194,7 @@ API
|
|
|
201
194
|
... :param param3: About param3.
|
|
202
195
|
... '''
|
|
203
196
|
... """
|
|
204
|
-
>>> docsig(string=string,
|
|
197
|
+
>>> docsig(string=string, no_ansi=True)
|
|
205
198
|
2 in function
|
|
206
199
|
E102: includes parameters that do not exist (params-do-not-exist)
|
|
207
200
|
1
|
|
@@ -229,7 +222,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
229
222
|
|
|
230
223
|
repos:
|
|
231
224
|
- repo: https://github.com/jshwi/docsig
|
|
232
|
-
rev: v0.
|
|
225
|
+
rev: v0.53.1
|
|
233
226
|
hooks:
|
|
234
227
|
- id: docsig
|
|
235
228
|
args:
|
|
@@ -237,5 +230,4 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
237
230
|
- "--check-dunders"
|
|
238
231
|
- "--check-overridden"
|
|
239
232
|
- "--check-protected"
|
|
240
|
-
- "--summary"
|
|
241
233
|
|
|
@@ -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,11 +93,10 @@ 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
|
|
@@ -107,28 +105,24 @@ Commandline
|
|
|
107
105
|
documented
|
|
108
106
|
-a, --ignore-args ignore args prefixed with an asterisk
|
|
109
107
|
-k, --ignore-kwargs ignore kwargs prefixed with two asterisks
|
|
110
|
-
-
|
|
111
|
-
|
|
108
|
+
-T, --ignore-typechecker ignore checking return values
|
|
109
|
+
-I, --include-ignored check files even if they match a gitignore pattern
|
|
112
110
|
-n, --no-ansi disable ansi output
|
|
113
|
-
-S, --summary print a summarised report
|
|
114
111
|
-v, --verbose increase output verbosity
|
|
115
112
|
-s STR, --string STR string to parse instead of files
|
|
116
113
|
-d LIST, --disable LIST comma separated list of rules to disable
|
|
117
114
|
-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
|
-
|
|
115
|
+
-e PATTERN, --exclude PATTERN regular expression of files or dirs to exclude from
|
|
116
|
+
checks
|
|
120
117
|
|
|
121
118
|
Options can also be configured with the pyproject.toml file
|
|
122
119
|
|
|
123
|
-
If you find the output is too verbose then the report can be configured to display a summary
|
|
124
|
-
|
|
125
120
|
.. code-block:: toml
|
|
126
121
|
|
|
127
122
|
[tool.docsig]
|
|
128
123
|
check-dunders = false
|
|
129
124
|
check-overridden = false
|
|
130
125
|
check-protected = false
|
|
131
|
-
summary = true
|
|
132
126
|
disable = [
|
|
133
127
|
"E101",
|
|
134
128
|
"E102",
|
|
@@ -158,7 +152,7 @@ API
|
|
|
158
152
|
... :param param3: About param3.
|
|
159
153
|
... '''
|
|
160
154
|
... """
|
|
161
|
-
>>> docsig(string=string,
|
|
155
|
+
>>> docsig(string=string, no_ansi=True)
|
|
162
156
|
0
|
|
163
157
|
|
|
164
158
|
.. code-block:: python
|
|
@@ -172,7 +166,7 @@ API
|
|
|
172
166
|
... :param param3: About param3.
|
|
173
167
|
... '''
|
|
174
168
|
... """
|
|
175
|
-
>>> docsig(string=string,
|
|
169
|
+
>>> docsig(string=string, no_ansi=True)
|
|
176
170
|
2 in function
|
|
177
171
|
E102: includes parameters that do not exist (params-do-not-exist)
|
|
178
172
|
1
|
|
@@ -200,7 +194,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
200
194
|
|
|
201
195
|
repos:
|
|
202
196
|
- repo: https://github.com/jshwi/docsig
|
|
203
|
-
rev: v0.
|
|
197
|
+
rev: v0.53.1
|
|
204
198
|
hooks:
|
|
205
199
|
- id: docsig
|
|
206
200
|
args:
|
|
@@ -208,4 +202,3 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
208
202
|
- "--check-dunders"
|
|
209
203
|
- "--check-overridden"
|
|
210
204
|
- "--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
|
|
@@ -151,7 +152,12 @@ class Parent(_t.List["Parent"]):
|
|
|
151
152
|
self._imports,
|
|
152
153
|
)
|
|
153
154
|
if func.isoverloaded:
|
|
154
|
-
|
|
155
|
+
if (
|
|
156
|
+
func.name not in self._overloads
|
|
157
|
+
or self._overloads[func.name].signature.rettype
|
|
158
|
+
== _RetType.NONE
|
|
159
|
+
):
|
|
160
|
+
self._overloads[func.name] = func
|
|
155
161
|
else:
|
|
156
162
|
if func.name in self._overloads:
|
|
157
163
|
func.overload(
|
|
@@ -356,7 +362,7 @@ class Function(Parent):
|
|
|
356
362
|
"""Comments, if any, belonging to this function."""
|
|
357
363
|
return self._comments
|
|
358
364
|
|
|
359
|
-
def overload(self, rettype:
|
|
365
|
+
def overload(self, rettype: _RetType) -> None:
|
|
360
366
|
"""Overload function with new signature return type.
|
|
361
367
|
|
|
362
368
|
: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.1"
|
|
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
|