Sphinx 8.1.2__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 +837 -483
- 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.2.dist-info → sphinx-8.2.0rc1.dist-info}/LICENSE.rst +1 -1
- {sphinx-8.1.2.dist-info → sphinx-8.2.0rc1.dist-info}/METADATA +23 -15
- {sphinx-8.1.2.dist-info → sphinx-8.2.0rc1.dist-info}/RECORD +190 -186
- {sphinx-8.1.2.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.2.dist-info → sphinx-8.2.0rc1.dist-info}/entry_points.txt +0 -0
|
@@ -11,7 +11,7 @@ autosummary directive
|
|
|
11
11
|
The autosummary directive has the form::
|
|
12
12
|
|
|
13
13
|
.. autosummary::
|
|
14
|
-
:
|
|
14
|
+
:signatures: none
|
|
15
15
|
:toctree: generated/
|
|
16
16
|
|
|
17
17
|
module.function_1
|
|
@@ -51,14 +51,13 @@ from __future__ import annotations
|
|
|
51
51
|
import functools
|
|
52
52
|
import inspect
|
|
53
53
|
import operator
|
|
54
|
-
import os
|
|
55
54
|
import posixpath
|
|
56
55
|
import re
|
|
57
56
|
import sys
|
|
58
57
|
from inspect import Parameter
|
|
59
|
-
from
|
|
58
|
+
from pathlib import Path
|
|
60
59
|
from types import ModuleType
|
|
61
|
-
from typing import TYPE_CHECKING,
|
|
60
|
+
from typing import TYPE_CHECKING, cast
|
|
62
61
|
|
|
63
62
|
from docutils import nodes
|
|
64
63
|
from docutils.parsers.rst import directives
|
|
@@ -70,7 +69,7 @@ from sphinx import addnodes
|
|
|
70
69
|
from sphinx.config import Config
|
|
71
70
|
from sphinx.environment import BuildEnvironment
|
|
72
71
|
from sphinx.errors import PycodeError
|
|
73
|
-
from sphinx.ext.autodoc import INSTANCEATTR,
|
|
72
|
+
from sphinx.ext.autodoc import INSTANCEATTR, Options
|
|
74
73
|
from sphinx.ext.autodoc.directive import DocumenterBridge
|
|
75
74
|
from sphinx.ext.autodoc.importer import import_module
|
|
76
75
|
from sphinx.ext.autodoc.mock import mock
|
|
@@ -92,10 +91,12 @@ from sphinx.util.parsing import nested_parse_to_nodes
|
|
|
92
91
|
|
|
93
92
|
if TYPE_CHECKING:
|
|
94
93
|
from collections.abc import Sequence
|
|
94
|
+
from typing import Any, ClassVar
|
|
95
95
|
|
|
96
96
|
from docutils.nodes import Node, system_message
|
|
97
97
|
|
|
98
98
|
from sphinx.application import Sphinx
|
|
99
|
+
from sphinx.ext.autodoc import Documenter
|
|
99
100
|
from sphinx.extension import Extension
|
|
100
101
|
from sphinx.util.typing import ExtensionMetadata, OptionSpec
|
|
101
102
|
from sphinx.writers.html5 import HTML5Translator
|
|
@@ -111,6 +112,7 @@ WELL_KNOWN_ABBREVIATIONS = ('et al.', 'e.g.', 'i.e.')
|
|
|
111
112
|
|
|
112
113
|
# -- autosummary_toc node ------------------------------------------------------
|
|
113
114
|
|
|
115
|
+
|
|
114
116
|
class autosummary_toc(nodes.comment):
|
|
115
117
|
pass
|
|
116
118
|
|
|
@@ -126,23 +128,26 @@ def autosummary_noop(self: nodes.NodeVisitor, node: Node) -> None:
|
|
|
126
128
|
|
|
127
129
|
# -- autosummary_table node ----------------------------------------------------
|
|
128
130
|
|
|
131
|
+
|
|
129
132
|
class autosummary_table(nodes.comment):
|
|
130
133
|
pass
|
|
131
134
|
|
|
132
135
|
|
|
133
|
-
def autosummary_table_visit_html(
|
|
136
|
+
def autosummary_table_visit_html(
|
|
137
|
+
self: HTML5Translator, node: autosummary_table
|
|
138
|
+
) -> None:
|
|
134
139
|
"""Make the first column of the table non-breaking."""
|
|
135
140
|
try:
|
|
136
|
-
table = cast(nodes.table, node[0])
|
|
137
|
-
tgroup = cast(nodes.tgroup, table[0])
|
|
138
|
-
tbody = cast(nodes.tbody, tgroup[-1])
|
|
139
|
-
rows = cast(list[nodes.row], tbody)
|
|
141
|
+
table = cast('nodes.table', node[0])
|
|
142
|
+
tgroup = cast('nodes.tgroup', table[0])
|
|
143
|
+
tbody = cast('nodes.tbody', tgroup[-1])
|
|
144
|
+
rows = cast('list[nodes.row]', tbody)
|
|
140
145
|
for row in rows:
|
|
141
|
-
col1_entry = cast(nodes.entry, row[0])
|
|
142
|
-
par = cast(nodes.paragraph, col1_entry[0])
|
|
146
|
+
col1_entry = cast('nodes.entry', row[0])
|
|
147
|
+
par = cast('nodes.paragraph', col1_entry[0])
|
|
143
148
|
for j, subnode in enumerate(list(par)):
|
|
144
149
|
if isinstance(subnode, nodes.Text):
|
|
145
|
-
new_text = subnode.astext().replace(
|
|
150
|
+
new_text = subnode.astext().replace(' ', '\u00a0')
|
|
146
151
|
par[j] = nodes.Text(new_text)
|
|
147
152
|
except IndexError:
|
|
148
153
|
pass
|
|
@@ -150,14 +155,15 @@ def autosummary_table_visit_html(self: HTML5Translator, node: autosummary_table)
|
|
|
150
155
|
|
|
151
156
|
# -- autodoc integration -------------------------------------------------------
|
|
152
157
|
|
|
158
|
+
|
|
153
159
|
class FakeApplication:
|
|
154
160
|
verbosity = 0
|
|
155
161
|
|
|
156
162
|
def __init__(self) -> None:
|
|
157
|
-
self.doctreedir =
|
|
163
|
+
self.doctreedir = Path()
|
|
158
164
|
self.events = None
|
|
159
165
|
self.extensions: dict[str, Extension] = {}
|
|
160
|
-
self.srcdir =
|
|
166
|
+
self.srcdir = Path()
|
|
161
167
|
self.config = Config()
|
|
162
168
|
self.project = Project('', {})
|
|
163
169
|
self.registry = SphinxComponentRegistry()
|
|
@@ -174,7 +180,9 @@ class FakeDirective(DocumenterBridge):
|
|
|
174
180
|
super().__init__(env, None, Options(), 0, state)
|
|
175
181
|
|
|
176
182
|
|
|
177
|
-
def
|
|
183
|
+
def _get_documenter(
|
|
184
|
+
obj: Any, parent: Any, *, registry: SphinxComponentRegistry
|
|
185
|
+
) -> type[Documenter]:
|
|
178
186
|
"""Get an autodoc.Documenter class suitable for documenting the given
|
|
179
187
|
object.
|
|
180
188
|
|
|
@@ -190,18 +198,21 @@ def get_documenter(app: Sphinx, obj: Any, parent: Any) -> type[Documenter]:
|
|
|
190
198
|
|
|
191
199
|
# Construct a fake documenter for *parent*
|
|
192
200
|
if parent is not None:
|
|
193
|
-
parent_doc_cls =
|
|
201
|
+
parent_doc_cls = _get_documenter(parent, None, registry=registry)
|
|
194
202
|
else:
|
|
195
203
|
parent_doc_cls = ModuleDocumenter
|
|
196
204
|
|
|
197
205
|
if hasattr(parent, '__name__'):
|
|
198
206
|
parent_doc = parent_doc_cls(FakeDirective(), parent.__name__)
|
|
199
207
|
else:
|
|
200
|
-
parent_doc = parent_doc_cls(FakeDirective(),
|
|
208
|
+
parent_doc = parent_doc_cls(FakeDirective(), '')
|
|
201
209
|
|
|
202
210
|
# Get the correct documenter class for *obj*
|
|
203
|
-
classes = [
|
|
204
|
-
|
|
211
|
+
classes = [
|
|
212
|
+
cls
|
|
213
|
+
for cls in registry.documenters.values()
|
|
214
|
+
if cls.can_document_member(obj, '', False, parent_doc)
|
|
215
|
+
]
|
|
205
216
|
if classes:
|
|
206
217
|
classes.sort(key=lambda cls: cls.priority)
|
|
207
218
|
return classes[-1]
|
|
@@ -211,9 +222,9 @@ def get_documenter(app: Sphinx, obj: Any, parent: Any) -> type[Documenter]:
|
|
|
211
222
|
|
|
212
223
|
# -- .. autosummary:: ----------------------------------------------------------
|
|
213
224
|
|
|
225
|
+
|
|
214
226
|
class Autosummary(SphinxDirective):
|
|
215
|
-
"""
|
|
216
|
-
Pretty table containing short signatures and summaries of functions etc.
|
|
227
|
+
"""Pretty table containing short signatures and summaries of functions etc.
|
|
217
228
|
|
|
218
229
|
autosummary can also optionally generate a hidden toctree:: node.
|
|
219
230
|
"""
|
|
@@ -224,18 +235,24 @@ class Autosummary(SphinxDirective):
|
|
|
224
235
|
has_content = True
|
|
225
236
|
option_spec: ClassVar[OptionSpec] = {
|
|
226
237
|
'caption': directives.unchanged_required,
|
|
238
|
+
'class': directives.class_option,
|
|
227
239
|
'toctree': directives.unchanged,
|
|
228
240
|
'nosignatures': directives.flag,
|
|
229
241
|
'recursive': directives.flag,
|
|
242
|
+
'signatures': directives.unchanged,
|
|
230
243
|
'template': directives.unchanged,
|
|
231
244
|
}
|
|
232
245
|
|
|
233
246
|
def run(self) -> list[Node]:
|
|
234
|
-
self.bridge = DocumenterBridge(
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
247
|
+
self.bridge = DocumenterBridge(
|
|
248
|
+
self.env, self.state.document.reporter, Options(), self.lineno, self.state
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
names = [
|
|
252
|
+
x.strip().split()[0]
|
|
253
|
+
for x in self.content
|
|
254
|
+
if x.strip() and re.search(r'^[~a-zA-Z_]', x.strip()[0])
|
|
255
|
+
]
|
|
239
256
|
items = self.get_items(names)
|
|
240
257
|
nodes = self.get_table(items)
|
|
241
258
|
|
|
@@ -252,10 +269,14 @@ class Autosummary(SphinxDirective):
|
|
|
252
269
|
docname = posixpath.normpath(posixpath.join(dirname, docname))
|
|
253
270
|
if docname not in self.env.found_docs:
|
|
254
271
|
if excluded(str(self.env.doc2path(docname, False))):
|
|
255
|
-
msg = __(
|
|
272
|
+
msg = __(
|
|
273
|
+
'autosummary references excluded document %r. Ignored.'
|
|
274
|
+
)
|
|
256
275
|
else:
|
|
257
|
-
msg = __(
|
|
258
|
-
|
|
276
|
+
msg = __(
|
|
277
|
+
'autosummary: stub file not found %r. '
|
|
278
|
+
'Check your autosummary_generate setting.'
|
|
279
|
+
)
|
|
259
280
|
|
|
260
281
|
logger.warning(msg, real_name, location=self.get_location())
|
|
261
282
|
continue
|
|
@@ -273,13 +294,15 @@ class Autosummary(SphinxDirective):
|
|
|
273
294
|
nodes.append(autosummary_toc('', '', tocnode))
|
|
274
295
|
|
|
275
296
|
if 'toctree' not in self.options and 'caption' in self.options:
|
|
276
|
-
logger.warning(
|
|
277
|
-
|
|
297
|
+
logger.warning(
|
|
298
|
+
__('A captioned autosummary requires :toctree: option. ignored.'),
|
|
299
|
+
location=nodes[-1],
|
|
300
|
+
)
|
|
278
301
|
|
|
279
302
|
return nodes
|
|
280
303
|
|
|
281
304
|
def import_by_name(
|
|
282
|
-
self, name: str, prefixes: list[str | None]
|
|
305
|
+
self, name: str, prefixes: list[str | None]
|
|
283
306
|
) -> tuple[str, Any, Any, str]:
|
|
284
307
|
with mock(self.config.autosummary_mock_imports):
|
|
285
308
|
try:
|
|
@@ -296,23 +319,41 @@ class Autosummary(SphinxDirective):
|
|
|
296
319
|
|
|
297
320
|
raise ImportExceptionGroup(exc.args[0], errors) from None
|
|
298
321
|
|
|
299
|
-
def create_documenter(
|
|
300
|
-
|
|
322
|
+
def create_documenter(
|
|
323
|
+
self,
|
|
324
|
+
obj: Any,
|
|
325
|
+
parent: Any,
|
|
326
|
+
full_name: str,
|
|
327
|
+
*,
|
|
328
|
+
registry: SphinxComponentRegistry,
|
|
329
|
+
) -> Documenter:
|
|
301
330
|
"""Get an autodoc.Documenter class suitable for documenting the given
|
|
302
331
|
object.
|
|
303
332
|
|
|
304
|
-
Wraps
|
|
333
|
+
Wraps _get_documenter and is meant as a hook for extensions.
|
|
305
334
|
"""
|
|
306
|
-
doccls =
|
|
335
|
+
doccls = _get_documenter(obj, parent, registry=registry)
|
|
307
336
|
return doccls(self.bridge, full_name)
|
|
308
337
|
|
|
309
|
-
def get_items(self, names: list[str]) -> list[tuple[str, str, str, str]]:
|
|
338
|
+
def get_items(self, names: list[str]) -> list[tuple[str, str | None, str, str]]:
|
|
310
339
|
"""Try to import the given names, and return a list of
|
|
311
340
|
``[(name, signature, summary_string, real_name), ...]``.
|
|
341
|
+
|
|
342
|
+
signature is already formatted and is None if :nosignatures: option was given.
|
|
312
343
|
"""
|
|
313
344
|
prefixes = get_import_prefixes_from_env(self.env)
|
|
314
345
|
|
|
315
|
-
items: list[tuple[str, str, str, str]] = []
|
|
346
|
+
items: list[tuple[str, str | None, str, str]] = []
|
|
347
|
+
|
|
348
|
+
signatures_option = self.options.get('signatures')
|
|
349
|
+
if signatures_option is None:
|
|
350
|
+
signatures_option = 'none' if 'nosignatures' in self.options else 'long'
|
|
351
|
+
if signatures_option not in {'none', 'short', 'long'}:
|
|
352
|
+
msg = (
|
|
353
|
+
'Invalid value for autosummary :signatures: option: '
|
|
354
|
+
f"{signatures_option!r}. Valid values are 'none', 'short', 'long'"
|
|
355
|
+
)
|
|
356
|
+
raise ValueError(msg)
|
|
316
357
|
|
|
317
358
|
max_item_chars = 50
|
|
318
359
|
|
|
@@ -323,11 +364,17 @@ class Autosummary(SphinxDirective):
|
|
|
323
364
|
display_name = name.split('.')[-1]
|
|
324
365
|
|
|
325
366
|
try:
|
|
326
|
-
real_name, obj, parent, modname = self.import_by_name(
|
|
367
|
+
real_name, obj, parent, modname = self.import_by_name(
|
|
368
|
+
name, prefixes=prefixes
|
|
369
|
+
)
|
|
327
370
|
except ImportExceptionGroup as exc:
|
|
328
|
-
errors = list({f
|
|
329
|
-
logger.warning(
|
|
330
|
-
|
|
371
|
+
errors = list({f'* {type(e).__name__}: {e}' for e in exc.exceptions})
|
|
372
|
+
logger.warning(
|
|
373
|
+
__('autosummary: failed to import %s.\nPossible hints:\n%s'),
|
|
374
|
+
name,
|
|
375
|
+
'\n'.join(errors),
|
|
376
|
+
location=self.get_location(),
|
|
377
|
+
)
|
|
331
378
|
continue
|
|
332
379
|
|
|
333
380
|
self.bridge.result = StringList() # initialize for each documenter
|
|
@@ -335,25 +382,34 @@ class Autosummary(SphinxDirective):
|
|
|
335
382
|
if not isinstance(obj, ModuleType):
|
|
336
383
|
# give explicitly separated module name, so that members
|
|
337
384
|
# of inner classes can be documented
|
|
338
|
-
full_name = modname + '::' + full_name[len(modname) + 1:]
|
|
385
|
+
full_name = modname + '::' + full_name[len(modname) + 1 :]
|
|
339
386
|
# NB. using full_name here is important, since Documenters
|
|
340
387
|
# handle module prefixes slightly differently
|
|
341
|
-
documenter = self.create_documenter(
|
|
388
|
+
documenter = self.create_documenter(
|
|
389
|
+
obj, parent, full_name, registry=self.env._registry
|
|
390
|
+
)
|
|
342
391
|
if not documenter.parse_name():
|
|
343
|
-
logger.warning(
|
|
344
|
-
|
|
392
|
+
logger.warning(
|
|
393
|
+
__('failed to parse name %s'),
|
|
394
|
+
real_name,
|
|
395
|
+
location=self.get_location(),
|
|
396
|
+
)
|
|
345
397
|
items.append((display_name, '', '', real_name))
|
|
346
398
|
continue
|
|
347
399
|
if not documenter.import_object():
|
|
348
|
-
logger.warning(
|
|
349
|
-
|
|
400
|
+
logger.warning(
|
|
401
|
+
__('failed to import object %s'),
|
|
402
|
+
real_name,
|
|
403
|
+
location=self.get_location(),
|
|
404
|
+
)
|
|
350
405
|
items.append((display_name, '', '', real_name))
|
|
351
406
|
continue
|
|
352
407
|
|
|
353
408
|
# try to also get a source code analyzer for attribute docs
|
|
354
409
|
try:
|
|
355
410
|
documenter.analyzer = ModuleAnalyzer.for_module(
|
|
356
|
-
documenter.get_real_modname()
|
|
411
|
+
documenter.get_real_modname()
|
|
412
|
+
)
|
|
357
413
|
# parse right now, to get PycodeErrors on parsing (results will
|
|
358
414
|
# be cached anyway)
|
|
359
415
|
documenter.analyzer.find_attr_docs()
|
|
@@ -364,17 +420,22 @@ class Autosummary(SphinxDirective):
|
|
|
364
420
|
|
|
365
421
|
# -- Grab the signature
|
|
366
422
|
|
|
367
|
-
|
|
368
|
-
sig =
|
|
369
|
-
except TypeError:
|
|
370
|
-
# the documenter does not support ``show_annotation`` option
|
|
371
|
-
sig = documenter.format_signature()
|
|
372
|
-
|
|
373
|
-
if not sig:
|
|
374
|
-
sig = ''
|
|
423
|
+
if signatures_option == 'none':
|
|
424
|
+
sig = None
|
|
375
425
|
else:
|
|
376
|
-
|
|
377
|
-
|
|
426
|
+
try:
|
|
427
|
+
sig = documenter.format_signature(show_annotation=False)
|
|
428
|
+
except TypeError:
|
|
429
|
+
# the documenter does not support ``show_annotation`` option
|
|
430
|
+
sig = documenter.format_signature()
|
|
431
|
+
if not sig:
|
|
432
|
+
sig = ''
|
|
433
|
+
elif signatures_option == 'short':
|
|
434
|
+
if sig != '()':
|
|
435
|
+
sig = '(…)'
|
|
436
|
+
else: # signatures_option == 'long'
|
|
437
|
+
max_chars = max(10, max_item_chars - len(display_name))
|
|
438
|
+
sig = mangle_signature(sig, max_chars=max_chars)
|
|
378
439
|
|
|
379
440
|
# -- Grab the summary
|
|
380
441
|
|
|
@@ -388,7 +449,7 @@ class Autosummary(SphinxDirective):
|
|
|
388
449
|
|
|
389
450
|
return items
|
|
390
451
|
|
|
391
|
-
def get_table(self, items: list[tuple[str, str, str, str]]) -> list[Node]:
|
|
452
|
+
def get_table(self, items: list[tuple[str, str | None, str, str]]) -> list[Node]:
|
|
392
453
|
"""Generate a proper list of table nodes for autosummary:: directive.
|
|
393
454
|
|
|
394
455
|
*items* is a list produced by :meth:`get_items`.
|
|
@@ -397,7 +458,9 @@ class Autosummary(SphinxDirective):
|
|
|
397
458
|
table_spec['spec'] = r'\X{1}{2}\X{1}{2}'
|
|
398
459
|
|
|
399
460
|
table = autosummary_table('')
|
|
400
|
-
real_table = nodes.table(
|
|
461
|
+
real_table = nodes.table(
|
|
462
|
+
'', classes=['autosummary', 'longtable', *self.options.get('class', ())]
|
|
463
|
+
)
|
|
401
464
|
table.append(real_table)
|
|
402
465
|
group = nodes.tgroup('', cols=2)
|
|
403
466
|
real_table.append(group)
|
|
@@ -412,8 +475,9 @@ class Autosummary(SphinxDirective):
|
|
|
412
475
|
for text in column_texts:
|
|
413
476
|
vl = StringList([text], f'{source}:{line}:<autosummary>')
|
|
414
477
|
with switch_source_input(self.state, vl):
|
|
415
|
-
col_nodes = nested_parse_to_nodes(
|
|
416
|
-
|
|
478
|
+
col_nodes = nested_parse_to_nodes(
|
|
479
|
+
self.state, vl, allow_section_headings=False
|
|
480
|
+
)
|
|
417
481
|
if col_nodes and isinstance(col_nodes[0], nodes.paragraph):
|
|
418
482
|
node = col_nodes[0]
|
|
419
483
|
else:
|
|
@@ -423,10 +487,11 @@ class Autosummary(SphinxDirective):
|
|
|
423
487
|
|
|
424
488
|
for name, sig, summary, real_name in items:
|
|
425
489
|
qualifier = 'obj'
|
|
426
|
-
if
|
|
427
|
-
col1 = f':py:{qualifier}:`{name} <{real_name}>`\\ {rst.escape(sig)}'
|
|
428
|
-
else:
|
|
490
|
+
if sig is None:
|
|
429
491
|
col1 = f':py:{qualifier}:`{name} <{real_name}>`'
|
|
492
|
+
else:
|
|
493
|
+
col1 = f':py:{qualifier}:`{name} <{real_name}>`\\ {rst.escape(sig)}'
|
|
494
|
+
|
|
430
495
|
col2 = summary
|
|
431
496
|
append_row(col1, col2)
|
|
432
497
|
|
|
@@ -463,31 +528,33 @@ def mangle_signature(sig: str, max_chars: int = 30) -> str:
|
|
|
463
528
|
s = _cleanup_signature(sig)
|
|
464
529
|
|
|
465
530
|
# Strip return type annotation
|
|
466
|
-
s = re.sub(r
|
|
531
|
+
s = re.sub(r'\)\s*->\s.*$', ')', s)
|
|
467
532
|
|
|
468
533
|
# Remove parenthesis
|
|
469
|
-
s = re.sub(r
|
|
534
|
+
s = re.sub(r'^\((.*)\)$', r'\1', s).strip()
|
|
470
535
|
|
|
471
536
|
# Strip literals (which can contain things that confuse the code below)
|
|
472
|
-
s = re.sub(r
|
|
473
|
-
s = re.sub(r"\\'",
|
|
474
|
-
s = re.sub(r'\\"',
|
|
475
|
-
s = re.sub(r"'[^']*'",
|
|
476
|
-
s = re.sub(r'"[^"]*"',
|
|
537
|
+
s = re.sub(r'\\\\', '', s) # escaped backslash (maybe inside string)
|
|
538
|
+
s = re.sub(r"\\'", '', s) # escaped single quote
|
|
539
|
+
s = re.sub(r'\\"', '', s) # escaped double quote
|
|
540
|
+
s = re.sub(r"'[^']*'", '', s) # string literal (w/ single quote)
|
|
541
|
+
s = re.sub(r'"[^"]*"', '', s) # string literal (w/ double quote)
|
|
477
542
|
|
|
478
543
|
# Strip complex objects (maybe default value of arguments)
|
|
479
|
-
while re.search(
|
|
544
|
+
while re.search(
|
|
545
|
+
r'\([^)]*\)', s
|
|
546
|
+
): # contents of parenthesis (ex. NamedTuple(attr=...))
|
|
480
547
|
s = re.sub(r'\([^)]*\)', '', s)
|
|
481
|
-
while re.search(r'<[^>]*>', s):
|
|
548
|
+
while re.search(r'<[^>]*>', s): # contents of angle brackets (ex. <object>)
|
|
482
549
|
s = re.sub(r'<[^>]*>', '', s)
|
|
483
|
-
while re.search(r'{[^}]*}', s):
|
|
550
|
+
while re.search(r'{[^}]*}', s): # contents of curly brackets (ex. dict)
|
|
484
551
|
s = re.sub(r'{[^}]*}', '', s)
|
|
485
552
|
|
|
486
553
|
# Parse the signature to arguments + options
|
|
487
554
|
args: list[str] = []
|
|
488
555
|
opts: list[str] = []
|
|
489
556
|
|
|
490
|
-
opt_re = re.compile(r
|
|
557
|
+
opt_re = re.compile(r'^(.*, |)([a-zA-Z0-9_*]+)\s*=\s*')
|
|
491
558
|
while s:
|
|
492
559
|
m = opt_re.search(s)
|
|
493
560
|
if not m:
|
|
@@ -506,19 +573,21 @@ def mangle_signature(sig: str, max_chars: int = 30) -> str:
|
|
|
506
573
|
opts[i] = strip_arg_typehint(opt)
|
|
507
574
|
|
|
508
575
|
# Produce a more compact signature
|
|
509
|
-
sig = limited_join(
|
|
576
|
+
sig = limited_join(', ', args, max_chars=max_chars - 2)
|
|
510
577
|
if opts:
|
|
511
578
|
if not sig:
|
|
512
|
-
sig =
|
|
579
|
+
sig = '[%s]' % limited_join(', ', opts, max_chars=max_chars - 4)
|
|
513
580
|
elif len(sig) < max_chars - 4 - 2 - 3:
|
|
514
|
-
sig +=
|
|
515
|
-
|
|
581
|
+
sig += '[, %s]' % limited_join(
|
|
582
|
+
', ', opts, max_chars=max_chars - len(sig) - 4 - 2
|
|
583
|
+
)
|
|
516
584
|
|
|
517
|
-
return
|
|
585
|
+
return '(%s)' % sig
|
|
518
586
|
|
|
519
587
|
|
|
520
588
|
def extract_summary(doc: list[str], document: Any) -> str:
|
|
521
589
|
"""Extract summary from docstring."""
|
|
590
|
+
|
|
522
591
|
def parse(doc: list[str], settings: Any) -> nodes.document:
|
|
523
592
|
state_machine = RSTStateMachine(state_classes, 'Body')
|
|
524
593
|
node = new_document('', settings)
|
|
@@ -552,13 +621,13 @@ def extract_summary(doc: list[str], document: Any) -> str:
|
|
|
552
621
|
summary = doc[0].strip()
|
|
553
622
|
else:
|
|
554
623
|
# Try to find the "first sentence", which may span multiple lines
|
|
555
|
-
sentences = periods_re.split(
|
|
624
|
+
sentences = periods_re.split(' '.join(doc))
|
|
556
625
|
if len(sentences) == 1:
|
|
557
626
|
summary = sentences[0].strip()
|
|
558
627
|
else:
|
|
559
628
|
summary = ''
|
|
560
629
|
for i in range(len(sentences)):
|
|
561
|
-
summary =
|
|
630
|
+
summary = '. '.join(sentences[: i + 1]).rstrip('.') + '.'
|
|
562
631
|
node[:] = []
|
|
563
632
|
node = parse(doc, document.settings)
|
|
564
633
|
if summary.endswith(WELL_KNOWN_ABBREVIATIONS):
|
|
@@ -573,8 +642,9 @@ def extract_summary(doc: list[str], document: Any) -> str:
|
|
|
573
642
|
return summary
|
|
574
643
|
|
|
575
644
|
|
|
576
|
-
def limited_join(
|
|
577
|
-
|
|
645
|
+
def limited_join(
|
|
646
|
+
sep: str, items: list[str], max_chars: int = 30, overflow_marker: str = '...'
|
|
647
|
+
) -> str:
|
|
578
648
|
"""Join a number of strings into one, limiting the length to *max_chars*.
|
|
579
649
|
|
|
580
650
|
If the string overflows this limit, replace the last fitting item by
|
|
@@ -607,14 +677,15 @@ class ImportExceptionGroup(Exception):
|
|
|
607
677
|
It contains an error messages and a list of exceptions as its arguments.
|
|
608
678
|
"""
|
|
609
679
|
|
|
610
|
-
def __init__(
|
|
680
|
+
def __init__(
|
|
681
|
+
self, message: str | None, exceptions: Sequence[BaseException]
|
|
682
|
+
) -> None:
|
|
611
683
|
super().__init__(message)
|
|
612
684
|
self.exceptions = list(exceptions)
|
|
613
685
|
|
|
614
686
|
|
|
615
687
|
def get_import_prefixes_from_env(env: BuildEnvironment) -> list[str | None]:
|
|
616
|
-
"""
|
|
617
|
-
Obtain current Python import prefixes (for `import_by_name`)
|
|
688
|
+
"""Obtain current Python import prefixes (for `import_by_name`)
|
|
618
689
|
from ``document.env``
|
|
619
690
|
"""
|
|
620
691
|
prefixes: list[str | None] = [None]
|
|
@@ -626,7 +697,7 @@ def get_import_prefixes_from_env(env: BuildEnvironment) -> list[str | None]:
|
|
|
626
697
|
currclass = env.ref_context.get('py:class')
|
|
627
698
|
if currclass:
|
|
628
699
|
if currmodule:
|
|
629
|
-
prefixes.insert(0, currmodule
|
|
700
|
+
prefixes.insert(0, f'{currmodule}.{currclass}')
|
|
630
701
|
else:
|
|
631
702
|
prefixes.insert(0, currclass)
|
|
632
703
|
|
|
@@ -634,7 +705,7 @@ def get_import_prefixes_from_env(env: BuildEnvironment) -> list[str | None]:
|
|
|
634
705
|
|
|
635
706
|
|
|
636
707
|
def import_by_name(
|
|
637
|
-
name: str, prefixes: Sequence[str | None] = (None,)
|
|
708
|
+
name: str, prefixes: Sequence[str | None] = (None,)
|
|
638
709
|
) -> tuple[str, Any, Any, str]:
|
|
639
710
|
"""Import a Python object that has the given *name*, under one of the
|
|
640
711
|
*prefixes*. The first name that succeeds is used.
|
|
@@ -644,17 +715,26 @@ def import_by_name(
|
|
|
644
715
|
for prefix in prefixes:
|
|
645
716
|
if prefix is not None and name.startswith(f'{prefix}.'):
|
|
646
717
|
# Catch and avoid module cycles (e.g., sphinx.ext.sphinx.ext...)
|
|
647
|
-
msg = __(
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
718
|
+
msg = __(
|
|
719
|
+
'Summarised items should not include the current module. '
|
|
720
|
+
'Replace %r with %r.'
|
|
721
|
+
)
|
|
722
|
+
logger.warning(
|
|
723
|
+
msg,
|
|
724
|
+
name,
|
|
725
|
+
name.removeprefix(f'{prefix}.'),
|
|
726
|
+
type='autosummary',
|
|
727
|
+
subtype='import_cycle',
|
|
728
|
+
)
|
|
651
729
|
continue
|
|
652
730
|
try:
|
|
653
731
|
if prefix:
|
|
654
732
|
prefixed_name = f'{prefix}.{name}'
|
|
655
733
|
else:
|
|
656
734
|
prefixed_name = name
|
|
657
|
-
obj, parent, modname = _import_by_name(
|
|
735
|
+
obj, parent, modname = _import_by_name(
|
|
736
|
+
prefixed_name, grouped_exception=True
|
|
737
|
+
)
|
|
658
738
|
return prefixed_name, obj, parent, modname
|
|
659
739
|
except ImportError:
|
|
660
740
|
tried.append(prefixed_name)
|
|
@@ -663,7 +743,8 @@ def import_by_name(
|
|
|
663
743
|
errors.append(exc)
|
|
664
744
|
|
|
665
745
|
exceptions: list[BaseException] = functools.reduce(
|
|
666
|
-
operator.iadd, (e.exceptions for e in errors), []
|
|
746
|
+
operator.iadd, (e.exceptions for e in errors), []
|
|
747
|
+
)
|
|
667
748
|
raise ImportExceptionGroup('no module named %s' % ' or '.join(tried), exceptions)
|
|
668
749
|
|
|
669
750
|
|
|
@@ -714,13 +795,14 @@ def _import_by_name(name: str, grouped_exception: bool = True) -> tuple[Any, Any
|
|
|
714
795
|
raise ImportError(*exc.args) from exc
|
|
715
796
|
|
|
716
797
|
|
|
717
|
-
def import_ivar_by_name(
|
|
718
|
-
|
|
798
|
+
def import_ivar_by_name(
|
|
799
|
+
name: str, prefixes: Sequence[str | None] = (None,), grouped_exception: bool = True
|
|
800
|
+
) -> tuple[str, Any, Any, str]:
|
|
719
801
|
"""Import an instance variable that has the given *name*, under one of the
|
|
720
802
|
*prefixes*. The first name that succeeds is used.
|
|
721
803
|
"""
|
|
722
804
|
try:
|
|
723
|
-
name, attr = name.rsplit(
|
|
805
|
+
name, attr = name.rsplit('.', 1)
|
|
724
806
|
real_name, obj, parent, modname = import_by_name(name, prefixes)
|
|
725
807
|
|
|
726
808
|
# Get ancestors of the object (class.__mro__ includes the class itself as
|
|
@@ -730,14 +812,16 @@ def import_ivar_by_name(name: str, prefixes: Sequence[str | None] = (None,),
|
|
|
730
812
|
candidate_objects = (obj,)
|
|
731
813
|
|
|
732
814
|
for candidate_obj in candidate_objects:
|
|
733
|
-
analyzer = ModuleAnalyzer.for_module(
|
|
815
|
+
analyzer = ModuleAnalyzer.for_module(
|
|
816
|
+
getattr(candidate_obj, '__module__', modname)
|
|
817
|
+
)
|
|
734
818
|
analyzer.analyze()
|
|
735
819
|
# check for presence in `annotations` to include dataclass attributes
|
|
736
820
|
found_attrs = set()
|
|
737
821
|
found_attrs |= {attr for (qualname, attr) in analyzer.attr_docs}
|
|
738
822
|
found_attrs |= {attr for (qualname, attr) in analyzer.annotations}
|
|
739
823
|
if attr in found_attrs:
|
|
740
|
-
return real_name
|
|
824
|
+
return f'{real_name}.{attr}', INSTANCEATTR, obj, modname
|
|
741
825
|
except (ImportError, ValueError, PycodeError) as exc:
|
|
742
826
|
raise ImportError from exc
|
|
743
827
|
except ImportExceptionGroup:
|
|
@@ -748,6 +832,7 @@ def import_ivar_by_name(name: str, prefixes: Sequence[str | None] = (None,),
|
|
|
748
832
|
|
|
749
833
|
# -- :autolink: (smart default role) -------------------------------------------
|
|
750
834
|
|
|
835
|
+
|
|
751
836
|
class AutoLink(SphinxRole):
|
|
752
837
|
"""Smart linking role.
|
|
753
838
|
|
|
@@ -758,13 +843,20 @@ class AutoLink(SphinxRole):
|
|
|
758
843
|
def run(self) -> tuple[list[Node], list[system_message]]:
|
|
759
844
|
pyobj_role = self.env.domains.python_domain.role('obj')
|
|
760
845
|
assert pyobj_role is not None
|
|
761
|
-
objects, errors = pyobj_role(
|
|
762
|
-
|
|
846
|
+
objects, errors = pyobj_role(
|
|
847
|
+
'obj',
|
|
848
|
+
self.rawtext,
|
|
849
|
+
self.text,
|
|
850
|
+
self.lineno,
|
|
851
|
+
self.inliner,
|
|
852
|
+
self.options,
|
|
853
|
+
self.content,
|
|
854
|
+
)
|
|
763
855
|
if errors:
|
|
764
856
|
return objects, errors
|
|
765
857
|
|
|
766
858
|
assert len(objects) == 1
|
|
767
|
-
pending_xref = cast(addnodes.pending_xref, objects[0])
|
|
859
|
+
pending_xref = cast('addnodes.pending_xref', objects[0])
|
|
768
860
|
try:
|
|
769
861
|
# try to import object by name
|
|
770
862
|
prefixes = get_import_prefixes_from_env(self.env)
|
|
@@ -777,9 +869,10 @@ class AutoLink(SphinxRole):
|
|
|
777
869
|
]
|
|
778
870
|
import_by_name(name, prefixes)
|
|
779
871
|
except ImportExceptionGroup:
|
|
780
|
-
literal = cast(nodes.literal, pending_xref[0])
|
|
781
|
-
objects[0] = nodes.emphasis(
|
|
782
|
-
|
|
872
|
+
literal = cast('nodes.literal', pending_xref[0])
|
|
873
|
+
objects[0] = nodes.emphasis(
|
|
874
|
+
self.rawtext, literal.astext(), classes=literal['classes']
|
|
875
|
+
)
|
|
783
876
|
|
|
784
877
|
return objects, errors
|
|
785
878
|
|
|
@@ -803,18 +896,23 @@ def process_generate_options(app: Sphinx) -> None:
|
|
|
803
896
|
genfiles = app.config.autosummary_generate
|
|
804
897
|
|
|
805
898
|
if genfiles is True:
|
|
806
|
-
env = app.
|
|
807
|
-
genfiles = [
|
|
808
|
-
|
|
899
|
+
env = app.env
|
|
900
|
+
genfiles = [
|
|
901
|
+
str(env.doc2path(x, base=False))
|
|
902
|
+
for x in env.found_docs
|
|
903
|
+
if env.doc2path(x).is_file()
|
|
904
|
+
]
|
|
809
905
|
elif genfiles is False:
|
|
810
906
|
pass
|
|
811
907
|
else:
|
|
812
908
|
ext = list(app.config.source_suffix)
|
|
813
|
-
genfiles = [
|
|
814
|
-
|
|
909
|
+
genfiles = [
|
|
910
|
+
genfile + (ext[0] if not genfile.endswith(tuple(ext)) else '')
|
|
911
|
+
for genfile in genfiles
|
|
912
|
+
]
|
|
815
913
|
|
|
816
914
|
for entry in genfiles[:]:
|
|
817
|
-
if not
|
|
915
|
+
if not (app.srcdir / entry).is_file():
|
|
818
916
|
logger.warning(__('autosummary_generate: file not found: %s'), entry)
|
|
819
917
|
genfiles.remove(entry)
|
|
820
918
|
|
|
@@ -823,45 +921,75 @@ def process_generate_options(app: Sphinx) -> None:
|
|
|
823
921
|
|
|
824
922
|
suffix = get_rst_suffix(app)
|
|
825
923
|
if suffix is None:
|
|
826
|
-
logger.warning(
|
|
827
|
-
|
|
924
|
+
logger.warning(
|
|
925
|
+
__(
|
|
926
|
+
'autosummary generates .rst files internally. '
|
|
927
|
+
'But your source_suffix does not contain .rst. Skipped.'
|
|
928
|
+
)
|
|
929
|
+
)
|
|
828
930
|
return
|
|
829
931
|
|
|
830
932
|
from sphinx.ext.autosummary.generate import generate_autosummary_docs
|
|
831
933
|
|
|
832
934
|
imported_members = app.config.autosummary_imported_members
|
|
833
935
|
with mock(app.config.autosummary_mock_imports):
|
|
834
|
-
generate_autosummary_docs(
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
936
|
+
generate_autosummary_docs(
|
|
937
|
+
genfiles,
|
|
938
|
+
suffix=suffix,
|
|
939
|
+
base_path=app.srcdir,
|
|
940
|
+
app=app,
|
|
941
|
+
imported_members=imported_members,
|
|
942
|
+
overwrite=app.config.autosummary_generate_overwrite,
|
|
943
|
+
encoding=app.config.source_encoding,
|
|
944
|
+
)
|
|
838
945
|
|
|
839
946
|
|
|
840
947
|
def setup(app: Sphinx) -> ExtensionMetadata:
|
|
841
948
|
# I need autodoc
|
|
842
949
|
app.setup_extension('sphinx.ext.autodoc')
|
|
843
|
-
app.add_node(
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
950
|
+
app.add_node(
|
|
951
|
+
autosummary_toc,
|
|
952
|
+
html=(autosummary_toc_visit_html, autosummary_noop),
|
|
953
|
+
latex=(autosummary_noop, autosummary_noop),
|
|
954
|
+
text=(autosummary_noop, autosummary_noop),
|
|
955
|
+
man=(autosummary_noop, autosummary_noop),
|
|
956
|
+
texinfo=(autosummary_noop, autosummary_noop),
|
|
957
|
+
)
|
|
958
|
+
app.add_node(
|
|
959
|
+
autosummary_table,
|
|
960
|
+
html=(autosummary_table_visit_html, autosummary_noop),
|
|
961
|
+
latex=(autosummary_noop, autosummary_noop),
|
|
962
|
+
text=(autosummary_noop, autosummary_noop),
|
|
963
|
+
man=(autosummary_noop, autosummary_noop),
|
|
964
|
+
texinfo=(autosummary_noop, autosummary_noop),
|
|
965
|
+
)
|
|
855
966
|
app.add_directive('autosummary', Autosummary)
|
|
856
967
|
app.add_role('autolink', AutoLink())
|
|
857
968
|
app.connect('builder-inited', process_generate_options)
|
|
858
|
-
app.add_config_value('autosummary_context', {}, 'env')
|
|
859
|
-
app.add_config_value(
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
app.add_config_value(
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
app.add_config_value(
|
|
866
|
-
|
|
867
|
-
|
|
969
|
+
app.add_config_value('autosummary_context', {}, 'env', types=frozenset({dict}))
|
|
970
|
+
app.add_config_value(
|
|
971
|
+
'autosummary_filename_map', {}, 'html', types=frozenset({dict})
|
|
972
|
+
)
|
|
973
|
+
app.add_config_value(
|
|
974
|
+
'autosummary_generate', True, 'env', types=frozenset({bool, list})
|
|
975
|
+
)
|
|
976
|
+
app.add_config_value(
|
|
977
|
+
'autosummary_generate_overwrite', True, '', types=frozenset({bool})
|
|
978
|
+
)
|
|
979
|
+
app.add_config_value(
|
|
980
|
+
'autosummary_mock_imports',
|
|
981
|
+
lambda config: config.autodoc_mock_imports,
|
|
982
|
+
'env',
|
|
983
|
+
types=frozenset({list, tuple}),
|
|
984
|
+
)
|
|
985
|
+
app.add_config_value(
|
|
986
|
+
'autosummary_imported_members', False, '', types=frozenset({bool})
|
|
987
|
+
)
|
|
988
|
+
app.add_config_value(
|
|
989
|
+
'autosummary_ignore_module_all', True, 'env', types=frozenset({bool})
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
return {
|
|
993
|
+
'version': sphinx.__display_version__,
|
|
994
|
+
'parallel_read_safe': True,
|
|
995
|
+
}
|