Sphinx 7.3.7__py3-none-any.whl → 7.4.1__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 +5 -6
- sphinx/_cli/__init__.py +296 -0
- sphinx/_cli/util/__init__.py +0 -0
- sphinx/_cli/util/colour.py +103 -0
- sphinx/_cli/util/errors.py +165 -0
- sphinx/application.py +78 -43
- sphinx/builders/__init__.py +59 -15
- sphinx/builders/_epub_base.py +11 -5
- sphinx/builders/changes.py +2 -2
- sphinx/builders/epub3.py +2 -2
- sphinx/builders/gettext.py +10 -10
- sphinx/builders/html/__init__.py +56 -54
- sphinx/builders/latex/__init__.py +5 -5
- sphinx/builders/latex/constants.py +5 -0
- sphinx/builders/linkcheck.py +73 -38
- sphinx/builders/texinfo.py +1 -1
- sphinx/cmd/build.py +1 -1
- sphinx/cmd/quickstart.py +11 -11
- sphinx/config.py +57 -38
- sphinx/directives/__init__.py +7 -9
- sphinx/directives/code.py +12 -15
- sphinx/directives/other.py +12 -15
- sphinx/directives/patches.py +26 -0
- sphinx/domains/__init__.py +1 -1
- sphinx/domains/c/__init__.py +5 -5
- sphinx/domains/c/_ast.py +436 -12
- sphinx/domains/c/_symbol.py +89 -134
- sphinx/domains/changeset.py +3 -4
- sphinx/domains/cpp/__init__.py +5 -6
- sphinx/domains/cpp/_ast.py +822 -25
- sphinx/domains/cpp/_symbol.py +3 -0
- sphinx/domains/javascript.py +3 -6
- sphinx/domains/math.py +3 -2
- sphinx/domains/python/__init__.py +44 -6
- sphinx/domains/python/_object.py +7 -5
- sphinx/domains/rst.py +2 -2
- sphinx/domains/std/__init__.py +95 -14
- sphinx/environment/__init__.py +35 -15
- sphinx/environment/adapters/indexentries.py +71 -24
- sphinx/environment/adapters/toctree.py +1 -1
- sphinx/environment/collectors/__init__.py +18 -4
- sphinx/environment/collectors/asset.py +4 -4
- sphinx/environment/collectors/toctree.py +27 -14
- sphinx/events.py +7 -6
- sphinx/ext/apidoc.py +377 -170
- sphinx/ext/autodoc/__init__.py +13 -13
- sphinx/ext/autodoc/directive.py +10 -13
- sphinx/ext/autodoc/mock.py +10 -7
- sphinx/ext/autodoc/preserve_defaults.py +1 -1
- sphinx/ext/autodoc/typehints.py +2 -2
- sphinx/ext/autosummary/__init__.py +15 -9
- sphinx/ext/autosummary/generate.py +270 -154
- sphinx/ext/coverage.py +108 -18
- sphinx/ext/duration.py +10 -3
- sphinx/ext/extlinks.py +3 -2
- sphinx/ext/graphviz.py +3 -3
- sphinx/ext/ifconfig.py +1 -2
- sphinx/ext/imgconverter.py +1 -0
- sphinx/ext/imgmath.py +7 -6
- sphinx/ext/inheritance_diagram.py +3 -3
- sphinx/ext/intersphinx/__init__.py +81 -0
- sphinx/ext/intersphinx/__main__.py +10 -0
- sphinx/ext/intersphinx/_cli.py +44 -0
- sphinx/ext/intersphinx/_load.py +253 -0
- sphinx/ext/{intersphinx.py → intersphinx/_resolve.py} +17 -368
- sphinx/ext/intersphinx/_shared.py +53 -0
- sphinx/ext/mathjax.py +1 -1
- sphinx/ext/todo.py +2 -2
- sphinx/io.py +2 -6
- sphinx/locale/__init__.py +1 -5
- sphinx/locale/ar/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ar/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ar/LC_MESSAGES/sphinx.po +678 -471
- sphinx/locale/bg/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/bg/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bg/LC_MESSAGES/sphinx.po +684 -476
- sphinx/locale/bn/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/bn/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/bn/LC_MESSAGES/sphinx.po +679 -472
- sphinx/locale/ca/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ca/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ca/LC_MESSAGES/sphinx.po +681 -474
- sphinx/locale/cak/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/cak/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cak/LC_MESSAGES/sphinx.po +678 -471
- sphinx/locale/cs/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/cs/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cs/LC_MESSAGES/sphinx.po +679 -472
- sphinx/locale/cy/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/cy/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/cy/LC_MESSAGES/sphinx.po +679 -472
- sphinx/locale/da/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/da/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/da/LC_MESSAGES/sphinx.po +679 -472
- sphinx/locale/de/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/de/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de/LC_MESSAGES/sphinx.po +679 -472
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/de_DE/LC_MESSAGES/sphinx.po +678 -471
- sphinx/locale/el/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/el/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/el/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_DE/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_FR/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_GB/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/en_HK/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/eo/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/eo/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eo/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/es/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/es/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/es_CO/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/et/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/et/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/et/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/eu/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/eu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/eu/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/fa/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/fa/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fa/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/fi/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/fi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fi/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/fr/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/fr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr/LC_MESSAGES/sphinx.po +725 -518
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/fr_FR/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/gl/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/gl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/gl/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/he/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/he/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/he/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/hi/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/hi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hi_IN/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/hr/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/hr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hr/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/hu/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/hu/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/hu/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/id/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/id/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/id/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/is/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/is/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/is/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/it/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/it/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/it/LC_MESSAGES/sphinx.po +708 -500
- sphinx/locale/ja/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ja/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ja/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/ka/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ka/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ka/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/ko/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ko/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ko/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/lt/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/lt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lt/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/lv/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/lv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/lv/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/mk/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/mk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/mk/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nb_NO/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/ne/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ne/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ne/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/nl/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/nl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/nl/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/pl/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/pl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pl/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/pt/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/pt/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_BR/LC_MESSAGES/sphinx.po +705 -498
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/pt_PT/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/ro/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ro/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ro/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/ru/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ru/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ru/LC_MESSAGES/sphinx.po +890 -680
- sphinx/locale/si/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/si/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/si/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/sk/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/sk/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sk/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/sl/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/sl/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sl/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/sphinx.pot +702 -494
- sphinx/locale/sq/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/sq/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sq/LC_MESSAGES/sphinx.po +704 -497
- sphinx/locale/sr/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/sr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/sr@latin/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sr_RS/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/sv/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/sv/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/ta/LC_MESSAGES/sphinx.po +1016 -808
- sphinx/locale/te/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/te/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/te/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/tr/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/tr/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/tr/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/uk_UA/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/ur/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/ur/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/ur/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/vi/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/vi/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/vi/LC_MESSAGES/sphinx.po +701 -494
- sphinx/locale/yue/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/yue/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/yue/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/zh_CN/LC_MESSAGES/sphinx.po +704 -496
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_HK/LC_MESSAGES/sphinx.po +700 -493
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW/LC_MESSAGES/sphinx.po +729 -522
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.js +1 -1
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.mo +0 -0
- sphinx/locale/zh_TW.Big5/LC_MESSAGES/sphinx.po +700 -493
- sphinx/roles.py +1 -1
- sphinx/search/__init__.py +17 -9
- sphinx/templates/quickstart/{root_doc.rst_t → root_doc.rst.jinja} +7 -10
- sphinx/testing/fixtures.py +22 -20
- sphinx/testing/path.py +6 -2
- sphinx/testing/util.py +8 -13
- sphinx/texinputs/sphinx.sty +449 -332
- sphinx/texinputs/sphinxlatexadmonitions.sty +209 -66
- sphinx/texinputs/sphinxlatexliterals.sty +9 -16
- sphinx/texinputs/sphinxlatexstyletext.sty +4 -38
- sphinx/texinputs/sphinxlatextables.sty +6 -14
- sphinx/texinputs/sphinxpackageboxes.sty +15 -42
- sphinx/texinputs/sphinxpackagefootnote.sty +4 -3
- sphinx/themes/agogo/layout.html +3 -3
- sphinx/themes/basic/genindex-single.html +2 -1
- sphinx/themes/basic/layout.html +3 -6
- sphinx/themes/basic/static/searchtools.js +4 -3
- sphinx/themes/haiku/layout.html +4 -4
- sphinx/themes/pyramid/layout.html +1 -1
- sphinx/themes/scrolls/layout.html +2 -2
- sphinx/theming.py +3 -3
- sphinx/transforms/__init__.py +34 -20
- sphinx/transforms/i18n.py +8 -7
- sphinx/transforms/post_transforms/__init__.py +1 -1
- sphinx/transforms/post_transforms/images.py +7 -10
- sphinx/util/_pathlib.py +2 -2
- sphinx/util/cfamily.py +52 -30
- sphinx/util/console.py +1 -1
- sphinx/util/display.py +16 -11
- sphinx/util/docutils.py +88 -40
- sphinx/util/fileutil.py +15 -3
- sphinx/util/images.py +1 -0
- sphinx/util/inspect.py +66 -22
- sphinx/util/inventory.py +15 -0
- sphinx/util/logging.py +14 -21
- sphinx/util/math.py +3 -1
- sphinx/util/nodes.py +9 -12
- sphinx/util/osutil.py +5 -5
- sphinx/util/parsing.py +93 -0
- sphinx/util/tags.py +71 -47
- sphinx/util/typing.py +265 -143
- sphinx/versioning.py +17 -17
- sphinx/writers/html5.py +26 -19
- sphinx/writers/latex.py +60 -30
- sphinx/writers/manpage.py +4 -3
- sphinx/writers/texinfo.py +19 -14
- {sphinx-7.3.7.dist-info → sphinx-7.4.1.dist-info}/METADATA +21 -20
- sphinx-7.4.1.dist-info/RECORD +591 -0
- sphinx-7.3.7.dist-info/RECORD +0 -581
- /sphinx/templates/apidoc/{module.rst_t → module.rst.jinja} +0 -0
- /sphinx/templates/apidoc/{package.rst_t → package.rst.jinja} +0 -0
- /sphinx/templates/apidoc/{toc.rst_t → toc.rst.jinja} +0 -0
- /sphinx/templates/epub3/{content.opf_t → content.opf.jinja} +0 -0
- /sphinx/templates/epub3/{nav.xhtml_t → nav.xhtml.jinja} +0 -0
- /sphinx/templates/epub3/{toc.ncx_t → toc.ncx.jinja} +0 -0
- /sphinx/templates/gettext/{message.pot_t → message.pot.jinja} +0 -0
- /sphinx/templates/imgmath/{preview.tex_t → preview.tex.jinja} +0 -0
- /sphinx/templates/imgmath/{template.tex_t → template.tex.jinja} +0 -0
- /sphinx/templates/latex/{latex.tex_t → latex.tex.jinja} +0 -0
- /sphinx/templates/latex/{longtable.tex_t → longtable.tex.jinja} +0 -0
- /sphinx/templates/latex/{sphinxmessages.sty_t → sphinxmessages.sty.jinja} +0 -0
- /sphinx/templates/latex/{tabular.tex_t → tabular.tex.jinja} +0 -0
- /sphinx/templates/latex/{tabulary.tex_t → tabulary.tex.jinja} +0 -0
- /sphinx/templates/quickstart/{Makefile_t → Makefile.jinja} +0 -0
- /sphinx/templates/quickstart/{Makefile.new_t → Makefile.new.jinja} +0 -0
- /sphinx/templates/quickstart/{conf.py_t → conf.py.jinja} +0 -0
- /sphinx/templates/quickstart/{make.bat_t → make.bat.jinja} +0 -0
- /sphinx/templates/quickstart/{make.bat.new_t → make.bat.new.jinja} +0 -0
- /sphinx/texinputs/{Makefile_t → Makefile.jinja} +0 -0
- /sphinx/texinputs/{latexmkjarc_t → latexmkjarc.jinja} +0 -0
- /sphinx/texinputs/{latexmkrc_t → latexmkrc.jinja} +0 -0
- /sphinx/texinputs/{make.bat_t → make.bat.jinja} +0 -0
- /sphinx/texinputs_win/{Makefile_t → Makefile.jinja} +0 -0
- /sphinx/themes/agogo/static/{agogo.css_t → agogo.css.jinja} +0 -0
- /sphinx/themes/basic/static/{basic.css_t → basic.css.jinja} +0 -0
- /sphinx/themes/basic/static/{documentation_options.js_t → documentation_options.js.jinja} +0 -0
- /sphinx/themes/basic/static/{language_data.js_t → language_data.js.jinja} +0 -0
- /sphinx/themes/bizstyle/static/{bizstyle.css_t → bizstyle.css.jinja} +0 -0
- /sphinx/themes/bizstyle/static/{bizstyle.js_t → bizstyle.js.jinja} +0 -0
- /sphinx/themes/classic/static/{classic.css_t → classic.css.jinja} +0 -0
- /sphinx/themes/classic/static/{sidebar.js_t → sidebar.js.jinja} +0 -0
- /sphinx/themes/epub/static/{epub.css_t → epub.css.jinja} +0 -0
- /sphinx/themes/haiku/static/{haiku.css_t → haiku.css.jinja} +0 -0
- /sphinx/themes/nature/static/{nature.css_t → nature.css.jinja} +0 -0
- /sphinx/themes/nonav/static/{nonav.css_t → nonav.css.jinja} +0 -0
- /sphinx/themes/pyramid/static/{epub.css_t → epub.css.jinja} +0 -0
- /sphinx/themes/pyramid/static/{pyramid.css_t → pyramid.css.jinja} +0 -0
- /sphinx/themes/scrolls/static/{scrolls.css_t → scrolls.css.jinja} +0 -0
- /sphinx/themes/sphinxdoc/static/{sphinxdoc.css_t → sphinxdoc.css.jinja} +0 -0
- /sphinx/themes/traditional/static/{traditional.css_t → traditional.css.jinja} +0 -0
- {sphinx-7.3.7.dist-info → sphinx-7.4.1.dist-info}/LICENSE.rst +0 -0
- {sphinx-7.3.7.dist-info → sphinx-7.4.1.dist-info}/WHEEL +0 -0
- {sphinx-7.3.7.dist-info → sphinx-7.4.1.dist-info}/entry_points.txt +0 -0
|
@@ -24,6 +24,7 @@ import pydoc
|
|
|
24
24
|
import re
|
|
25
25
|
import sys
|
|
26
26
|
from os import path
|
|
27
|
+
from pathlib import Path
|
|
27
28
|
from typing import TYPE_CHECKING, Any, NamedTuple
|
|
28
29
|
|
|
29
30
|
from jinja2 import TemplateNotFound
|
|
@@ -65,7 +66,7 @@ class DummyApplication:
|
|
|
65
66
|
self.config = Config()
|
|
66
67
|
self.registry = SphinxComponentRegistry()
|
|
67
68
|
self.messagelog: list[str] = []
|
|
68
|
-
self.srcdir =
|
|
69
|
+
self.srcdir = '/'
|
|
69
70
|
self.translator = translator
|
|
70
71
|
self.verbosity = 0
|
|
71
72
|
self._warncount = 0
|
|
@@ -98,10 +99,17 @@ def setup_documenters(app: Any) -> None:
|
|
|
98
99
|
ModuleDocumenter,
|
|
99
100
|
PropertyDocumenter,
|
|
100
101
|
)
|
|
102
|
+
|
|
101
103
|
documenters: list[type[Documenter]] = [
|
|
102
|
-
ModuleDocumenter,
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
ModuleDocumenter,
|
|
105
|
+
ClassDocumenter,
|
|
106
|
+
ExceptionDocumenter,
|
|
107
|
+
DataDocumenter,
|
|
108
|
+
FunctionDocumenter,
|
|
109
|
+
MethodDocumenter,
|
|
110
|
+
AttributeDocumenter,
|
|
111
|
+
DecoratorDocumenter,
|
|
112
|
+
PropertyDocumenter,
|
|
105
113
|
]
|
|
106
114
|
for documenter in documenters:
|
|
107
115
|
app.registry.add_documenter(documenter.objtype, documenter)
|
|
@@ -123,8 +131,9 @@ class AutosummaryRenderer:
|
|
|
123
131
|
raise ValueError(msg)
|
|
124
132
|
|
|
125
133
|
system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
|
|
126
|
-
loader = SphinxTemplateLoader(
|
|
127
|
-
|
|
134
|
+
loader = SphinxTemplateLoader(
|
|
135
|
+
app.srcdir, app.config.templates_path, system_templates_path
|
|
136
|
+
)
|
|
128
137
|
|
|
129
138
|
self.env = SandboxedEnvironment(loader=loader)
|
|
130
139
|
self.env.filters['escape'] = rst.escape
|
|
@@ -132,7 +141,7 @@ class AutosummaryRenderer:
|
|
|
132
141
|
self.env.filters['underline'] = _underline
|
|
133
142
|
|
|
134
143
|
if app.translator:
|
|
135
|
-
self.env.add_extension(
|
|
144
|
+
self.env.add_extension('jinja2.ext.i18n')
|
|
136
145
|
# ``install_gettext_translations`` is injected by the ``jinja2.ext.i18n`` extension
|
|
137
146
|
self.env.install_gettext_translations(app.translator) # type: ignore[attr-defined]
|
|
138
147
|
|
|
@@ -168,17 +177,17 @@ def _split_full_qualified_name(name: str) -> tuple[str | None, str]:
|
|
|
168
177
|
parts = name.split('.')
|
|
169
178
|
for i, _part in enumerate(parts, 1):
|
|
170
179
|
try:
|
|
171
|
-
modname =
|
|
180
|
+
modname = '.'.join(parts[:i])
|
|
172
181
|
importlib.import_module(modname)
|
|
173
182
|
except ImportError:
|
|
174
|
-
if parts[:i - 1]:
|
|
175
|
-
return
|
|
183
|
+
if parts[: i - 1]:
|
|
184
|
+
return '.'.join(parts[: i - 1]), '.'.join(parts[i - 1 :])
|
|
176
185
|
else:
|
|
177
|
-
return None,
|
|
186
|
+
return None, '.'.join(parts)
|
|
178
187
|
except IndexError:
|
|
179
188
|
pass
|
|
180
189
|
|
|
181
|
-
return name,
|
|
190
|
+
return name, ''
|
|
182
191
|
|
|
183
192
|
|
|
184
193
|
# -- Generating output ---------------------------------------------------------
|
|
@@ -194,12 +203,19 @@ class ModuleScanner:
|
|
|
194
203
|
|
|
195
204
|
def is_skipped(self, name: str, value: Any, objtype: str) -> bool:
|
|
196
205
|
try:
|
|
197
|
-
return self.app.emit_firstresult(
|
|
198
|
-
|
|
206
|
+
return self.app.emit_firstresult(
|
|
207
|
+
'autodoc-skip-member', objtype, name, value, False, {}
|
|
208
|
+
)
|
|
199
209
|
except Exception as exc:
|
|
200
|
-
logger.warning(
|
|
201
|
-
|
|
202
|
-
|
|
210
|
+
logger.warning(
|
|
211
|
+
__(
|
|
212
|
+
'autosummary: failed to determine %r to be documented, '
|
|
213
|
+
'the following exception was raised:\n%s'
|
|
214
|
+
),
|
|
215
|
+
name,
|
|
216
|
+
exc,
|
|
217
|
+
type='autosummary',
|
|
218
|
+
)
|
|
203
219
|
return False
|
|
204
220
|
|
|
205
221
|
def scan(self, imported_members: bool) -> list[str]:
|
|
@@ -257,12 +273,19 @@ def members_of(obj: Any, conf: Config) -> Sequence[str]:
|
|
|
257
273
|
return getall(obj) or dir(obj)
|
|
258
274
|
|
|
259
275
|
|
|
260
|
-
def generate_autosummary_content(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
276
|
+
def generate_autosummary_content(
|
|
277
|
+
name: str,
|
|
278
|
+
obj: Any,
|
|
279
|
+
parent: Any,
|
|
280
|
+
template: AutosummaryRenderer,
|
|
281
|
+
template_name: str,
|
|
282
|
+
imported_members: bool,
|
|
283
|
+
app: Any,
|
|
284
|
+
recursive: bool,
|
|
285
|
+
context: dict,
|
|
286
|
+
modname: str | None = None,
|
|
287
|
+
qualname: str | None = None,
|
|
288
|
+
) -> str:
|
|
266
289
|
doc = get_documenter(app, obj, parent)
|
|
267
290
|
|
|
268
291
|
ns: dict[str, Any] = {}
|
|
@@ -275,23 +298,25 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
|
|
|
275
298
|
respect_module_all = not app.config.autosummary_ignore_module_all
|
|
276
299
|
imported_members = imported_members or ('__all__' in dir(obj) and respect_module_all)
|
|
277
300
|
|
|
278
|
-
ns['functions'], ns['all_functions'] =
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
ns['
|
|
285
|
-
|
|
301
|
+
ns['functions'], ns['all_functions'] = _get_members(
|
|
302
|
+
doc, app, obj, {'function'}, imported=imported_members
|
|
303
|
+
)
|
|
304
|
+
ns['classes'], ns['all_classes'] = _get_members(
|
|
305
|
+
doc, app, obj, {'class'}, imported=imported_members
|
|
306
|
+
)
|
|
307
|
+
ns['exceptions'], ns['all_exceptions'] = _get_members(
|
|
308
|
+
doc, app, obj, {'exception'}, imported=imported_members
|
|
309
|
+
)
|
|
310
|
+
ns['attributes'], ns['all_attributes'] = _get_module_attrs(name, ns['members'])
|
|
286
311
|
ispackage = hasattr(obj, '__path__')
|
|
287
312
|
if ispackage and recursive:
|
|
288
313
|
# Use members that are not modules as skip list, because it would then mean
|
|
289
314
|
# that module was overwritten in the package namespace
|
|
290
315
|
skip = (
|
|
291
|
-
ns[
|
|
292
|
-
+ ns[
|
|
293
|
-
+ ns[
|
|
294
|
-
+ ns[
|
|
316
|
+
ns['all_functions']
|
|
317
|
+
+ ns['all_classes']
|
|
318
|
+
+ ns['all_exceptions']
|
|
319
|
+
+ ns['all_attributes']
|
|
295
320
|
)
|
|
296
321
|
|
|
297
322
|
# If respect_module_all and module has a __all__ attribute, first get
|
|
@@ -301,40 +326,44 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
|
|
|
301
326
|
#
|
|
302
327
|
# Otherwise, use get_modules method normally
|
|
303
328
|
if respect_module_all and '__all__' in dir(obj):
|
|
304
|
-
imported_modules, all_imported_modules =
|
|
305
|
-
|
|
329
|
+
imported_modules, all_imported_modules = _get_members(
|
|
330
|
+
doc, app, obj, {'module'}, imported=True
|
|
331
|
+
)
|
|
306
332
|
skip += all_imported_modules
|
|
307
333
|
imported_modules = [name + '.' + modname for modname in imported_modules]
|
|
308
|
-
all_imported_modules =
|
|
309
|
-
|
|
334
|
+
all_imported_modules = [
|
|
335
|
+
name + '.' + modname for modname in all_imported_modules
|
|
336
|
+
]
|
|
310
337
|
public_members = getall(obj)
|
|
311
338
|
else:
|
|
312
339
|
imported_modules, all_imported_modules = [], []
|
|
313
340
|
public_members = None
|
|
314
341
|
|
|
315
|
-
modules, all_modules = _get_modules(
|
|
316
|
-
|
|
342
|
+
modules, all_modules = _get_modules(
|
|
343
|
+
obj, skip=skip, name=name, public_members=public_members
|
|
344
|
+
)
|
|
317
345
|
ns['modules'] = imported_modules + modules
|
|
318
|
-
ns[
|
|
346
|
+
ns['all_modules'] = all_imported_modules + all_modules
|
|
319
347
|
elif doc.objtype == 'class':
|
|
320
348
|
ns['members'] = dir(obj)
|
|
321
|
-
ns['inherited_members'] =
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
ns['attributes'], ns['all_attributes'] =
|
|
326
|
-
|
|
349
|
+
ns['inherited_members'] = set(dir(obj)) - set(obj.__dict__.keys())
|
|
350
|
+
ns['methods'], ns['all_methods'] = _get_members(
|
|
351
|
+
doc, app, obj, {'method'}, include_public={'__init__'}
|
|
352
|
+
)
|
|
353
|
+
ns['attributes'], ns['all_attributes'] = _get_members(
|
|
354
|
+
doc, app, obj, {'attribute', 'property'}
|
|
355
|
+
)
|
|
327
356
|
|
|
328
357
|
if modname is None or qualname is None:
|
|
329
358
|
modname, qualname = _split_full_qualified_name(name)
|
|
330
359
|
|
|
331
360
|
if doc.objtype in ('method', 'attribute', 'property'):
|
|
332
|
-
ns['class'] = qualname.rsplit(
|
|
361
|
+
ns['class'] = qualname.rsplit('.', 1)[0]
|
|
333
362
|
|
|
334
363
|
if doc.objtype == 'class':
|
|
335
364
|
shortname = qualname
|
|
336
365
|
else:
|
|
337
|
-
shortname = qualname.rsplit(
|
|
366
|
+
shortname = qualname.rsplit('.', 1)[-1]
|
|
338
367
|
|
|
339
368
|
ns['fullname'] = name
|
|
340
369
|
ns['module'] = modname
|
|
@@ -352,12 +381,17 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any,
|
|
|
352
381
|
|
|
353
382
|
def _skip_member(app: Sphinx, obj: Any, name: str, objtype: str) -> bool:
|
|
354
383
|
try:
|
|
355
|
-
return app.emit_firstresult('autodoc-skip-member', objtype, name,
|
|
356
|
-
obj, False, {})
|
|
384
|
+
return app.emit_firstresult('autodoc-skip-member', objtype, name, obj, False, {})
|
|
357
385
|
except Exception as exc:
|
|
358
|
-
logger.warning(
|
|
359
|
-
|
|
360
|
-
|
|
386
|
+
logger.warning(
|
|
387
|
+
__(
|
|
388
|
+
'autosummary: failed to determine %r to be documented, '
|
|
389
|
+
'the following exception was raised:\n%s'
|
|
390
|
+
),
|
|
391
|
+
name,
|
|
392
|
+
exc,
|
|
393
|
+
type='autosummary',
|
|
394
|
+
)
|
|
361
395
|
return False
|
|
362
396
|
|
|
363
397
|
|
|
@@ -384,9 +418,15 @@ def _get_all_members(doc: type[Documenter], app: Sphinx, obj: Any) -> dict[str,
|
|
|
384
418
|
return {}
|
|
385
419
|
|
|
386
420
|
|
|
387
|
-
def _get_members(
|
|
388
|
-
|
|
389
|
-
|
|
421
|
+
def _get_members(
|
|
422
|
+
doc: type[Documenter],
|
|
423
|
+
app: Sphinx,
|
|
424
|
+
obj: Any,
|
|
425
|
+
types: set[str],
|
|
426
|
+
*,
|
|
427
|
+
include_public: Set[str] = frozenset(),
|
|
428
|
+
imported: bool = True,
|
|
429
|
+
) -> tuple[list[str], list[str]]:
|
|
390
430
|
items: list[str] = []
|
|
391
431
|
public: list[str] = []
|
|
392
432
|
|
|
@@ -423,20 +463,16 @@ def _get_module_attrs(name: str, members: Any) -> tuple[list[str], list[str]]:
|
|
|
423
463
|
if not attr_name.startswith('_'):
|
|
424
464
|
public.append(attr_name)
|
|
425
465
|
except PycodeError:
|
|
426
|
-
pass
|
|
466
|
+
pass # give up if ModuleAnalyzer fails to parse code
|
|
427
467
|
return public, attrs
|
|
428
468
|
|
|
429
469
|
|
|
430
470
|
def _get_modules(
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
skip: Sequence[str],
|
|
434
|
-
name: str,
|
|
435
|
-
public_members: Sequence[str] | None = None) -> tuple[list[str], list[str]]:
|
|
471
|
+
obj: Any, *, skip: Sequence[str], name: str, public_members: Sequence[str] | None = None
|
|
472
|
+
) -> tuple[list[str], list[str]]:
|
|
436
473
|
items: list[str] = []
|
|
437
474
|
public: list[str] = []
|
|
438
475
|
for _, modname, _ispkg in pkgutil.iter_modules(obj.__path__):
|
|
439
|
-
|
|
440
476
|
if modname in skip:
|
|
441
477
|
# module was overwritten in __init__.py, so not accessible
|
|
442
478
|
continue
|
|
@@ -458,20 +494,29 @@ def _get_modules(
|
|
|
458
494
|
return public, items
|
|
459
495
|
|
|
460
496
|
|
|
461
|
-
def generate_autosummary_docs(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
497
|
+
def generate_autosummary_docs(
|
|
498
|
+
sources: list[str],
|
|
499
|
+
output_dir: str | os.PathLike[str] | None = None,
|
|
500
|
+
suffix: str = '.rst',
|
|
501
|
+
base_path: str | os.PathLike[str] | None = None,
|
|
502
|
+
imported_members: bool = False,
|
|
503
|
+
app: Sphinx | None = None,
|
|
504
|
+
overwrite: bool = True,
|
|
505
|
+
encoding: str = 'utf-8',
|
|
506
|
+
) -> list[Path]:
|
|
507
|
+
"""Generate autosummary documentation for the given sources.
|
|
508
|
+
|
|
509
|
+
:returns: list of generated files (both new and existing ones)
|
|
510
|
+
"""
|
|
511
|
+
assert app is not None, 'app is required'
|
|
512
|
+
|
|
467
513
|
showed_sources = sorted(sources)
|
|
468
514
|
if len(showed_sources) > 20:
|
|
469
515
|
showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
|
|
470
|
-
logger.info(__('[autosummary] generating autosummary for: %s')
|
|
471
|
-
', '.join(showed_sources))
|
|
516
|
+
logger.info(__('[autosummary] generating autosummary for: %s'), ', '.join(showed_sources))
|
|
472
517
|
|
|
473
518
|
if output_dir:
|
|
474
|
-
logger.info(__('[autosummary] writing to %s')
|
|
519
|
+
logger.info(__('[autosummary] writing to %s'), output_dir)
|
|
475
520
|
|
|
476
521
|
if base_path is not None:
|
|
477
522
|
sources = [os.path.join(base_path, filename) for filename in sources]
|
|
@@ -482,12 +527,10 @@ def generate_autosummary_docs(sources: list[str],
|
|
|
482
527
|
items = find_autosummary_in_files(sources)
|
|
483
528
|
|
|
484
529
|
# keep track of new files
|
|
485
|
-
new_files = []
|
|
530
|
+
new_files: list[Path] = []
|
|
531
|
+
all_files: list[Path] = []
|
|
486
532
|
|
|
487
|
-
|
|
488
|
-
filename_map = app.config.autosummary_filename_map
|
|
489
|
-
else:
|
|
490
|
-
filename_map = {}
|
|
533
|
+
filename_map = app.config.autosummary_filename_map
|
|
491
534
|
|
|
492
535
|
# write
|
|
493
536
|
for entry in sorted(set(items), key=str):
|
|
@@ -501,57 +544,79 @@ def generate_autosummary_docs(sources: list[str],
|
|
|
501
544
|
|
|
502
545
|
try:
|
|
503
546
|
name, obj, parent, modname = import_by_name(entry.name)
|
|
504
|
-
qualname = name.replace(modname +
|
|
547
|
+
qualname = name.replace(modname + '.', '')
|
|
505
548
|
except ImportExceptionGroup as exc:
|
|
506
549
|
try:
|
|
507
550
|
# try to import as an instance attribute
|
|
508
551
|
name, obj, parent, modname = import_ivar_by_name(entry.name)
|
|
509
|
-
qualname = name.replace(modname +
|
|
552
|
+
qualname = name.replace(modname + '.', '')
|
|
510
553
|
except ImportError as exc2:
|
|
511
554
|
if exc2.__cause__:
|
|
512
555
|
exceptions: list[BaseException] = [*exc.exceptions, exc2.__cause__]
|
|
513
556
|
else:
|
|
514
557
|
exceptions = [*exc.exceptions, exc2]
|
|
515
558
|
|
|
516
|
-
errors = list({f
|
|
517
|
-
logger.warning(
|
|
518
|
-
|
|
559
|
+
errors = list({f'* {type(e).__name__}: {e}' for e in exceptions})
|
|
560
|
+
logger.warning(
|
|
561
|
+
__('[autosummary] failed to import %s.\nPossible hints:\n%s'),
|
|
562
|
+
entry.name,
|
|
563
|
+
'\n'.join(errors),
|
|
564
|
+
)
|
|
519
565
|
continue
|
|
520
566
|
|
|
521
|
-
context: dict[str, Any] = {}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
567
|
+
context: dict[str, Any] = {**app.config.autosummary_context}
|
|
568
|
+
|
|
569
|
+
content = generate_autosummary_content(
|
|
570
|
+
name,
|
|
571
|
+
obj,
|
|
572
|
+
parent,
|
|
573
|
+
template,
|
|
574
|
+
entry.template,
|
|
575
|
+
imported_members,
|
|
576
|
+
app,
|
|
577
|
+
entry.recursive,
|
|
578
|
+
context,
|
|
579
|
+
modname,
|
|
580
|
+
qualname,
|
|
581
|
+
)
|
|
582
|
+
|
|
583
|
+
file_path = Path(path, filename_map.get(name, name) + suffix)
|
|
584
|
+
all_files.append(file_path)
|
|
585
|
+
if file_path.is_file():
|
|
586
|
+
with file_path.open(encoding=encoding) as f:
|
|
532
587
|
old_content = f.read()
|
|
533
588
|
|
|
534
589
|
if content == old_content:
|
|
535
590
|
continue
|
|
536
591
|
if overwrite: # content has changed
|
|
537
|
-
with open(
|
|
592
|
+
with file_path.open('w', encoding=encoding) as f:
|
|
538
593
|
f.write(content)
|
|
539
|
-
new_files.append(
|
|
594
|
+
new_files.append(file_path)
|
|
540
595
|
else:
|
|
541
|
-
with open(
|
|
596
|
+
with open(file_path, 'w', encoding=encoding) as f:
|
|
542
597
|
f.write(content)
|
|
543
|
-
new_files.append(
|
|
598
|
+
new_files.append(file_path)
|
|
544
599
|
|
|
545
600
|
# descend recursively to new files
|
|
546
601
|
if new_files:
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
602
|
+
all_files.extend(
|
|
603
|
+
generate_autosummary_docs(
|
|
604
|
+
[str(f) for f in new_files],
|
|
605
|
+
output_dir=output_dir,
|
|
606
|
+
suffix=suffix,
|
|
607
|
+
base_path=base_path,
|
|
608
|
+
imported_members=imported_members,
|
|
609
|
+
app=app,
|
|
610
|
+
overwrite=overwrite,
|
|
611
|
+
)
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
return all_files
|
|
551
615
|
|
|
552
616
|
|
|
553
617
|
# -- Finding documented entries in files ---------------------------------------
|
|
554
618
|
|
|
619
|
+
|
|
555
620
|
def find_autosummary_in_files(filenames: list[str]) -> list[AutosummaryEntry]:
|
|
556
621
|
"""Find out what items are documented in source/*.rst.
|
|
557
622
|
|
|
@@ -566,7 +631,8 @@ def find_autosummary_in_files(filenames: list[str]) -> list[AutosummaryEntry]:
|
|
|
566
631
|
|
|
567
632
|
|
|
568
633
|
def find_autosummary_in_docstring(
|
|
569
|
-
name: str,
|
|
634
|
+
name: str,
|
|
635
|
+
filename: str | None = None,
|
|
570
636
|
) -> list[AutosummaryEntry]:
|
|
571
637
|
"""Find out what items are documented in the given object's docstring.
|
|
572
638
|
|
|
@@ -579,16 +645,21 @@ def find_autosummary_in_docstring(
|
|
|
579
645
|
except AttributeError:
|
|
580
646
|
pass
|
|
581
647
|
except ImportExceptionGroup as exc:
|
|
582
|
-
errors = '\n'.join({f
|
|
648
|
+
errors = '\n'.join({f'* {type(e).__name__}: {e}' for e in exc.exceptions})
|
|
583
649
|
logger.warning(f'Failed to import {name}.\nPossible hints:\n{errors}') # NoQA: G004
|
|
584
650
|
except SystemExit:
|
|
585
|
-
logger.warning(
|
|
586
|
-
|
|
651
|
+
logger.warning(
|
|
652
|
+
"Failed to import '%s'; the module executes module level "
|
|
653
|
+
'statement and it might call sys.exit().',
|
|
654
|
+
name,
|
|
655
|
+
)
|
|
587
656
|
return []
|
|
588
657
|
|
|
589
658
|
|
|
590
659
|
def find_autosummary_in_lines(
|
|
591
|
-
lines: list[str],
|
|
660
|
+
lines: list[str],
|
|
661
|
+
module: str | None = None,
|
|
662
|
+
filename: str | None = None,
|
|
592
663
|
) -> list[AutosummaryEntry]:
|
|
593
664
|
"""Find out what items appear in autosummary:: directives in the
|
|
594
665
|
given lines.
|
|
@@ -601,10 +672,8 @@ def find_autosummary_in_lines(
|
|
|
601
672
|
corresponding options set.
|
|
602
673
|
"""
|
|
603
674
|
autosummary_re = re.compile(r'^(\s*)\.\.\s+autosummary::\s*')
|
|
604
|
-
automodule_re = re.compile(
|
|
605
|
-
|
|
606
|
-
module_re = re.compile(
|
|
607
|
-
r'^\s*\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
|
|
675
|
+
automodule_re = re.compile(r'^\s*\.\.\s+automodule::\s*([A-Za-z0-9_.]+)\s*$')
|
|
676
|
+
module_re = re.compile(r'^\s*\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$')
|
|
608
677
|
autosummary_item_re = re.compile(r'^\s+(~?[_a-zA-Z][a-zA-Z0-9_.]*)\s*.*?')
|
|
609
678
|
recursive_arg_re = re.compile(r'^\s+:recursive:\s*$')
|
|
610
679
|
toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$')
|
|
@@ -617,7 +686,7 @@ def find_autosummary_in_lines(
|
|
|
617
686
|
template = ''
|
|
618
687
|
current_module = module
|
|
619
688
|
in_autosummary = False
|
|
620
|
-
base_indent =
|
|
689
|
+
base_indent = ''
|
|
621
690
|
|
|
622
691
|
for line in lines:
|
|
623
692
|
if in_autosummary:
|
|
@@ -630,8 +699,7 @@ def find_autosummary_in_lines(
|
|
|
630
699
|
if m:
|
|
631
700
|
toctree = m.group(1)
|
|
632
701
|
if filename:
|
|
633
|
-
toctree = os.path.join(os.path.dirname(filename),
|
|
634
|
-
toctree)
|
|
702
|
+
toctree = os.path.join(os.path.dirname(filename), toctree)
|
|
635
703
|
continue
|
|
636
704
|
|
|
637
705
|
m = template_arg_re.match(line)
|
|
@@ -647,13 +715,12 @@ def find_autosummary_in_lines(
|
|
|
647
715
|
name = m.group(1).strip()
|
|
648
716
|
if name.startswith('~'):
|
|
649
717
|
name = name[1:]
|
|
650
|
-
if current_module and
|
|
651
|
-
|
|
652
|
-
name = f"{current_module}.{name}"
|
|
718
|
+
if current_module and not name.startswith(current_module + '.'):
|
|
719
|
+
name = f'{current_module}.{name}'
|
|
653
720
|
documented.append(AutosummaryEntry(name, toctree, template, recursive))
|
|
654
721
|
continue
|
|
655
722
|
|
|
656
|
-
if not line.strip() or line.startswith(base_indent +
|
|
723
|
+
if not line.strip() or line.startswith(base_indent + ' '):
|
|
657
724
|
continue
|
|
658
725
|
|
|
659
726
|
in_autosummary = False
|
|
@@ -671,8 +738,7 @@ def find_autosummary_in_lines(
|
|
|
671
738
|
if m:
|
|
672
739
|
current_module = m.group(1).strip()
|
|
673
740
|
# recurse into the automodule docstring
|
|
674
|
-
documented.extend(find_autosummary_in_docstring(
|
|
675
|
-
current_module, filename=filename))
|
|
741
|
+
documented.extend(find_autosummary_in_docstring(current_module, filename=filename))
|
|
676
742
|
continue
|
|
677
743
|
|
|
678
744
|
m = module_re.match(line)
|
|
@@ -698,33 +764,69 @@ The format of the autosummary directive is documented in the
|
|
|
698
764
|
``sphinx.ext.autosummary`` Python module and can be read using::
|
|
699
765
|
|
|
700
766
|
pydoc sphinx.ext.autosummary
|
|
701
|
-
""")
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
767
|
+
"""),
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
parser.add_argument(
|
|
771
|
+
'--version',
|
|
772
|
+
action='version',
|
|
773
|
+
dest='show_version',
|
|
774
|
+
version='%%(prog)s %s' % __display_version__,
|
|
775
|
+
)
|
|
776
|
+
|
|
777
|
+
parser.add_argument(
|
|
778
|
+
'source_file', nargs='+', help=__('source files to generate rST files for')
|
|
779
|
+
)
|
|
780
|
+
|
|
781
|
+
parser.add_argument(
|
|
782
|
+
'-o',
|
|
783
|
+
'--output-dir',
|
|
784
|
+
action='store',
|
|
785
|
+
dest='output_dir',
|
|
786
|
+
help=__('directory to place all output in'),
|
|
787
|
+
)
|
|
788
|
+
parser.add_argument(
|
|
789
|
+
'-s',
|
|
790
|
+
'--suffix',
|
|
791
|
+
action='store',
|
|
792
|
+
dest='suffix',
|
|
793
|
+
default='rst',
|
|
794
|
+
help=__('default suffix for files (default: ' '%(default)s)'),
|
|
795
|
+
)
|
|
796
|
+
parser.add_argument(
|
|
797
|
+
'-t',
|
|
798
|
+
'--templates',
|
|
799
|
+
action='store',
|
|
800
|
+
dest='templates',
|
|
801
|
+
default=None,
|
|
802
|
+
help=__('custom template directory (default: ' '%(default)s)'),
|
|
803
|
+
)
|
|
804
|
+
parser.add_argument(
|
|
805
|
+
'-i',
|
|
806
|
+
'--imported-members',
|
|
807
|
+
action='store_true',
|
|
808
|
+
dest='imported_members',
|
|
809
|
+
default=False,
|
|
810
|
+
help=__('document imported members (default: ' '%(default)s)'),
|
|
811
|
+
)
|
|
812
|
+
parser.add_argument(
|
|
813
|
+
'-a',
|
|
814
|
+
'--respect-module-all',
|
|
815
|
+
action='store_true',
|
|
816
|
+
dest='respect_module_all',
|
|
817
|
+
default=False,
|
|
818
|
+
help=__(
|
|
819
|
+
'document exactly the members in module __all__ attribute. '
|
|
820
|
+
'(default: %(default)s)'
|
|
821
|
+
),
|
|
822
|
+
)
|
|
823
|
+
parser.add_argument(
|
|
824
|
+
'--remove-old',
|
|
825
|
+
action='store_true',
|
|
826
|
+
dest='remove_old',
|
|
827
|
+
default=False,
|
|
828
|
+
help=__('Remove existing files in the output directory that were not generated'),
|
|
829
|
+
)
|
|
728
830
|
|
|
729
831
|
return parser
|
|
730
832
|
|
|
@@ -740,14 +842,28 @@ def main(argv: Sequence[str] = (), /) -> None:
|
|
|
740
842
|
|
|
741
843
|
if args.templates:
|
|
742
844
|
app.config.templates_path.append(path.abspath(args.templates))
|
|
743
|
-
app.config.autosummary_ignore_module_all =
|
|
744
|
-
|
|
845
|
+
app.config.autosummary_ignore_module_all = not args.respect_module_all
|
|
846
|
+
|
|
847
|
+
written_files = generate_autosummary_docs(
|
|
848
|
+
args.source_file,
|
|
849
|
+
args.output_dir,
|
|
850
|
+
'.' + args.suffix,
|
|
851
|
+
imported_members=args.imported_members,
|
|
852
|
+
app=app, # type: ignore[arg-type]
|
|
745
853
|
)
|
|
746
854
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
855
|
+
if args.remove_old:
|
|
856
|
+
for existing in Path(args.output_dir).glob(f'**/*.{args.suffix}'):
|
|
857
|
+
if existing not in written_files:
|
|
858
|
+
try:
|
|
859
|
+
existing.unlink()
|
|
860
|
+
except OSError as exc:
|
|
861
|
+
logger.warning(
|
|
862
|
+
__('Failed to remove %s: %s'),
|
|
863
|
+
existing,
|
|
864
|
+
exc.strerror,
|
|
865
|
+
type='autosummary',
|
|
866
|
+
)
|
|
751
867
|
|
|
752
868
|
|
|
753
869
|
if __name__ == '__main__':
|