docsig 0.53.0__tar.gz → 0.53.2__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.53.0 → docsig-0.53.2}/PKG-INFO +8 -7
- {docsig-0.53.0 → docsig-0.53.2}/README.rst +7 -6
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_module.py +6 -1
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_report.py +40 -7
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_stub.py +44 -6
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_version.py +1 -1
- {docsig-0.53.0 → docsig-0.53.2}/pyproject.toml +8 -6
- {docsig-0.53.0 → docsig-0.53.2}/LICENSE +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/__init__.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/__main__.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_config.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_core.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_decorators.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_directives.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_hooks.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_main.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/_utils.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/messages.py +0 -0
- {docsig-0.53.0 → docsig-0.53.2}/docsig/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: docsig
|
|
3
|
-
Version: 0.53.
|
|
3
|
+
Version: 0.53.2
|
|
4
4
|
Summary: Check signature params for proper documentation
|
|
5
5
|
Home-page: https://pypi.org/project/docsig/
|
|
6
6
|
License: MIT
|
|
@@ -90,7 +90,7 @@ Supports reStructuredText (``Sphinx``), ``NumPy``, and ``Google``
|
|
|
90
90
|
|
|
91
91
|
Contributing
|
|
92
92
|
------------
|
|
93
|
-
If you are interested in contributing to ``docsig`` please read about contributing `here <https://
|
|
93
|
+
If you are interested in contributing to ``docsig`` please read about contributing `here <https://docsig.readthedocs.io/en/latest/development/contributing.html>`__
|
|
94
94
|
|
|
95
95
|
Installation
|
|
96
96
|
------------
|
|
@@ -129,7 +129,8 @@ Commandline
|
|
|
129
129
|
-o, --check-overridden check overridden methods
|
|
130
130
|
-p, --check-protected check protected functions and classes
|
|
131
131
|
-P, --check-property-returns check property return values
|
|
132
|
-
-i, --ignore-no-params ignore docstrings where parameters are not
|
|
132
|
+
-i, --ignore-no-params ignore docstrings where parameters are not
|
|
133
|
+
documented
|
|
133
134
|
-a, --ignore-args ignore args prefixed with an asterisk
|
|
134
135
|
-k, --ignore-kwargs ignore kwargs prefixed with two asterisks
|
|
135
136
|
-T, --ignore-typechecker ignore checking return values
|
|
@@ -198,17 +199,17 @@ API
|
|
|
198
199
|
E102: includes parameters that do not exist (params-do-not-exist)
|
|
199
200
|
1
|
|
200
201
|
|
|
201
|
-
A full list of checks can be found `here <https://docsig.readthedocs.io/en/latest/
|
|
202
|
+
A full list of checks can be found `here <https://docsig.readthedocs.io/en/latest/usage/messages.html>`__
|
|
202
203
|
|
|
203
204
|
Message Control
|
|
204
205
|
***************
|
|
205
206
|
|
|
206
|
-
`Documentation on message control <https://
|
|
207
|
+
`Documentation on message control <https://docsig.readthedocs.io/en/latest/usage/message-control.html>`_
|
|
207
208
|
|
|
208
209
|
Classes
|
|
209
210
|
*******
|
|
210
211
|
|
|
211
|
-
`Documenting classes <https://
|
|
212
|
+
`Documenting classes <https://docsig.readthedocs.io/en/latest/usage/configuration.html#classes>`_
|
|
212
213
|
|
|
213
214
|
pre-commit
|
|
214
215
|
**********
|
|
@@ -221,7 +222,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
221
222
|
|
|
222
223
|
repos:
|
|
223
224
|
- repo: https://github.com/jshwi/docsig
|
|
224
|
-
rev: v0.53.
|
|
225
|
+
rev: v0.53.2
|
|
225
226
|
hooks:
|
|
226
227
|
- id: docsig
|
|
227
228
|
args:
|
|
@@ -62,7 +62,7 @@ Supports reStructuredText (``Sphinx``), ``NumPy``, and ``Google``
|
|
|
62
62
|
|
|
63
63
|
Contributing
|
|
64
64
|
------------
|
|
65
|
-
If you are interested in contributing to ``docsig`` please read about contributing `here <https://
|
|
65
|
+
If you are interested in contributing to ``docsig`` please read about contributing `here <https://docsig.readthedocs.io/en/latest/development/contributing.html>`__
|
|
66
66
|
|
|
67
67
|
Installation
|
|
68
68
|
------------
|
|
@@ -101,7 +101,8 @@ Commandline
|
|
|
101
101
|
-o, --check-overridden check overridden methods
|
|
102
102
|
-p, --check-protected check protected functions and classes
|
|
103
103
|
-P, --check-property-returns check property return values
|
|
104
|
-
-i, --ignore-no-params ignore docstrings where parameters are not
|
|
104
|
+
-i, --ignore-no-params ignore docstrings where parameters are not
|
|
105
|
+
documented
|
|
105
106
|
-a, --ignore-args ignore args prefixed with an asterisk
|
|
106
107
|
-k, --ignore-kwargs ignore kwargs prefixed with two asterisks
|
|
107
108
|
-T, --ignore-typechecker ignore checking return values
|
|
@@ -170,17 +171,17 @@ API
|
|
|
170
171
|
E102: includes parameters that do not exist (params-do-not-exist)
|
|
171
172
|
1
|
|
172
173
|
|
|
173
|
-
A full list of checks can be found `here <https://docsig.readthedocs.io/en/latest/
|
|
174
|
+
A full list of checks can be found `here <https://docsig.readthedocs.io/en/latest/usage/messages.html>`__
|
|
174
175
|
|
|
175
176
|
Message Control
|
|
176
177
|
***************
|
|
177
178
|
|
|
178
|
-
`Documentation on message control <https://
|
|
179
|
+
`Documentation on message control <https://docsig.readthedocs.io/en/latest/usage/message-control.html>`_
|
|
179
180
|
|
|
180
181
|
Classes
|
|
181
182
|
*******
|
|
182
183
|
|
|
183
|
-
`Documenting classes <https://
|
|
184
|
+
`Documenting classes <https://docsig.readthedocs.io/en/latest/usage/configuration.html#classes>`_
|
|
184
185
|
|
|
185
186
|
pre-commit
|
|
186
187
|
**********
|
|
@@ -193,7 +194,7 @@ It can be added to your .pre-commit-config.yaml as follows:
|
|
|
193
194
|
|
|
194
195
|
repos:
|
|
195
196
|
- repo: https://github.com/jshwi/docsig
|
|
196
|
-
rev: v0.53.
|
|
197
|
+
rev: v0.53.2
|
|
197
198
|
hooks:
|
|
198
199
|
- id: docsig
|
|
199
200
|
args:
|
|
@@ -152,7 +152,12 @@ class Parent(_t.List["Parent"]):
|
|
|
152
152
|
self._imports,
|
|
153
153
|
)
|
|
154
154
|
if func.isoverloaded:
|
|
155
|
-
|
|
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
|
|
156
161
|
else:
|
|
157
162
|
if func.name in self._overloads:
|
|
158
163
|
func.overload(
|
|
@@ -11,6 +11,7 @@ import typing as _t
|
|
|
11
11
|
import click as _click
|
|
12
12
|
|
|
13
13
|
from ._module import Function as _Function
|
|
14
|
+
from ._stub import UNNAMED as _UNNAMED
|
|
14
15
|
from ._stub import Param as _Param
|
|
15
16
|
from ._stub import RetType as _RetType
|
|
16
17
|
from ._utils import almost_equal as _almost_equal
|
|
@@ -65,10 +66,14 @@ class Failure(_t.List[str]):
|
|
|
65
66
|
self._missing_class_docstring()
|
|
66
67
|
self._missing_func_docstring()
|
|
67
68
|
if func.docstring.string is not None:
|
|
68
|
-
|
|
69
|
+
# make sure these come first as they alter the function
|
|
70
|
+
# docstring object before it is analysed further
|
|
71
|
+
self._duplicates()
|
|
69
72
|
self._exists()
|
|
73
|
+
|
|
74
|
+
# all further analysis below
|
|
75
|
+
self._return_not_typed()
|
|
70
76
|
self._missing()
|
|
71
|
-
self._duplicates()
|
|
72
77
|
self._extra_return()
|
|
73
78
|
self._missing_return()
|
|
74
79
|
self._property_return()
|
|
@@ -78,9 +83,9 @@ class Failure(_t.List[str]):
|
|
|
78
83
|
doc = func.docstring.args.get(index)
|
|
79
84
|
self._description_syntax(doc)
|
|
80
85
|
self._indent_syntax(doc)
|
|
86
|
+
self._incorrect(doc)
|
|
81
87
|
if arg != doc:
|
|
82
88
|
self._order(arg, doc)
|
|
83
|
-
self._incorrect(arg, doc)
|
|
84
89
|
self._misspelled(arg, doc)
|
|
85
90
|
self._not_equal(arg, doc)
|
|
86
91
|
|
|
@@ -105,7 +110,16 @@ class Failure(_t.List[str]):
|
|
|
105
110
|
self._add(_E[101])
|
|
106
111
|
|
|
107
112
|
def _exists(self) -> None:
|
|
113
|
+
# pop the parameters that do not exist so that they are excluded
|
|
114
|
+
# from further analysis, that way there are no additional, and
|
|
115
|
+
# redundant, errors
|
|
116
|
+
# this will ensure that both signature and docstring are equal
|
|
117
|
+
# in length, with all parameters that do not exist accounted for
|
|
108
118
|
if len(self._func.docstring.args) > len(self._func.signature.args):
|
|
119
|
+
for count, __ in enumerate(self._func.docstring.args, 1):
|
|
120
|
+
if count > len(self._func.signature.args):
|
|
121
|
+
self._func.docstring.args.pop(count - 1)
|
|
122
|
+
|
|
109
123
|
self._add(_E[102])
|
|
110
124
|
|
|
111
125
|
def _missing_func_docstring(self) -> None:
|
|
@@ -121,7 +135,14 @@ class Failure(_t.List[str]):
|
|
|
121
135
|
self._add(_E[103])
|
|
122
136
|
|
|
123
137
|
def _duplicates(self) -> None:
|
|
138
|
+
# pop the duplicates so that they are considered a single
|
|
139
|
+
# parameter, that way there are no assumptions that the
|
|
140
|
+
# parameters must be out of order
|
|
124
141
|
if self._func.docstring.args.duplicated:
|
|
142
|
+
for count, arg in enumerate(self._func.docstring.args):
|
|
143
|
+
if arg in self._func.docstring.args.duplicates:
|
|
144
|
+
self._func.docstring.args.pop(count)
|
|
145
|
+
|
|
125
146
|
self._add(_E[106])
|
|
126
147
|
|
|
127
148
|
def _extra_return(self) -> None:
|
|
@@ -151,13 +172,25 @@ class Failure(_t.List[str]):
|
|
|
151
172
|
and not self._no_returns
|
|
152
173
|
):
|
|
153
174
|
docstring = self._func.docstring.string
|
|
154
|
-
|
|
155
|
-
|
|
175
|
+
# do more than just search the docstring for the word return
|
|
176
|
+
# as return statements come last, so only search the last
|
|
177
|
+
# line
|
|
178
|
+
# params can also come last, so make sure it is not a param
|
|
179
|
+
# declaration
|
|
180
|
+
if docstring is not None:
|
|
181
|
+
lines = docstring.splitlines()
|
|
182
|
+
if len(lines) > 1:
|
|
183
|
+
if "return" in lines[-1] and ":param" not in lines[-1]:
|
|
184
|
+
hint = True
|
|
156
185
|
|
|
157
186
|
self._add(_E[105], hint=hint)
|
|
158
187
|
|
|
159
|
-
def _incorrect(self,
|
|
160
|
-
if
|
|
188
|
+
def _incorrect(self, doc: _Param) -> None:
|
|
189
|
+
# if the parameter does not have a name, but exists, then it
|
|
190
|
+
# must be incorrectly documented
|
|
191
|
+
# prior implementation relied on the docstring parameter
|
|
192
|
+
# equalling the signature parameter
|
|
193
|
+
if doc.name == _UNNAMED:
|
|
161
194
|
self._add(_E[107])
|
|
162
195
|
|
|
163
196
|
# final catch-all
|
|
@@ -14,6 +14,9 @@ from enum import Enum as _Enum
|
|
|
14
14
|
import astroid as _ast
|
|
15
15
|
import sphinx.ext.napoleon as _s
|
|
16
16
|
|
|
17
|
+
# no function will accidentally have this name
|
|
18
|
+
UNNAMED = -1000
|
|
19
|
+
|
|
17
20
|
|
|
18
21
|
# noinspection PyTypeChecker
|
|
19
22
|
class _GoogleDocstring(str):
|
|
@@ -131,19 +134,22 @@ class Param(_t.NamedTuple):
|
|
|
131
134
|
class _Matches(_t.List[Param]):
|
|
132
135
|
_pattern = _re.compile(":(.*?):")
|
|
133
136
|
|
|
134
|
-
def __init__(self, string: str) -> None:
|
|
137
|
+
def __init__(self, string: str, indent_anomaly: bool) -> None:
|
|
135
138
|
super().__init__()
|
|
136
139
|
for line in string.splitlines():
|
|
137
140
|
strip_line = line.lstrip()
|
|
138
141
|
match = self._pattern.split(strip_line)[1:]
|
|
139
142
|
if match:
|
|
140
|
-
|
|
143
|
+
description = None
|
|
141
144
|
kinds = match[0].split()
|
|
142
145
|
if kinds:
|
|
143
146
|
kind = DocType.from_str(kinds[0])
|
|
144
147
|
|
|
145
148
|
if len(kinds) > 1:
|
|
146
149
|
name = kinds[1]
|
|
150
|
+
else:
|
|
151
|
+
# name could not be parsed
|
|
152
|
+
name = UNNAMED
|
|
147
153
|
|
|
148
154
|
if len(match) > 1:
|
|
149
155
|
description = match[1]
|
|
@@ -153,7 +159,7 @@ class _Matches(_t.List[Param]):
|
|
|
153
159
|
kind,
|
|
154
160
|
name,
|
|
155
161
|
description,
|
|
156
|
-
|
|
162
|
+
int(indent_anomaly),
|
|
157
163
|
)
|
|
158
164
|
)
|
|
159
165
|
|
|
@@ -165,6 +171,7 @@ class _Params(_t.List[Param]):
|
|
|
165
171
|
super().__init__()
|
|
166
172
|
self._ignore_args = ignore_args
|
|
167
173
|
self._ignore_kwargs = ignore_kwargs
|
|
174
|
+
self._duplicates: list[Param] = []
|
|
168
175
|
|
|
169
176
|
# pylint: disable=too-many-boolean-expressions
|
|
170
177
|
def append(self, value: Param) -> None:
|
|
@@ -195,8 +202,26 @@ class _Params(_t.List[Param]):
|
|
|
195
202
|
|
|
196
203
|
@property
|
|
197
204
|
def duplicated(self) -> bool:
|
|
198
|
-
"""Boolean value for whether there are duplicate parameters.
|
|
199
|
-
|
|
205
|
+
"""Boolean value for whether there are duplicate parameters.
|
|
206
|
+
|
|
207
|
+
Ensure only the names of the parameters are needed to be
|
|
208
|
+
considered duplicates. It is not relevant whether the
|
|
209
|
+
descriptions match.
|
|
210
|
+
"""
|
|
211
|
+
for k, v in _Counter(i.name for i in self).items():
|
|
212
|
+
if v > 1:
|
|
213
|
+
for i in self:
|
|
214
|
+
if i.name == k:
|
|
215
|
+
# record the duplicates for later analysis
|
|
216
|
+
self._duplicates.append(i)
|
|
217
|
+
return True
|
|
218
|
+
|
|
219
|
+
return False
|
|
220
|
+
|
|
221
|
+
@property
|
|
222
|
+
def duplicates(self) -> list[Param]:
|
|
223
|
+
"""Duplicated parameters."""
|
|
224
|
+
return self._duplicates
|
|
200
225
|
|
|
201
226
|
|
|
202
227
|
class _Stub:
|
|
@@ -288,6 +313,19 @@ class Docstring(_Stub):
|
|
|
288
313
|
:param ignore_kwargs: Ignore kwargs prefixed with two asterisks.
|
|
289
314
|
"""
|
|
290
315
|
|
|
316
|
+
@staticmethod
|
|
317
|
+
def _indent_anomaly(string: str) -> bool:
|
|
318
|
+
leading_spaces = []
|
|
319
|
+
for line in string.splitlines():
|
|
320
|
+
match = _re.match(r"^\s*", line)
|
|
321
|
+
if match is not None:
|
|
322
|
+
spaces = len(match.group())
|
|
323
|
+
if spaces > 0:
|
|
324
|
+
leading_spaces.append(spaces)
|
|
325
|
+
|
|
326
|
+
# look for spaces in odd intervals
|
|
327
|
+
return bool(any(i % 2 != 0 for i in leading_spaces))
|
|
328
|
+
|
|
291
329
|
def __init__(
|
|
292
330
|
self,
|
|
293
331
|
node: _ast.Const | None = None,
|
|
@@ -298,7 +336,7 @@ class Docstring(_Stub):
|
|
|
298
336
|
self._string = None
|
|
299
337
|
if node is not None:
|
|
300
338
|
self._string = _RawDocstring(node.value)
|
|
301
|
-
for i in _Matches(self._string):
|
|
339
|
+
for i in _Matches(self._string, self._indent_anomaly(node.value)):
|
|
302
340
|
self._args.append(i)
|
|
303
341
|
|
|
304
342
|
self._returns = self._string is not None and bool(
|
|
@@ -27,6 +27,7 @@ fail_under = 100
|
|
|
27
27
|
|
|
28
28
|
[tool.coverage.run]
|
|
29
29
|
omit = [
|
|
30
|
+
"docs/conf.py",
|
|
30
31
|
"docsig/__main__.py",
|
|
31
32
|
"whitelist.py"
|
|
32
33
|
]
|
|
@@ -65,7 +66,7 @@ maintainers = [
|
|
|
65
66
|
name = "docsig"
|
|
66
67
|
readme = "README.rst"
|
|
67
68
|
repository = "https://github.com/jshwi/docsig"
|
|
68
|
-
version = "0.53.
|
|
69
|
+
version = "0.53.2"
|
|
69
70
|
|
|
70
71
|
[tool.poetry.dependencies]
|
|
71
72
|
Sphinx = "^7.0.0"
|
|
@@ -78,14 +79,16 @@ python = "^3.8"
|
|
|
78
79
|
[tool.poetry.dev-dependencies]
|
|
79
80
|
bump2version = "^1.0.1"
|
|
80
81
|
deptry = "^0.16.1"
|
|
82
|
+
furo = "^2024.4.27"
|
|
81
83
|
ipython = "^8.12.0"
|
|
84
|
+
myst-parser = "^3.0.1"
|
|
82
85
|
pre-commit = "^3.3.3"
|
|
83
86
|
pyaud = "^7.5.0"
|
|
84
87
|
pytest-randomly = "^3.13.0"
|
|
85
88
|
pytest-sugar = "^1.0.0"
|
|
86
89
|
pytest-xdist = "^3.6.1"
|
|
87
90
|
restview = "^3.0.0"
|
|
88
|
-
sphinx-
|
|
91
|
+
sphinx-copybutton = "^0.5.2"
|
|
89
92
|
sphinx-toolbox = "^3.5.0"
|
|
90
93
|
templatest = "^0.10.1"
|
|
91
94
|
tox = "^4.15.0"
|
|
@@ -95,10 +98,8 @@ docsig = "docsig.__main__:main"
|
|
|
95
98
|
|
|
96
99
|
[tool.pyaud]
|
|
97
100
|
audit = [
|
|
98
|
-
"about-tests",
|
|
99
101
|
"commit-policy",
|
|
100
102
|
"copyright-year",
|
|
101
|
-
"files",
|
|
102
103
|
"format",
|
|
103
104
|
"format-docs",
|
|
104
105
|
"format-str",
|
|
@@ -106,13 +107,14 @@ audit = [
|
|
|
106
107
|
"lint",
|
|
107
108
|
"test",
|
|
108
109
|
"typecheck",
|
|
109
|
-
"unused"
|
|
110
|
+
"unused",
|
|
111
|
+
"whitelist"
|
|
110
112
|
]
|
|
111
113
|
exclude = '''
|
|
112
114
|
(?x)^(
|
|
113
115
|
| docs\/conf\.py
|
|
114
116
|
| whitelist\.py
|
|
115
|
-
| scripts
|
|
117
|
+
| scripts\/.*
|
|
116
118
|
)$
|
|
117
119
|
'''
|
|
118
120
|
|
|
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
|
|
File without changes
|
|
File without changes
|