Sphinx 8.1.3__py3-none-any.whl → 8.2.0rc1__py3-none-any.whl
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.
Potentially problematic release.
This version of Sphinx might be problematic. Click here for more details.
- sphinx/__init__.py +8 -4
- sphinx/__main__.py +2 -0
- sphinx/_cli/__init__.py +2 -5
- sphinx/_cli/util/colour.py +34 -11
- sphinx/_cli/util/errors.py +128 -61
- sphinx/addnodes.py +51 -35
- sphinx/application.py +362 -230
- sphinx/builders/__init__.py +87 -64
- sphinx/builders/_epub_base.py +65 -56
- sphinx/builders/changes.py +17 -23
- sphinx/builders/dirhtml.py +8 -13
- sphinx/builders/epub3.py +70 -38
- sphinx/builders/gettext.py +93 -73
- sphinx/builders/html/__init__.py +240 -186
- sphinx/builders/html/_assets.py +9 -2
- sphinx/builders/html/_build_info.py +3 -0
- sphinx/builders/latex/__init__.py +64 -54
- sphinx/builders/latex/constants.py +14 -11
- sphinx/builders/latex/nodes.py +2 -0
- sphinx/builders/latex/theming.py +8 -9
- sphinx/builders/latex/transforms.py +7 -5
- sphinx/builders/linkcheck.py +193 -149
- sphinx/builders/manpage.py +17 -17
- sphinx/builders/singlehtml.py +28 -16
- sphinx/builders/texinfo.py +28 -21
- sphinx/builders/text.py +10 -15
- sphinx/builders/xml.py +10 -19
- sphinx/cmd/build.py +49 -119
- sphinx/cmd/make_mode.py +35 -31
- sphinx/cmd/quickstart.py +78 -62
- sphinx/config.py +265 -163
- sphinx/directives/__init__.py +51 -54
- sphinx/directives/admonitions.py +107 -0
- sphinx/directives/code.py +24 -19
- sphinx/directives/other.py +21 -42
- sphinx/directives/patches.py +28 -16
- sphinx/domains/__init__.py +54 -31
- sphinx/domains/_domains_container.py +22 -17
- sphinx/domains/_index.py +5 -8
- sphinx/domains/c/__init__.py +366 -245
- sphinx/domains/c/_ast.py +378 -256
- sphinx/domains/c/_ids.py +89 -31
- sphinx/domains/c/_parser.py +283 -214
- sphinx/domains/c/_symbol.py +269 -198
- sphinx/domains/changeset.py +39 -24
- sphinx/domains/citation.py +54 -24
- sphinx/domains/cpp/__init__.py +517 -362
- sphinx/domains/cpp/_ast.py +999 -682
- sphinx/domains/cpp/_ids.py +133 -65
- sphinx/domains/cpp/_parser.py +746 -588
- sphinx/domains/cpp/_symbol.py +692 -489
- sphinx/domains/index.py +10 -8
- sphinx/domains/javascript.py +152 -74
- sphinx/domains/math.py +48 -40
- sphinx/domains/python/__init__.py +402 -211
- sphinx/domains/python/_annotations.py +114 -57
- sphinx/domains/python/_object.py +151 -67
- sphinx/domains/rst.py +94 -49
- sphinx/domains/std/__init__.py +510 -249
- sphinx/environment/__init__.py +345 -61
- sphinx/environment/adapters/asset.py +7 -1
- sphinx/environment/adapters/indexentries.py +15 -20
- sphinx/environment/adapters/toctree.py +19 -9
- sphinx/environment/collectors/__init__.py +3 -1
- sphinx/environment/collectors/asset.py +18 -15
- sphinx/environment/collectors/dependencies.py +8 -10
- sphinx/environment/collectors/metadata.py +6 -4
- sphinx/environment/collectors/title.py +3 -1
- sphinx/environment/collectors/toctree.py +4 -4
- sphinx/errors.py +1 -3
- sphinx/events.py +4 -4
- sphinx/ext/apidoc/__init__.py +21 -0
- sphinx/ext/apidoc/__main__.py +9 -0
- sphinx/ext/apidoc/_cli.py +356 -0
- sphinx/ext/apidoc/_generate.py +356 -0
- sphinx/ext/apidoc/_shared.py +66 -0
- sphinx/ext/autodoc/__init__.py +829 -480
- sphinx/ext/autodoc/directive.py +57 -21
- sphinx/ext/autodoc/importer.py +184 -67
- sphinx/ext/autodoc/mock.py +25 -10
- sphinx/ext/autodoc/preserve_defaults.py +17 -9
- sphinx/ext/autodoc/type_comment.py +56 -29
- sphinx/ext/autodoc/typehints.py +49 -26
- sphinx/ext/autosectionlabel.py +28 -11
- sphinx/ext/autosummary/__init__.py +271 -143
- sphinx/ext/autosummary/generate.py +121 -51
- sphinx/ext/coverage.py +152 -91
- sphinx/ext/doctest.py +169 -101
- sphinx/ext/duration.py +12 -6
- sphinx/ext/extlinks.py +33 -21
- sphinx/ext/githubpages.py +8 -8
- sphinx/ext/graphviz.py +175 -109
- sphinx/ext/ifconfig.py +11 -6
- sphinx/ext/imgconverter.py +48 -25
- sphinx/ext/imgmath.py +127 -97
- sphinx/ext/inheritance_diagram.py +177 -103
- sphinx/ext/intersphinx/__init__.py +22 -13
- sphinx/ext/intersphinx/__main__.py +3 -1
- sphinx/ext/intersphinx/_cli.py +18 -14
- sphinx/ext/intersphinx/_load.py +91 -82
- sphinx/ext/intersphinx/_resolve.py +108 -74
- sphinx/ext/intersphinx/_shared.py +2 -2
- sphinx/ext/linkcode.py +28 -12
- sphinx/ext/mathjax.py +60 -29
- sphinx/ext/napoleon/__init__.py +19 -7
- sphinx/ext/napoleon/docstring.py +229 -231
- sphinx/ext/todo.py +44 -49
- sphinx/ext/viewcode.py +105 -57
- sphinx/extension.py +3 -1
- sphinx/highlighting.py +13 -7
- sphinx/io.py +9 -13
- sphinx/jinja2glue.py +29 -26
- sphinx/locale/__init__.py +8 -9
- sphinx/parsers.py +8 -7
- sphinx/project.py +2 -2
- sphinx/pycode/__init__.py +31 -21
- sphinx/pycode/ast.py +6 -3
- sphinx/pycode/parser.py +14 -8
- sphinx/pygments_styles.py +4 -5
- sphinx/registry.py +192 -92
- sphinx/roles.py +58 -7
- sphinx/search/__init__.py +75 -54
- sphinx/search/en.py +11 -13
- sphinx/search/fi.py +1 -1
- sphinx/search/ja.py +8 -6
- sphinx/search/nl.py +1 -1
- sphinx/search/zh.py +19 -21
- sphinx/testing/fixtures.py +26 -29
- sphinx/testing/path.py +26 -62
- sphinx/testing/restructuredtext.py +14 -8
- sphinx/testing/util.py +21 -19
- sphinx/texinputs/make.bat.jinja +50 -50
- sphinx/texinputs/sphinx.sty +4 -3
- sphinx/texinputs/sphinxlatexadmonitions.sty +1 -1
- sphinx/texinputs/sphinxlatexobjects.sty +29 -10
- sphinx/themes/basic/static/searchtools.js +8 -5
- sphinx/theming.py +49 -61
- sphinx/transforms/__init__.py +17 -38
- sphinx/transforms/compact_bullet_list.py +5 -3
- sphinx/transforms/i18n.py +8 -21
- sphinx/transforms/post_transforms/__init__.py +142 -93
- sphinx/transforms/post_transforms/code.py +5 -5
- sphinx/transforms/post_transforms/images.py +28 -24
- sphinx/transforms/references.py +3 -1
- sphinx/util/__init__.py +109 -60
- sphinx/util/_files.py +39 -23
- sphinx/util/_importer.py +4 -1
- sphinx/util/_inventory_file_reader.py +76 -0
- sphinx/util/_io.py +2 -2
- sphinx/util/_lines.py +6 -3
- sphinx/util/_pathlib.py +40 -2
- sphinx/util/build_phase.py +2 -0
- sphinx/util/cfamily.py +19 -14
- sphinx/util/console.py +44 -179
- sphinx/util/display.py +9 -10
- sphinx/util/docfields.py +140 -122
- sphinx/util/docstrings.py +1 -1
- sphinx/util/docutils.py +118 -77
- sphinx/util/fileutil.py +25 -26
- sphinx/util/http_date.py +2 -0
- sphinx/util/i18n.py +77 -64
- sphinx/util/images.py +8 -6
- sphinx/util/inspect.py +147 -38
- sphinx/util/inventory.py +215 -116
- sphinx/util/logging.py +33 -33
- sphinx/util/matching.py +12 -4
- sphinx/util/nodes.py +18 -13
- sphinx/util/osutil.py +38 -39
- sphinx/util/parallel.py +22 -13
- sphinx/util/parsing.py +2 -1
- sphinx/util/png.py +6 -2
- sphinx/util/requests.py +33 -2
- sphinx/util/rst.py +3 -2
- sphinx/util/tags.py +1 -1
- sphinx/util/template.py +18 -10
- sphinx/util/texescape.py +8 -6
- sphinx/util/typing.py +148 -122
- sphinx/versioning.py +3 -3
- sphinx/writers/html.py +3 -1
- sphinx/writers/html5.py +61 -50
- sphinx/writers/latex.py +80 -65
- sphinx/writers/manpage.py +19 -38
- sphinx/writers/texinfo.py +44 -45
- sphinx/writers/text.py +48 -30
- sphinx/writers/xml.py +11 -8
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/LICENSE.rst +1 -1
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/METADATA +23 -15
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/RECORD +190 -186
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/WHEEL +1 -1
- sphinx/builders/html/transforms.py +0 -90
- sphinx/ext/apidoc.py +0 -721
- sphinx/util/exceptions.py +0 -74
- {sphinx-8.1.3.dist-info → sphinx-8.2.0rc1.dist-info}/entry_points.txt +0 -0
|
@@ -6,25 +6,28 @@ import operator
|
|
|
6
6
|
import token
|
|
7
7
|
from collections import deque
|
|
8
8
|
from inspect import Parameter
|
|
9
|
-
from typing import TYPE_CHECKING
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
10
|
|
|
11
11
|
from docutils import nodes
|
|
12
12
|
|
|
13
13
|
from sphinx import addnodes
|
|
14
|
-
from sphinx.addnodes import
|
|
14
|
+
from sphinx.addnodes import pending_xref, pending_xref_condition
|
|
15
15
|
from sphinx.pycode.parser import Token, TokenProcessor
|
|
16
16
|
from sphinx.util.inspect import signature_from_str
|
|
17
17
|
|
|
18
18
|
if TYPE_CHECKING:
|
|
19
19
|
from collections.abc import Iterable, Iterator
|
|
20
|
+
from typing import Any
|
|
20
21
|
|
|
21
22
|
from docutils.nodes import Element, Node
|
|
22
23
|
|
|
24
|
+
from sphinx.addnodes import desc_signature
|
|
23
25
|
from sphinx.environment import BuildEnvironment
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
def parse_reftarget(
|
|
27
|
-
|
|
28
|
+
def parse_reftarget(
|
|
29
|
+
reftarget: str, suppress_prefix: bool = False
|
|
30
|
+
) -> tuple[str, str, str, bool]:
|
|
28
31
|
"""Parse a type string and return (reftype, reftarget, title, refspecific flag)"""
|
|
29
32
|
refspecific = False
|
|
30
33
|
if reftarget.startswith('.'):
|
|
@@ -50,12 +53,15 @@ def parse_reftarget(reftarget: str, suppress_prefix: bool = False,
|
|
|
50
53
|
return reftype, reftarget, title, refspecific
|
|
51
54
|
|
|
52
55
|
|
|
53
|
-
def type_to_xref(
|
|
54
|
-
|
|
56
|
+
def type_to_xref(
|
|
57
|
+
target: str, env: BuildEnvironment, *, suppress_prefix: bool = False
|
|
58
|
+
) -> addnodes.pending_xref:
|
|
55
59
|
"""Convert a type string to a cross reference node."""
|
|
56
60
|
if env:
|
|
57
|
-
kwargs = {
|
|
58
|
-
|
|
61
|
+
kwargs = {
|
|
62
|
+
'py:module': env.ref_context.get('py:module'),
|
|
63
|
+
'py:class': env.ref_context.get('py:class'),
|
|
64
|
+
}
|
|
59
65
|
else:
|
|
60
66
|
kwargs = {}
|
|
61
67
|
|
|
@@ -66,14 +72,22 @@ def type_to_xref(target: str, env: BuildEnvironment, *,
|
|
|
66
72
|
# nested classes. But python domain can't access the real python object because this
|
|
67
73
|
# module should work not-dynamically.
|
|
68
74
|
shortname = title.split('.')[-1]
|
|
69
|
-
contnodes: list[Node] = [
|
|
70
|
-
|
|
75
|
+
contnodes: list[Node] = [
|
|
76
|
+
pending_xref_condition('', shortname, condition='resolved'),
|
|
77
|
+
pending_xref_condition('', title, condition='*'),
|
|
78
|
+
]
|
|
71
79
|
else:
|
|
72
80
|
contnodes = [nodes.Text(title)]
|
|
73
81
|
|
|
74
|
-
return pending_xref(
|
|
75
|
-
|
|
76
|
-
|
|
82
|
+
return pending_xref(
|
|
83
|
+
'',
|
|
84
|
+
*contnodes,
|
|
85
|
+
refdomain='py',
|
|
86
|
+
reftype=reftype,
|
|
87
|
+
reftarget=target,
|
|
88
|
+
refspecific=refspecific,
|
|
89
|
+
**kwargs,
|
|
90
|
+
)
|
|
77
91
|
|
|
78
92
|
|
|
79
93
|
def _parse_annotation(annotation: str, env: BuildEnvironment) -> list[Node]:
|
|
@@ -82,19 +96,21 @@ def _parse_annotation(annotation: str, env: BuildEnvironment) -> list[Node]:
|
|
|
82
96
|
|
|
83
97
|
def unparse(node: ast.AST) -> list[Node]:
|
|
84
98
|
if isinstance(node, ast.Attribute):
|
|
85
|
-
return [nodes.Text(f
|
|
99
|
+
return [nodes.Text(f'{unparse(node.value)[0]}.{node.attr}')]
|
|
86
100
|
if isinstance(node, ast.BinOp):
|
|
87
101
|
result: list[Node] = unparse(node.left)
|
|
88
102
|
result.extend(unparse(node.op))
|
|
89
103
|
result.extend(unparse(node.right))
|
|
90
104
|
return result
|
|
91
105
|
if isinstance(node, ast.BitOr):
|
|
92
|
-
return [
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
return [
|
|
107
|
+
addnodes.desc_sig_space(),
|
|
108
|
+
addnodes.desc_sig_punctuation('', '|'),
|
|
109
|
+
addnodes.desc_sig_space(),
|
|
110
|
+
]
|
|
95
111
|
if isinstance(node, ast.Constant):
|
|
96
112
|
if node.value is Ellipsis:
|
|
97
|
-
return [addnodes.desc_sig_punctuation('',
|
|
113
|
+
return [addnodes.desc_sig_punctuation('', '...')]
|
|
98
114
|
if isinstance(node.value, bool):
|
|
99
115
|
return [addnodes.desc_sig_keyword('', repr(node.value))]
|
|
100
116
|
if isinstance(node.value, int):
|
|
@@ -140,7 +156,7 @@ def _parse_annotation(annotation: str, env: BuildEnvironment) -> list[Node]:
|
|
|
140
156
|
result.append(addnodes.desc_sig_punctuation('', ']'))
|
|
141
157
|
|
|
142
158
|
# Wrap the Text nodes inside brackets by literal node if the subscript is a Literal
|
|
143
|
-
if result[0] in
|
|
159
|
+
if result[0] in {'Literal', 'typing.Literal'}:
|
|
144
160
|
for i, subnode in enumerate(result[1:], start=1):
|
|
145
161
|
if isinstance(subnode, nodes.Text):
|
|
146
162
|
result[i] = nodes.literal('', '', subnode)
|
|
@@ -157,8 +173,10 @@ def _parse_annotation(annotation: str, env: BuildEnvironment) -> list[Node]:
|
|
|
157
173
|
result.pop()
|
|
158
174
|
result.pop()
|
|
159
175
|
else:
|
|
160
|
-
result = [
|
|
161
|
-
|
|
176
|
+
result = [
|
|
177
|
+
addnodes.desc_sig_punctuation('', '('),
|
|
178
|
+
addnodes.desc_sig_punctuation('', ')'),
|
|
179
|
+
]
|
|
162
180
|
|
|
163
181
|
return result
|
|
164
182
|
if isinstance(node, ast.Call):
|
|
@@ -211,8 +229,11 @@ def _parse_annotation(annotation: str, env: BuildEnvironment) -> list[Node]:
|
|
|
211
229
|
if isinstance(node, nodes.literal):
|
|
212
230
|
result.append(node[0])
|
|
213
231
|
elif isinstance(node, nodes.Text) and node.strip():
|
|
214
|
-
if (
|
|
215
|
-
|
|
232
|
+
if (
|
|
233
|
+
result
|
|
234
|
+
and isinstance(result[-1], addnodes.desc_sig_punctuation)
|
|
235
|
+
and result[-1].astext() == '~'
|
|
236
|
+
):
|
|
216
237
|
result.pop()
|
|
217
238
|
result.append(type_to_xref(str(node), env, suppress_prefix=True))
|
|
218
239
|
else:
|
|
@@ -244,8 +265,7 @@ class _TypeParameterListParser(TokenProcessor):
|
|
|
244
265
|
else:
|
|
245
266
|
if current == token.INDENT:
|
|
246
267
|
tokens += self.fetch_until(token.DEDENT)
|
|
247
|
-
elif current.match(
|
|
248
|
-
[token.OP, ':'], [token.OP, '='], [token.OP, ',']):
|
|
268
|
+
elif current.match([token.OP, ':'], [token.OP, '='], [token.OP, ',']):
|
|
249
269
|
tokens.pop()
|
|
250
270
|
break
|
|
251
271
|
return tokens
|
|
@@ -254,7 +274,9 @@ class _TypeParameterListParser(TokenProcessor):
|
|
|
254
274
|
while current := self.fetch_token():
|
|
255
275
|
if current == token.NAME:
|
|
256
276
|
tp_name = current.value.strip()
|
|
257
|
-
if self.previous and self.previous.match(
|
|
277
|
+
if self.previous and self.previous.match(
|
|
278
|
+
[token.OP, '*'], [token.OP, '**']
|
|
279
|
+
):
|
|
258
280
|
if self.previous == [token.OP, '*']:
|
|
259
281
|
tp_kind = Parameter.VAR_POSITIONAL
|
|
260
282
|
else:
|
|
@@ -275,9 +297,14 @@ class _TypeParameterListParser(TokenProcessor):
|
|
|
275
297
|
tokens = self.fetch_type_param_spec()
|
|
276
298
|
tp_default = self._build_identifier(tokens)
|
|
277
299
|
|
|
278
|
-
if
|
|
279
|
-
|
|
280
|
-
|
|
300
|
+
if (
|
|
301
|
+
tp_kind != Parameter.POSITIONAL_OR_KEYWORD
|
|
302
|
+
and tp_ann != Parameter.empty
|
|
303
|
+
):
|
|
304
|
+
msg = (
|
|
305
|
+
'type parameter bound or constraint is not allowed '
|
|
306
|
+
f'for {tp_kind.description} parameters'
|
|
307
|
+
)
|
|
281
308
|
raise SyntaxError(msg)
|
|
282
309
|
|
|
283
310
|
type_param = (tp_name, tp_kind, tp_default, tp_ann)
|
|
@@ -315,12 +342,22 @@ class _TypeParameterListParser(TokenProcessor):
|
|
|
315
342
|
idents.append(ident)
|
|
316
343
|
# determine if the next token is an unpack operator depending
|
|
317
344
|
# on the left and right hand side of the operator symbol
|
|
318
|
-
is_unpack_operator = (
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
345
|
+
is_unpack_operator = op.match([token.OP, '*'], [token.OP, '**']) and not (
|
|
346
|
+
tok.match(
|
|
347
|
+
token.NAME,
|
|
348
|
+
token.NUMBER,
|
|
349
|
+
token.STRING,
|
|
350
|
+
[token.OP, ')'],
|
|
351
|
+
[token.OP, ']'],
|
|
352
|
+
[token.OP, '}'],
|
|
353
|
+
)
|
|
354
|
+
and after.match(
|
|
355
|
+
token.NAME,
|
|
356
|
+
token.NUMBER,
|
|
357
|
+
token.STRING,
|
|
358
|
+
[token.OP, '('],
|
|
359
|
+
[token.OP, '['],
|
|
360
|
+
[token.OP, '{'],
|
|
324
361
|
)
|
|
325
362
|
)
|
|
326
363
|
|
|
@@ -356,28 +393,33 @@ class _TypeParameterListParser(TokenProcessor):
|
|
|
356
393
|
[token.OP, '@'], [token.OP, '/'], [token.OP, '//'], [token.OP, '%'],
|
|
357
394
|
[token.OP, '<<'], [token.OP, '>>'], [token.OP, '>>>'],
|
|
358
395
|
[token.OP, '<='], [token.OP, '>='], [token.OP, '=='], [token.OP, '!='],
|
|
359
|
-
):
|
|
396
|
+
): # fmt: skip
|
|
360
397
|
return f' {tok.value} '
|
|
361
398
|
|
|
362
399
|
return tok.value
|
|
363
400
|
|
|
364
401
|
|
|
365
402
|
def _parse_type_list(
|
|
366
|
-
tp_list: str,
|
|
403
|
+
tp_list: str,
|
|
404
|
+
env: BuildEnvironment,
|
|
367
405
|
multi_line_parameter_list: bool = False,
|
|
406
|
+
trailing_comma: bool = True,
|
|
368
407
|
) -> addnodes.desc_type_parameter_list:
|
|
369
408
|
"""Parse a list of type parameters according to PEP 695."""
|
|
370
409
|
type_params = addnodes.desc_type_parameter_list(tp_list)
|
|
371
410
|
type_params['multi_line_parameter_list'] = multi_line_parameter_list
|
|
411
|
+
type_params['multi_line_trailing_comma'] = trailing_comma
|
|
372
412
|
# formal parameter names are interpreted as type parameter names and
|
|
373
413
|
# type annotations are interpreted as type parameter bound or constraints
|
|
374
414
|
parser = _TypeParameterListParser(tp_list)
|
|
375
415
|
parser.parse()
|
|
376
|
-
for
|
|
416
|
+
for tp_name, tp_kind, tp_default, tp_ann in parser.type_params:
|
|
377
417
|
# no positional-only or keyword-only allowed in a type parameters list
|
|
378
418
|
if tp_kind in {Parameter.POSITIONAL_ONLY, Parameter.KEYWORD_ONLY}:
|
|
379
|
-
msg = (
|
|
380
|
-
|
|
419
|
+
msg = (
|
|
420
|
+
'positional-only or keyword-only parameters '
|
|
421
|
+
'are prohibited in type parameter lists'
|
|
422
|
+
)
|
|
381
423
|
raise SyntaxError(msg)
|
|
382
424
|
|
|
383
425
|
node = addnodes.desc_type_parameter()
|
|
@@ -395,8 +437,7 @@ def _parse_type_list(
|
|
|
395
437
|
node += addnodes.desc_sig_punctuation('', ':')
|
|
396
438
|
node += addnodes.desc_sig_space()
|
|
397
439
|
|
|
398
|
-
type_ann_expr = addnodes.desc_sig_name('', '',
|
|
399
|
-
*annotation) # type: ignore[arg-type]
|
|
440
|
+
type_ann_expr = addnodes.desc_sig_name('', '', *annotation) # type: ignore[arg-type]
|
|
400
441
|
# a type bound is ``T: U`` whereas type constraints
|
|
401
442
|
# must be enclosed with parentheses. ``T: (U, V)``
|
|
402
443
|
if tp_ann.startswith('(') and tp_ann.endswith(')'):
|
|
@@ -416,31 +457,41 @@ def _parse_type_list(
|
|
|
416
457
|
node += addnodes.desc_sig_space()
|
|
417
458
|
node += addnodes.desc_sig_operator('', '=')
|
|
418
459
|
node += addnodes.desc_sig_space()
|
|
419
|
-
node += nodes.inline(
|
|
420
|
-
|
|
421
|
-
|
|
460
|
+
node += nodes.inline(
|
|
461
|
+
'', tp_default, classes=['default_value'], support_smartquotes=False
|
|
462
|
+
)
|
|
422
463
|
|
|
423
464
|
type_params += node
|
|
424
465
|
return type_params
|
|
425
466
|
|
|
426
467
|
|
|
427
468
|
def _parse_arglist(
|
|
428
|
-
arglist: str,
|
|
469
|
+
arglist: str,
|
|
470
|
+
env: BuildEnvironment,
|
|
471
|
+
multi_line_parameter_list: bool = False,
|
|
472
|
+
trailing_comma: bool = True,
|
|
429
473
|
) -> addnodes.desc_parameterlist:
|
|
430
474
|
"""Parse a list of arguments using AST parser"""
|
|
431
475
|
params = addnodes.desc_parameterlist(arglist)
|
|
432
476
|
params['multi_line_parameter_list'] = multi_line_parameter_list
|
|
477
|
+
params['multi_line_trailing_comma'] = trailing_comma
|
|
433
478
|
sig = signature_from_str('(%s)' % arglist)
|
|
434
479
|
last_kind = None
|
|
435
480
|
for param in sig.parameters.values():
|
|
436
481
|
if param.kind != param.POSITIONAL_ONLY and last_kind == param.POSITIONAL_ONLY:
|
|
437
482
|
# PEP-570: Separator for Positional Only Parameter: /
|
|
438
|
-
params += addnodes.desc_parameter(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
483
|
+
params += addnodes.desc_parameter(
|
|
484
|
+
'', '', addnodes.desc_sig_operator('', '/')
|
|
485
|
+
)
|
|
486
|
+
if param.kind == param.KEYWORD_ONLY and last_kind in {
|
|
487
|
+
param.POSITIONAL_OR_KEYWORD,
|
|
488
|
+
param.POSITIONAL_ONLY,
|
|
489
|
+
None,
|
|
490
|
+
}:
|
|
442
491
|
# PEP-3102: Separator for Keyword Only Parameter: *
|
|
443
|
-
params += addnodes.desc_parameter(
|
|
492
|
+
params += addnodes.desc_parameter(
|
|
493
|
+
'', '', addnodes.desc_sig_operator('', '*')
|
|
494
|
+
)
|
|
444
495
|
|
|
445
496
|
node = addnodes.desc_parameter()
|
|
446
497
|
if param.kind == param.VAR_POSITIONAL:
|
|
@@ -464,8 +515,9 @@ def _parse_arglist(
|
|
|
464
515
|
node += addnodes.desc_sig_space()
|
|
465
516
|
else:
|
|
466
517
|
node += addnodes.desc_sig_operator('', '=')
|
|
467
|
-
node += nodes.inline(
|
|
468
|
-
|
|
518
|
+
node += nodes.inline(
|
|
519
|
+
'', param.default, classes=['default_value'], support_smartquotes=False
|
|
520
|
+
)
|
|
469
521
|
|
|
470
522
|
params += node
|
|
471
523
|
last_kind = param.kind
|
|
@@ -478,9 +530,12 @@ def _parse_arglist(
|
|
|
478
530
|
|
|
479
531
|
|
|
480
532
|
def _pseudo_parse_arglist(
|
|
481
|
-
signode: desc_signature,
|
|
533
|
+
signode: desc_signature,
|
|
534
|
+
arglist: str,
|
|
535
|
+
multi_line_parameter_list: bool = False,
|
|
536
|
+
trailing_comma: bool = True,
|
|
482
537
|
) -> None:
|
|
483
|
-
"""
|
|
538
|
+
"""'Parse' a list of arguments separated by commas.
|
|
484
539
|
|
|
485
540
|
Arguments can have "optional" annotations given by enclosing them in
|
|
486
541
|
brackets. Currently, this will split at any comma, even if it's inside a
|
|
@@ -488,6 +543,7 @@ def _pseudo_parse_arglist(
|
|
|
488
543
|
"""
|
|
489
544
|
paramlist = addnodes.desc_parameterlist()
|
|
490
545
|
paramlist['multi_line_parameter_list'] = multi_line_parameter_list
|
|
546
|
+
paramlist['multi_line_trailing_comma'] = trailing_comma
|
|
491
547
|
stack: list[Element] = [paramlist]
|
|
492
548
|
try:
|
|
493
549
|
for argument in arglist.split(','):
|
|
@@ -508,7 +564,8 @@ def _pseudo_parse_arglist(
|
|
|
508
564
|
argument = argument[:-1].strip()
|
|
509
565
|
if argument:
|
|
510
566
|
stack[-1] += addnodes.desc_parameter(
|
|
511
|
-
'', '', addnodes.desc_sig_name(argument, argument)
|
|
567
|
+
'', '', addnodes.desc_sig_name(argument, argument)
|
|
568
|
+
)
|
|
512
569
|
while ends_open:
|
|
513
570
|
stack.append(addnodes.desc_optional())
|
|
514
571
|
stack[-2] += stack[-1]
|
|
@@ -517,7 +574,7 @@ def _pseudo_parse_arglist(
|
|
|
517
574
|
stack.pop()
|
|
518
575
|
ends_close -= 1
|
|
519
576
|
if len(stack) != 1:
|
|
520
|
-
raise IndexError
|
|
577
|
+
raise IndexError # NoQA: TRY301
|
|
521
578
|
except IndexError:
|
|
522
579
|
# if there are too few or too many elements on the stack, just give up
|
|
523
580
|
# and treat the whole argument list as one argument, discarding the
|