docsig 0.90.3__tar.gz → 0.91.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.90.3 → docsig-0.91.0}/PKG-INFO +4 -4
- {docsig-0.90.3 → docsig-0.91.0}/README.rst +3 -3
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_check.py +2 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_config.py +8 -7
- docsig-0.91.0/docsig/_diagnostic.py +21 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_main.py +0 -1
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_parsers.py +3 -3
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_report.py +99 -45
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_version.py +1 -1
- {docsig-0.90.3 → docsig-0.91.0}/pyproject.toml +3 -3
- {docsig-0.90.3 → docsig-0.91.0}/LICENSE +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/LICENSES/SPHINX_LICENSE +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/__init__.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/__main__.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_core.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_decorators.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_directives.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_files.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_hooks.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_module.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_stub.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_utils.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/_vendor/sphinx/ext/napoleon.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/messages.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/plugin/__init__.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/plugin/_flake8.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/plugin/_validate_pyproject.py +0 -0
- {docsig-0.90.3 → docsig-0.91.0}/docsig/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: docsig
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.91.0
|
|
4
4
|
Summary: Check signature params for proper documentation
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -206,7 +206,7 @@ ensure your installation has registered `docsig`
|
|
|
206
206
|
.. code-block:: console
|
|
207
207
|
|
|
208
208
|
$ flake8 --version
|
|
209
|
-
7.3.0 (docsig: 0.
|
|
209
|
+
7.3.0 (docsig: 0.91.0, mccabe: 0.7.0, pycodestyle: 2.14.0, pyflakes: 3.4.0) CPython 3.10.19 on Darwin
|
|
210
210
|
|
|
211
211
|
And now use `flake8` to lint your files
|
|
212
212
|
|
|
@@ -292,7 +292,7 @@ Standalone
|
|
|
292
292
|
|
|
293
293
|
repos:
|
|
294
294
|
- repo: https://github.com/jshwi/docsig
|
|
295
|
-
rev: v0.
|
|
295
|
+
rev: v0.91.0
|
|
296
296
|
hooks:
|
|
297
297
|
- id: docsig
|
|
298
298
|
args:
|
|
@@ -311,7 +311,7 @@ or integrated with ``flake8``
|
|
|
311
311
|
hooks:
|
|
312
312
|
- id: flake8
|
|
313
313
|
additional_dependencies:
|
|
314
|
-
- docsig==0.
|
|
314
|
+
- docsig==0.91.0
|
|
315
315
|
args:
|
|
316
316
|
- "--sig-check-class"
|
|
317
317
|
- "--sig-check-dunders"
|
|
@@ -178,7 +178,7 @@ ensure your installation has registered `docsig`
|
|
|
178
178
|
.. code-block:: console
|
|
179
179
|
|
|
180
180
|
$ flake8 --version
|
|
181
|
-
7.3.0 (docsig: 0.
|
|
181
|
+
7.3.0 (docsig: 0.91.0, mccabe: 0.7.0, pycodestyle: 2.14.0, pyflakes: 3.4.0) CPython 3.10.19 on Darwin
|
|
182
182
|
|
|
183
183
|
And now use `flake8` to lint your files
|
|
184
184
|
|
|
@@ -264,7 +264,7 @@ Standalone
|
|
|
264
264
|
|
|
265
265
|
repos:
|
|
266
266
|
- repo: https://github.com/jshwi/docsig
|
|
267
|
-
rev: v0.
|
|
267
|
+
rev: v0.91.0
|
|
268
268
|
hooks:
|
|
269
269
|
- id: docsig
|
|
270
270
|
args:
|
|
@@ -283,7 +283,7 @@ or integrated with ``flake8``
|
|
|
283
283
|
hooks:
|
|
284
284
|
- id: flake8
|
|
285
285
|
additional_dependencies:
|
|
286
|
-
- docsig==0.
|
|
286
|
+
- docsig==0.91.0
|
|
287
287
|
args:
|
|
288
288
|
- "--sig-check-class"
|
|
289
289
|
- "--sig-check-dunders"
|
|
@@ -156,17 +156,10 @@ def build_parser() -> _ArgumentParser:
|
|
|
156
156
|
action="store_true",
|
|
157
157
|
help="check nested functions and classes",
|
|
158
158
|
)
|
|
159
|
-
parser.add_argument(
|
|
160
|
-
"-o",
|
|
161
|
-
action="store_true",
|
|
162
|
-
help=_argparse.SUPPRESS,
|
|
163
|
-
dest="check_overridden",
|
|
164
|
-
)
|
|
165
159
|
parser.add_argument(
|
|
166
160
|
"--check-overridden",
|
|
167
161
|
action="store_true",
|
|
168
162
|
help="check overridden methods",
|
|
169
|
-
dest="check_overridden",
|
|
170
163
|
)
|
|
171
164
|
parser.add_argument(
|
|
172
165
|
"--check-property-returns",
|
|
@@ -332,6 +325,14 @@ class Config:
|
|
|
332
325
|
|
|
333
326
|
Groups check, ignore settings, and run options so the core runner
|
|
334
327
|
takes a single config object instead of many parameters.
|
|
328
|
+
|
|
329
|
+
:param check: Configuration for which docstrings and members to
|
|
330
|
+
check.
|
|
331
|
+
:param ignore: Configuration for which docstring elements to ignore.
|
|
332
|
+
:param filters: Configuration for which paths to filter.
|
|
333
|
+
:param target: List of errors to target.
|
|
334
|
+
:param disable: List of errors to disable.
|
|
335
|
+
:param no_ansi: Disable ANSI output.
|
|
335
336
|
"""
|
|
336
337
|
|
|
337
338
|
check: Check = _field(default_factory=Check)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""
|
|
2
|
+
docsig._diagnostic
|
|
3
|
+
==================
|
|
4
|
+
|
|
5
|
+
Diagnostic records and per-function check results for docsig runs.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass as _dataclass
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@_dataclass(frozen=True, order=True)
|
|
12
|
+
class Diagnostic: # pylint: disable=too-few-public-methods
|
|
13
|
+
"""Single reported issue for one function."""
|
|
14
|
+
|
|
15
|
+
name: str
|
|
16
|
+
ref: str
|
|
17
|
+
description: str
|
|
18
|
+
symbolic: str
|
|
19
|
+
lineno: int
|
|
20
|
+
hint: str | None = None
|
|
21
|
+
new: bool = False
|
|
@@ -25,9 +25,9 @@ def parse_from_string(
|
|
|
25
25
|
) -> _Parent:
|
|
26
26
|
"""Build a Parent from a string of Python code.
|
|
27
27
|
|
|
28
|
-
Parses AST and comment directives (AST does not include comments,
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
Parses AST and comment directives (AST does not include comments, so
|
|
29
|
+
directives are parsed separately). On syntax error, returns a Parent
|
|
30
|
+
with an error set.
|
|
31
31
|
|
|
32
32
|
:param code: Python source to parse.
|
|
33
33
|
:param config: Configuration object.
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
docsig._report
|
|
3
3
|
==============
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
defines Failure (per-function validation results), Failed (one reported
|
|
7
|
-
issue), Failures (sequence of failures), and report() to print them and
|
|
8
|
-
return the highest exit code.
|
|
5
|
+
Format and print docstring-check diagnostics for CLI and tooling.
|
|
9
6
|
"""
|
|
10
7
|
|
|
11
8
|
import contextlib as _contextlib
|
|
@@ -13,12 +10,12 @@ import json as _json
|
|
|
13
10
|
import os as _os
|
|
14
11
|
import sys as _sys
|
|
15
12
|
import typing as _t
|
|
16
|
-
from dataclasses import dataclass as _dataclass
|
|
17
13
|
from warnings import warn as _warn
|
|
18
14
|
|
|
19
15
|
import astroid as _ast
|
|
20
16
|
|
|
21
17
|
from ._config import Config as _Config
|
|
18
|
+
from ._diagnostic import Diagnostic as _Diagnostic
|
|
22
19
|
from ._module import Function as _Function
|
|
23
20
|
from ._stub import UNNAMED as _UNNAMED
|
|
24
21
|
from ._stub import VALID_DESCRIPTION as _VALID_DESCRIPTION
|
|
@@ -36,14 +33,14 @@ _MIN_MATCH = 0.8
|
|
|
36
33
|
_MAX_MATCH = 1.0
|
|
37
34
|
|
|
38
35
|
|
|
39
|
-
def check_function(func: _Function, config: _Config) -> "
|
|
36
|
+
def check_function(func: _Function, config: _Config) -> "_FunctionResult":
|
|
40
37
|
"""Run configured checks for one function and return the result.
|
|
41
38
|
|
|
42
39
|
:param func: Function under check.
|
|
43
40
|
:param config: Configuration object.
|
|
44
41
|
:return: Collected diagnostics for the function.
|
|
45
42
|
"""
|
|
46
|
-
return FunctionChecker(func, config)
|
|
43
|
+
return FunctionChecker(func, config).run()
|
|
47
44
|
|
|
48
45
|
|
|
49
46
|
class RetCode:
|
|
@@ -68,24 +65,11 @@ class RetCode:
|
|
|
68
65
|
return max(self._data)
|
|
69
66
|
|
|
70
67
|
|
|
71
|
-
class Failures(list["
|
|
72
|
-
"""Sequence of
|
|
68
|
+
class Failures(list["_FunctionResult"]):
|
|
69
|
+
"""Sequence of result instances (one per function checked)."""
|
|
73
70
|
|
|
74
71
|
|
|
75
|
-
|
|
76
|
-
class Diagnostic: # pylint: disable=too-few-public-methods
|
|
77
|
-
"""Single reported issue."""
|
|
78
|
-
|
|
79
|
-
name: str
|
|
80
|
-
ref: str
|
|
81
|
-
description: str
|
|
82
|
-
symbolic: str
|
|
83
|
-
lineno: int
|
|
84
|
-
hint: str | None = None
|
|
85
|
-
new: bool = False
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
class FunctionChecker(list[Diagnostic]):
|
|
72
|
+
class FunctionChecker: # pylint: disable=too-few-public-methods
|
|
89
73
|
"""Collect docstring and signature failures for one function.
|
|
90
74
|
|
|
91
75
|
Runs configured checks and appends Failed entries for each
|
|
@@ -96,9 +80,9 @@ class FunctionChecker(list[Diagnostic]):
|
|
|
96
80
|
"""
|
|
97
81
|
|
|
98
82
|
def __init__(self, func: _Function, config: _Config) -> None:
|
|
99
|
-
super().__init__()
|
|
100
|
-
self._retcode = RetCode()
|
|
101
83
|
self._func = func
|
|
84
|
+
self._config = config
|
|
85
|
+
self._diagnostics: list[_Diagnostic] = []
|
|
102
86
|
if config.target:
|
|
103
87
|
self._func.messages.extend(
|
|
104
88
|
i for i in _E.all if i not in config.target
|
|
@@ -113,8 +97,15 @@ class FunctionChecker(list[Diagnostic]):
|
|
|
113
97
|
):
|
|
114
98
|
self._name = f"{self._func.parent.name}.{self._name}"
|
|
115
99
|
|
|
100
|
+
self._collector = _Collector(func, self._name, self._func.lineno)
|
|
101
|
+
|
|
102
|
+
def run(self) -> "_FunctionResult":
|
|
103
|
+
"""Run the function checks and return the result.
|
|
104
|
+
|
|
105
|
+
:return: Function result.
|
|
106
|
+
"""
|
|
116
107
|
if self._func.error is not None:
|
|
117
|
-
self.
|
|
108
|
+
self._collector.retcode.add(2)
|
|
118
109
|
self._sig9xx_error()
|
|
119
110
|
else:
|
|
120
111
|
self._sig0xx_config()
|
|
@@ -128,9 +119,9 @@ class FunctionChecker(list[Diagnostic]):
|
|
|
128
119
|
sig = self._func.signature.args.get(index)
|
|
129
120
|
self._sig4xx_parameters(doc, sig)
|
|
130
121
|
|
|
131
|
-
self._sig5xx_returns(
|
|
122
|
+
self._sig5xx_returns(self._config.check.property_returns)
|
|
132
123
|
|
|
133
|
-
self.
|
|
124
|
+
return _FunctionResult(self._name, self._func.lineno, self._collector)
|
|
134
125
|
|
|
135
126
|
def _add(
|
|
136
127
|
self,
|
|
@@ -138,18 +129,7 @@ class FunctionChecker(list[Diagnostic]):
|
|
|
138
129
|
include_hint: bool = False,
|
|
139
130
|
**kwargs: _t.Any,
|
|
140
131
|
) -> None:
|
|
141
|
-
self.
|
|
142
|
-
failed = Diagnostic(
|
|
143
|
-
self._name,
|
|
144
|
-
value.ref,
|
|
145
|
-
value.description.format(**kwargs),
|
|
146
|
-
value.symbolic,
|
|
147
|
-
self.lineno,
|
|
148
|
-
value.hint if include_hint else None,
|
|
149
|
-
value.new,
|
|
150
|
-
)
|
|
151
|
-
if value not in self._func.messages and failed not in self:
|
|
152
|
-
super().append(failed)
|
|
132
|
+
self._collector.add(value, include_hint=include_hint, **kwargs)
|
|
153
133
|
|
|
154
134
|
@staticmethod
|
|
155
135
|
def _normalize_params(from_: _Params, to: _Params) -> None:
|
|
@@ -371,7 +351,7 @@ class FunctionChecker(list[Diagnostic]):
|
|
|
371
351
|
# invalid-syntax
|
|
372
352
|
if self._func.error is _ast.AstroidSyntaxError:
|
|
373
353
|
self._add(_E[901])
|
|
374
|
-
self.
|
|
354
|
+
self._collector.retcode.add(123)
|
|
375
355
|
# unicode-decode-error
|
|
376
356
|
if self._func.error is UnicodeDecodeError:
|
|
377
357
|
self._add(_E[902])
|
|
@@ -382,6 +362,73 @@ class FunctionChecker(list[Diagnostic]):
|
|
|
382
362
|
if self._func.error is _ast.DuplicateBasesError:
|
|
383
363
|
self._add(_E[904])
|
|
384
364
|
|
|
365
|
+
|
|
366
|
+
class _Collector:
|
|
367
|
+
def __init__(
|
|
368
|
+
self,
|
|
369
|
+
func: _Function,
|
|
370
|
+
qualified_name: str,
|
|
371
|
+
lineno: int,
|
|
372
|
+
) -> None:
|
|
373
|
+
self._func = func
|
|
374
|
+
self._qualified_name = qualified_name
|
|
375
|
+
self._lineno = lineno
|
|
376
|
+
self._diagnostics: list[_Diagnostic] = []
|
|
377
|
+
self._retcode = RetCode()
|
|
378
|
+
|
|
379
|
+
def add(
|
|
380
|
+
self,
|
|
381
|
+
value: _Message,
|
|
382
|
+
include_hint: bool = False,
|
|
383
|
+
**kwargs: _t.Any,
|
|
384
|
+
) -> None:
|
|
385
|
+
"""Add a diagnostic message.
|
|
386
|
+
|
|
387
|
+
:param value: Message to add.
|
|
388
|
+
:param include_hint: Whether to include the hint.
|
|
389
|
+
:param kwargs: Additional arguments to format the description.
|
|
390
|
+
"""
|
|
391
|
+
self._retcode.add(int(not value.new))
|
|
392
|
+
diagnostic = _Diagnostic(
|
|
393
|
+
self._qualified_name,
|
|
394
|
+
value.ref,
|
|
395
|
+
value.description.format(**kwargs),
|
|
396
|
+
value.symbolic,
|
|
397
|
+
self._lineno,
|
|
398
|
+
value.hint if include_hint else None,
|
|
399
|
+
value.new,
|
|
400
|
+
)
|
|
401
|
+
if (
|
|
402
|
+
value not in self._func.messages
|
|
403
|
+
and diagnostic not in self._diagnostics
|
|
404
|
+
):
|
|
405
|
+
self._diagnostics.append(diagnostic)
|
|
406
|
+
|
|
407
|
+
@property
|
|
408
|
+
def diagnostics(self) -> list[_Diagnostic]:
|
|
409
|
+
"""Diagnostics sorted for stable output."""
|
|
410
|
+
return sorted(self._diagnostics)
|
|
411
|
+
|
|
412
|
+
@property
|
|
413
|
+
def retcode(self) -> RetCode:
|
|
414
|
+
"""Exit code (non-zero if any check failed)."""
|
|
415
|
+
return self._retcode
|
|
416
|
+
|
|
417
|
+
def __bool__(self) -> bool:
|
|
418
|
+
return bool(self._diagnostics)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
class _FunctionResult:
|
|
422
|
+
def __init__(
|
|
423
|
+
self,
|
|
424
|
+
name: str,
|
|
425
|
+
lineno: int,
|
|
426
|
+
collector: _Collector,
|
|
427
|
+
) -> None:
|
|
428
|
+
self._name = name
|
|
429
|
+
self._lineno = lineno
|
|
430
|
+
self._collector = collector
|
|
431
|
+
|
|
385
432
|
@property
|
|
386
433
|
def name(self) -> str:
|
|
387
434
|
"""Qualified name (Class.method) when nested, else bare name."""
|
|
@@ -390,12 +437,18 @@ class FunctionChecker(list[Diagnostic]):
|
|
|
390
437
|
@property
|
|
391
438
|
def lineno(self) -> int:
|
|
392
439
|
"""Line number of the function in the source."""
|
|
393
|
-
return self.
|
|
440
|
+
return self._lineno
|
|
394
441
|
|
|
395
442
|
@property
|
|
396
443
|
def retcode(self) -> int:
|
|
397
444
|
"""Exit code (non-zero if any check failed)."""
|
|
398
|
-
return self.
|
|
445
|
+
return self._collector.retcode.result
|
|
446
|
+
|
|
447
|
+
def __iter__(self) -> _t.Iterator[_Diagnostic]:
|
|
448
|
+
return iter(self._collector.diagnostics)
|
|
449
|
+
|
|
450
|
+
def __bool__(self) -> bool:
|
|
451
|
+
return bool(self._collector)
|
|
399
452
|
|
|
400
453
|
|
|
401
454
|
# TODO: make report json by default and wrap with a reporter for cli
|
|
@@ -404,12 +457,13 @@ def report(
|
|
|
404
457
|
config: _Config,
|
|
405
458
|
file: str | None = None,
|
|
406
459
|
) -> int:
|
|
407
|
-
"""Print failures
|
|
460
|
+
"""Print failures and return the highest exit code.
|
|
408
461
|
|
|
409
462
|
Iterates over failures, prints each with path, line header, and
|
|
410
463
|
messages, then returns the maximum retcode (0 or non-zero).
|
|
411
464
|
|
|
412
|
-
:param failures: Failures to print (one
|
|
465
|
+
:param failures: Failures to print (one FunctionResult per
|
|
466
|
+
function).
|
|
413
467
|
:param config: Config for ANSI and formatting.
|
|
414
468
|
:param file: Module path when failures came from a file (optional).
|
|
415
469
|
:return: Exit code (non-zero if any check failed).
|
|
@@ -29,7 +29,7 @@ maintainers = [
|
|
|
29
29
|
name = "docsig"
|
|
30
30
|
readme = "README.rst"
|
|
31
31
|
requires-python = ">=3.10"
|
|
32
|
-
version = "0.
|
|
32
|
+
version = "0.91.0"
|
|
33
33
|
|
|
34
34
|
[project.entry-points."flake8.extension"]
|
|
35
35
|
SIG = "docsig.plugin:Flake8"
|
|
@@ -47,7 +47,7 @@ line-length = 79
|
|
|
47
47
|
allow_dirty = true
|
|
48
48
|
commit = true
|
|
49
49
|
commit_args = "-sS"
|
|
50
|
-
current_version = "0.
|
|
50
|
+
current_version = "0.91.0"
|
|
51
51
|
message = "bump: version {current_version} → {new_version}"
|
|
52
52
|
sign_tags = true
|
|
53
53
|
tag = true
|
|
@@ -146,7 +146,7 @@ black = ">=24.4.2,<27.0.0"
|
|
|
146
146
|
bump-my-version = ">=1.4.1,<1.5.0"
|
|
147
147
|
deptry = ">=0.16.1,<0.26.0"
|
|
148
148
|
flynt = "^1.0.1"
|
|
149
|
-
gitpython = "^3.1.
|
|
149
|
+
gitpython = "^3.1.52"
|
|
150
150
|
isort = ">=5.13.2,<9.0.0"
|
|
151
151
|
mypy = ">=2.3.0,<3.0"
|
|
152
152
|
pre-commit = ">=3.3.3,<5.0.0"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|