docsig 0.82.1__tar.gz → 0.82.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.82.1 → docsig-0.82.2}/PKG-INFO +4 -4
- {docsig-0.82.1 → docsig-0.82.2}/README.rst +3 -3
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_module.py +15 -12
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_parsers.py +4 -7
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_report.py +12 -10
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_stub.py +32 -37
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_version.py +1 -1
- {docsig-0.82.1 → docsig-0.82.2}/docsig/messages.py +5 -0
- {docsig-0.82.1 → docsig-0.82.2}/pyproject.toml +3 -3
- {docsig-0.82.1 → docsig-0.82.2}/LICENSE +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/__init__.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/__main__.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_check.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_config.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_core.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_decorators.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_directives.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_files.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_hooks.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_main.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/_utils.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/plugin.py +0 -0
- {docsig-0.82.1 → docsig-0.82.2}/docsig/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docsig
|
|
3
|
-
Version: 0.82.
|
|
3
|
+
Version: 0.82.2
|
|
4
4
|
Summary: Check signature params for proper documentation
|
|
5
5
|
License: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -184,7 +184,7 @@ ensure your installation has registered `docsig`
|
|
|
184
184
|
.. code-block:: console
|
|
185
185
|
|
|
186
186
|
$ flake8 --version
|
|
187
|
-
7.3.0 (docsig: 0.82.
|
|
187
|
+
7.3.0 (docsig: 0.82.2, mccabe: 0.7.0, pycodestyle: 2.14.0, pyflakes: 3.4.0) CPython 3.10.19 on Darwin
|
|
188
188
|
|
|
189
189
|
And now use `flake8` to lint your files
|
|
190
190
|
|
|
@@ -270,7 +270,7 @@ Standalone
|
|
|
270
270
|
|
|
271
271
|
repos:
|
|
272
272
|
- repo: https://github.com/jshwi/docsig
|
|
273
|
-
rev: v0.82.
|
|
273
|
+
rev: v0.82.2
|
|
274
274
|
hooks:
|
|
275
275
|
- id: docsig
|
|
276
276
|
args:
|
|
@@ -289,7 +289,7 @@ or integrated with ``flake8``
|
|
|
289
289
|
hooks:
|
|
290
290
|
- id: flake8
|
|
291
291
|
additional_dependencies:
|
|
292
|
-
- docsig==0.82.
|
|
292
|
+
- docsig==0.82.2
|
|
293
293
|
args:
|
|
294
294
|
- "--sig-check-class"
|
|
295
295
|
- "--sig-check-dunders"
|
|
@@ -155,7 +155,7 @@ ensure your installation has registered `docsig`
|
|
|
155
155
|
.. code-block:: console
|
|
156
156
|
|
|
157
157
|
$ flake8 --version
|
|
158
|
-
7.3.0 (docsig: 0.82.
|
|
158
|
+
7.3.0 (docsig: 0.82.2, mccabe: 0.7.0, pycodestyle: 2.14.0, pyflakes: 3.4.0) CPython 3.10.19 on Darwin
|
|
159
159
|
|
|
160
160
|
And now use `flake8` to lint your files
|
|
161
161
|
|
|
@@ -241,7 +241,7 @@ Standalone
|
|
|
241
241
|
|
|
242
242
|
repos:
|
|
243
243
|
- repo: https://github.com/jshwi/docsig
|
|
244
|
-
rev: v0.82.
|
|
244
|
+
rev: v0.82.2
|
|
245
245
|
hooks:
|
|
246
246
|
- id: docsig
|
|
247
247
|
args:
|
|
@@ -260,7 +260,7 @@ or integrated with ``flake8``
|
|
|
260
260
|
hooks:
|
|
261
261
|
- id: flake8
|
|
262
262
|
additional_dependencies:
|
|
263
|
-
- docsig==0.82.
|
|
263
|
+
- docsig==0.82.2
|
|
264
264
|
args:
|
|
265
265
|
- "--sig-check-class"
|
|
266
266
|
- "--sig-check-dunders"
|
|
@@ -9,7 +9,6 @@ from __future__ import annotations as _
|
|
|
9
9
|
|
|
10
10
|
import re as _re
|
|
11
11
|
import typing as _t
|
|
12
|
-
from enum import Enum as _Enum
|
|
13
12
|
from pathlib import Path as _Path
|
|
14
13
|
|
|
15
14
|
import astroid as _ast
|
|
@@ -32,12 +31,12 @@ class _Overloads(dict[str, "Function"]): ...
|
|
|
32
31
|
class _Children(list[_t.Union["Parent", "Function"]]): ...
|
|
33
32
|
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
ERRORS = (
|
|
35
|
+
_ast.AstroidSyntaxError,
|
|
36
|
+
UnicodeDecodeError,
|
|
37
|
+
RecursionError,
|
|
38
|
+
_ast.DuplicateBasesError,
|
|
39
|
+
)
|
|
41
40
|
|
|
42
41
|
|
|
43
42
|
class Parent: # pylint: disable=too-many-instance-attributes
|
|
@@ -65,7 +64,7 @@ class Parent: # pylint: disable=too-many-instance-attributes
|
|
|
65
64
|
file: _Path | None = None,
|
|
66
65
|
config: _Config | None = None,
|
|
67
66
|
imports: _Imports | None = None,
|
|
68
|
-
error:
|
|
67
|
+
error: type[BaseException] | None = None,
|
|
69
68
|
) -> None:
|
|
70
69
|
super().__init__()
|
|
71
70
|
self._error = error
|
|
@@ -127,14 +126,18 @@ class Parent: # pylint: disable=too-many-instance-attributes
|
|
|
127
126
|
if func.isoverloaded:
|
|
128
127
|
if (
|
|
129
128
|
func.name not in self._overloads
|
|
130
|
-
or self._overloads[
|
|
129
|
+
or self._overloads[
|
|
130
|
+
func.name
|
|
131
|
+
].signature.returns.type
|
|
131
132
|
== _RetType.NONE
|
|
132
133
|
):
|
|
133
134
|
self._overloads[func.name] = func
|
|
134
135
|
else:
|
|
135
136
|
if func.name in self._overloads:
|
|
136
137
|
func.overload(
|
|
137
|
-
self._overloads[
|
|
138
|
+
self._overloads[
|
|
139
|
+
func.name
|
|
140
|
+
].signature.returns.type,
|
|
138
141
|
)
|
|
139
142
|
|
|
140
143
|
self._children.append(func)
|
|
@@ -157,7 +160,7 @@ class Parent: # pylint: disable=too-many-instance-attributes
|
|
|
157
160
|
return self._name.startswith("_")
|
|
158
161
|
|
|
159
162
|
@property
|
|
160
|
-
def error(self) ->
|
|
163
|
+
def error(self) -> type[BaseException] | None:
|
|
161
164
|
"""Unrecoverable error for this scope, if any."""
|
|
162
165
|
return self._error
|
|
163
166
|
|
|
@@ -190,7 +193,7 @@ class Function(Parent): # pylint: disable=too-many-instance-attributes
|
|
|
190
193
|
file: _Path | None = None,
|
|
191
194
|
config: _Config | None = None,
|
|
192
195
|
imports: _Imports | None = None,
|
|
193
|
-
error:
|
|
196
|
+
error: type[BaseException] | None = None,
|
|
194
197
|
) -> None:
|
|
195
198
|
super().__init__(
|
|
196
199
|
node,
|
|
@@ -15,7 +15,7 @@ import astroid as _ast
|
|
|
15
15
|
from ._config import Config as _Config
|
|
16
16
|
from ._directives import Directives as _Directives
|
|
17
17
|
from ._files import FILE_INFO as _FILE_INFO
|
|
18
|
-
from ._module import
|
|
18
|
+
from ._module import ERRORS as _ERRORS
|
|
19
19
|
from ._module import Parent as _Parent
|
|
20
20
|
|
|
21
21
|
|
|
@@ -53,12 +53,9 @@ def parse_from_string(
|
|
|
53
53
|
|
|
54
54
|
parent = _Parent(node, directives, file, config)
|
|
55
55
|
logger.debug(_FILE_INFO, source_name, "Parsing Python code successful")
|
|
56
|
-
except
|
|
56
|
+
except _ERRORS as err:
|
|
57
57
|
logger.debug(_FILE_INFO, source_name, str(err).replace("\n", " "))
|
|
58
|
-
parent = _Parent(error=
|
|
59
|
-
except RecursionError as err:
|
|
60
|
-
logger.debug(_FILE_INFO, source_name, str(err).replace("\n", " "))
|
|
61
|
-
parent = _Parent(error=_Error.RECURSION)
|
|
58
|
+
parent = _Parent(error=type(err))
|
|
62
59
|
|
|
63
60
|
return parent
|
|
64
61
|
|
|
@@ -81,7 +78,7 @@ def parse_from_file(file: _Path, config: _Config) -> _Parent:
|
|
|
81
78
|
except UnicodeDecodeError as err:
|
|
82
79
|
logger = _logging.getLogger(__package__)
|
|
83
80
|
logger.debug(_FILE_INFO, file, str(err).replace("\n", " "))
|
|
84
|
-
parent = _Parent(error=
|
|
81
|
+
parent = _Parent(error=type(err))
|
|
85
82
|
|
|
86
83
|
if parent.error is not None and not file.name.endswith(".py"):
|
|
87
84
|
parent = _Parent()
|
|
@@ -15,10 +15,10 @@ import sys as _sys
|
|
|
15
15
|
import typing as _t
|
|
16
16
|
from warnings import warn as _warn
|
|
17
17
|
|
|
18
|
+
import astroid as _ast
|
|
18
19
|
from astroid.nodes.scoped_nodes import scoped_nodes as _scoped_nodes
|
|
19
20
|
|
|
20
21
|
from ._config import Config as _Config
|
|
21
|
-
from ._module import Error as _Error
|
|
22
22
|
from ._module import Function as _Function
|
|
23
23
|
from ._stub import UNNAMED as _UNNAMED
|
|
24
24
|
from ._stub import VALID_DESCRIPTION as _VALID_DESCRIPTION
|
|
@@ -288,18 +288,18 @@ class Failure(list[Failed]):
|
|
|
288
288
|
self._func.isproperty and not check_property_returns
|
|
289
289
|
):
|
|
290
290
|
# no types, cannot know either way
|
|
291
|
-
if self._func.signature.
|
|
291
|
+
if self._func.signature.returns.type == _RetType.UNTYPED:
|
|
292
292
|
# confirm-return-needed
|
|
293
293
|
self._add(_E[501], hint=True)
|
|
294
294
|
# return-type is none, so no return should be documented
|
|
295
|
-
elif self._func.docstring.returns:
|
|
296
|
-
if self._func.signature.
|
|
295
|
+
elif self._func.docstring.returns.returns:
|
|
296
|
+
if self._func.signature.returns.type == _RetType.NONE:
|
|
297
297
|
# return-documented-for-none
|
|
298
298
|
self._add(_E[502])
|
|
299
|
-
if self._func.docstring.
|
|
299
|
+
if self._func.docstring.returns.description_missing:
|
|
300
300
|
self._add(_E[506])
|
|
301
301
|
# return-type is some, so return should be documented
|
|
302
|
-
elif self._func.signature.returns:
|
|
302
|
+
elif self._func.signature.returns.returns:
|
|
303
303
|
# return-missing
|
|
304
304
|
lines = str(self._func.docstring.string).splitlines()
|
|
305
305
|
self._add(
|
|
@@ -310,7 +310,7 @@ class Failure(list[Failed]):
|
|
|
310
310
|
and ":param" not in lines[-1]
|
|
311
311
|
),
|
|
312
312
|
)
|
|
313
|
-
elif self._func.docstring.returns:
|
|
313
|
+
elif self._func.docstring.returns.returns:
|
|
314
314
|
# this method is init, so no return should be documented
|
|
315
315
|
if self._func.isinit:
|
|
316
316
|
# class-return-documented
|
|
@@ -322,13 +322,15 @@ class Failure(list[Failed]):
|
|
|
322
322
|
|
|
323
323
|
def _sig9xx_error(self) -> None:
|
|
324
324
|
# invalid-syntax
|
|
325
|
-
if self._func.error
|
|
325
|
+
if self._func.error is _ast.AstroidSyntaxError:
|
|
326
326
|
self._add(_E[901])
|
|
327
327
|
self._retcode = 123
|
|
328
|
-
if self._func.error
|
|
328
|
+
if self._func.error is UnicodeDecodeError:
|
|
329
329
|
self._add(_E[902])
|
|
330
|
-
if self._func.error
|
|
330
|
+
if self._func.error is RecursionError:
|
|
331
331
|
self._add(_E[903])
|
|
332
|
+
if self._func.error is _ast.DuplicateBasesError:
|
|
333
|
+
self._add(_E[904])
|
|
332
334
|
|
|
333
335
|
@property
|
|
334
336
|
def name(self) -> str:
|
|
@@ -9,6 +9,7 @@ from __future__ import annotations as _
|
|
|
9
9
|
|
|
10
10
|
import re as _re
|
|
11
11
|
import textwrap as _textwrap
|
|
12
|
+
import typing as _t
|
|
12
13
|
from collections import Counter as _Counter
|
|
13
14
|
from enum import Enum as _Enum
|
|
14
15
|
|
|
@@ -80,8 +81,6 @@ class DocType(_Enum):
|
|
|
80
81
|
return cls.UNKNOWN
|
|
81
82
|
|
|
82
83
|
|
|
83
|
-
# todo: consider a parent object that can be used for returns that do
|
|
84
|
-
# todo: not include the name attribute
|
|
85
84
|
class Param:
|
|
86
85
|
"""Single parameter from a docstring or function signature.
|
|
87
86
|
|
|
@@ -152,6 +151,13 @@ class Param:
|
|
|
152
151
|
return self._closing_token
|
|
153
152
|
|
|
154
153
|
|
|
154
|
+
# single return from a docstring or function signature
|
|
155
|
+
class _Return(_t.NamedTuple):
|
|
156
|
+
returns: bool = False
|
|
157
|
+
type: RetType = RetType.UNTYPED
|
|
158
|
+
description_missing: bool = False
|
|
159
|
+
|
|
160
|
+
|
|
155
161
|
class Params(list[Param]):
|
|
156
162
|
"""A list-like collection of params.
|
|
157
163
|
|
|
@@ -218,9 +224,13 @@ class Params(list[Param]):
|
|
|
218
224
|
|
|
219
225
|
|
|
220
226
|
class _Stub:
|
|
221
|
-
def __init__(
|
|
227
|
+
def __init__(
|
|
228
|
+
self,
|
|
229
|
+
returns: _Return | None = None,
|
|
230
|
+
ignore: _Ignore | None = None,
|
|
231
|
+
) -> None:
|
|
222
232
|
self._args = Params(ignore or _Ignore())
|
|
223
|
-
self._returns =
|
|
233
|
+
self._returns = returns or _Return()
|
|
224
234
|
|
|
225
235
|
@property
|
|
226
236
|
def args(self) -> Params:
|
|
@@ -228,7 +238,7 @@ class _Stub:
|
|
|
228
238
|
return self._args
|
|
229
239
|
|
|
230
240
|
@property
|
|
231
|
-
def returns(self) ->
|
|
241
|
+
def returns(self) -> _Return:
|
|
232
242
|
"""True if a return (or yield) is declared or documented."""
|
|
233
243
|
return self._returns
|
|
234
244
|
|
|
@@ -236,20 +246,16 @@ class _Stub:
|
|
|
236
246
|
class Signature(_Stub):
|
|
237
247
|
"""Parsed function signature (args and return type).
|
|
238
248
|
|
|
239
|
-
:param rettype: Kind of return (none, some, untyped).
|
|
240
249
|
:param returns: True if return is declared in the signature.
|
|
241
250
|
:param ignore: Configuration object for what to ignore.
|
|
242
251
|
"""
|
|
243
252
|
|
|
244
253
|
def __init__(
|
|
245
254
|
self,
|
|
246
|
-
|
|
247
|
-
returns: bool = False,
|
|
255
|
+
returns: _Return | None = None,
|
|
248
256
|
ignore: _Ignore | None = None,
|
|
249
257
|
) -> None:
|
|
250
|
-
super().__init__(ignore or _Ignore())
|
|
251
|
-
self._rettype = rettype
|
|
252
|
-
self._returns = returns
|
|
258
|
+
super().__init__(returns, ignore or _Ignore())
|
|
253
259
|
|
|
254
260
|
@classmethod
|
|
255
261
|
def from_ast(
|
|
@@ -264,8 +270,8 @@ class Signature(_Stub):
|
|
|
264
270
|
:return: Signature with args and return type.
|
|
265
271
|
"""
|
|
266
272
|
rettype = RetType.from_ast(node.returns)
|
|
267
|
-
returns = rettype == RetType.SOME
|
|
268
|
-
signature = cls(
|
|
273
|
+
returns = _Return(rettype == RetType.SOME, rettype)
|
|
274
|
+
signature = cls(returns, ignore)
|
|
269
275
|
# noinspection PyUnresolvedReferences
|
|
270
276
|
for i in [
|
|
271
277
|
a if isinstance(a, Param) else Param(name=a.name)
|
|
@@ -282,18 +288,12 @@ class Signature(_Stub):
|
|
|
282
288
|
|
|
283
289
|
return signature
|
|
284
290
|
|
|
285
|
-
@property
|
|
286
|
-
def rettype(self) -> RetType:
|
|
287
|
-
"""Return annotation kind (none, some, or untyped)."""
|
|
288
|
-
return self._rettype
|
|
289
|
-
|
|
290
291
|
def overload(self, rettype: RetType) -> None:
|
|
291
292
|
"""Set this signature's return type (for overloads).
|
|
292
293
|
|
|
293
294
|
:param rettype: Return type for the overloaded variant.
|
|
294
295
|
"""
|
|
295
|
-
self.
|
|
296
|
-
self._returns = rettype != RetType.NONE
|
|
296
|
+
self._returns = _Return(rettype != RetType.NONE, rettype)
|
|
297
297
|
|
|
298
298
|
|
|
299
299
|
class Docstring(_Stub):
|
|
@@ -301,7 +301,6 @@ class Docstring(_Stub):
|
|
|
301
301
|
|
|
302
302
|
:param string: Raw docstring text after normalization.
|
|
303
303
|
:param returns: True if a return or yield section is present.
|
|
304
|
-
:param ret_description_missing: True if return has no description.
|
|
305
304
|
"""
|
|
306
305
|
|
|
307
306
|
@staticmethod
|
|
@@ -345,13 +344,10 @@ class Docstring(_Stub):
|
|
|
345
344
|
def __init__(
|
|
346
345
|
self,
|
|
347
346
|
string: str | None = None,
|
|
348
|
-
returns:
|
|
349
|
-
ret_description_missing: bool = False,
|
|
347
|
+
returns: _Return | None = None,
|
|
350
348
|
) -> None:
|
|
351
|
-
super().__init__()
|
|
349
|
+
super().__init__(returns)
|
|
352
350
|
self._string = string
|
|
353
|
-
self._returns = returns
|
|
354
|
-
self._ret_description_missing = ret_description_missing
|
|
355
351
|
|
|
356
352
|
@classmethod
|
|
357
353
|
def from_ast(cls, node: _ast.Const) -> Docstring:
|
|
@@ -362,16 +358,16 @@ class Docstring(_Stub):
|
|
|
362
358
|
"""
|
|
363
359
|
indent_anomaly = cls._indent_anomaly(node.value)
|
|
364
360
|
string = cls._normalize_docstring(node.value)
|
|
365
|
-
# todo: we can start building return objects for more detailed
|
|
366
|
-
# todo: checks that are in common with the params class
|
|
367
361
|
match = _re.search(
|
|
368
362
|
r":(?:returns?|yields?):\s*(.*)",
|
|
369
363
|
string,
|
|
370
364
|
_re.IGNORECASE,
|
|
371
365
|
)
|
|
372
|
-
returns =
|
|
373
|
-
|
|
374
|
-
|
|
366
|
+
returns = _Return(
|
|
367
|
+
bool(match),
|
|
368
|
+
description_missing=not match or not match.group(1),
|
|
369
|
+
)
|
|
370
|
+
docstring = cls(string, returns)
|
|
375
371
|
for match in _re.findall(
|
|
376
372
|
r":([\w\s]+(?:\s\|\s[\w\s]+|\w+))([^\w\s])((?:.|\n)*?)(?=\n:|$)",
|
|
377
373
|
string,
|
|
@@ -402,9 +398,8 @@ class Docstring(_Stub):
|
|
|
402
398
|
|
|
403
399
|
Used when the function has a docstring but documents nothing.
|
|
404
400
|
"""
|
|
405
|
-
return
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
return self._ret_description_missing
|
|
401
|
+
return (
|
|
402
|
+
self._string is not None
|
|
403
|
+
and not self._args
|
|
404
|
+
and not self.returns.returns
|
|
405
|
+
)
|
|
@@ -11,7 +11,7 @@ line-length = 79
|
|
|
11
11
|
allow_dirty = true
|
|
12
12
|
commit = true
|
|
13
13
|
commit_args = "-sS"
|
|
14
|
-
current_version = "0.82.
|
|
14
|
+
current_version = "0.82.2"
|
|
15
15
|
message = "bump: version {current_version} → {new_version}"
|
|
16
16
|
sign_tags = true
|
|
17
17
|
tag = true
|
|
@@ -122,7 +122,7 @@ maintainers = [
|
|
|
122
122
|
name = "docsig"
|
|
123
123
|
readme = "README.rst"
|
|
124
124
|
repository = "https://github.com/jshwi/docsig"
|
|
125
|
-
version = "0.82.
|
|
125
|
+
version = "0.82.2"
|
|
126
126
|
|
|
127
127
|
[tool.poetry.dependencies]
|
|
128
128
|
Sphinx = ">=7,<9"
|
|
@@ -239,7 +239,7 @@ name = "Security"
|
|
|
239
239
|
|
|
240
240
|
[tool.vulture]
|
|
241
241
|
exclude = [
|
|
242
|
-
"tests/
|
|
242
|
+
"tests/base_test.py",
|
|
243
243
|
"tests/conftest.py"
|
|
244
244
|
]
|
|
245
245
|
make_whitelist = true
|
|
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
|
|
File without changes
|
|
File without changes
|