Sphinx 7.3.6__py3-none-any.whl → 7.4.0__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 +45 -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 +42 -7
- 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 +261 -143
- sphinx/versioning.py +17 -17
- sphinx/writers/html5.py +26 -19
- sphinx/writers/latex.py +58 -28
- sphinx/writers/manpage.py +4 -3
- sphinx/writers/texinfo.py +19 -14
- {sphinx-7.3.6.dist-info → sphinx-7.4.0.dist-info}/METADATA +21 -20
- sphinx-7.4.0.dist-info/RECORD +591 -0
- sphinx-7.3.6.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.6.dist-info → sphinx-7.4.0.dist-info}/LICENSE.rst +0 -0
- {sphinx-7.3.6.dist-info → sphinx-7.4.0.dist-info}/WHEEL +0 -0
- {sphinx-7.3.6.dist-info → sphinx-7.4.0.dist-info}/entry_points.txt +0 -0
sphinx/ext/apidoc.py
CHANGED
|
@@ -21,7 +21,8 @@ import sys
|
|
|
21
21
|
from copy import copy
|
|
22
22
|
from importlib.machinery import EXTENSION_SUFFIXES
|
|
23
23
|
from os import path
|
|
24
|
-
from
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import TYPE_CHECKING, Any, Protocol
|
|
25
26
|
|
|
26
27
|
import sphinx.locale
|
|
27
28
|
from sphinx import __display_version__, package_dir
|
|
@@ -52,9 +53,9 @@ PY_SUFFIXES = ('.py', '.pyx', *tuple(EXTENSION_SUFFIXES))
|
|
|
52
53
|
template_dir = path.join(package_dir, 'templates', 'apidoc')
|
|
53
54
|
|
|
54
55
|
|
|
55
|
-
def is_initpy(filename: str) -> bool:
|
|
56
|
+
def is_initpy(filename: str | Path) -> bool:
|
|
56
57
|
"""Check *filename* is __init__ file or not."""
|
|
57
|
-
basename =
|
|
58
|
+
basename = Path(filename).name
|
|
58
59
|
return any(
|
|
59
60
|
basename == '__init__' + suffix
|
|
60
61
|
for suffix in sorted(PY_SUFFIXES, key=len, reverse=True)
|
|
@@ -76,27 +77,27 @@ def is_packagedir(dirname: str | None = None, files: list[str] | None = None) ->
|
|
|
76
77
|
return any(f for f in files if is_initpy(f))
|
|
77
78
|
|
|
78
79
|
|
|
79
|
-
def write_file(name: str, text: str, opts:
|
|
80
|
+
def write_file(name: str, text: str, opts: CliOptions) -> Path:
|
|
80
81
|
"""Write the output file for module/package <name>."""
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
fname = path.join(opts.destdir, f'{name}.{opts.suffix}')
|
|
82
|
+
fname = Path(opts.destdir, f'{name}.{opts.suffix}')
|
|
84
83
|
if opts.dryrun:
|
|
85
|
-
if not quiet:
|
|
84
|
+
if not opts.quiet:
|
|
86
85
|
logger.info(__('Would create file %s.'), fname)
|
|
87
|
-
return
|
|
88
|
-
if not opts.force and
|
|
89
|
-
if not quiet:
|
|
86
|
+
return fname
|
|
87
|
+
if not opts.force and fname.is_file():
|
|
88
|
+
if not opts.quiet:
|
|
90
89
|
logger.info(__('File %s already exists, skipping.'), fname)
|
|
91
90
|
else:
|
|
92
|
-
if not quiet:
|
|
91
|
+
if not opts.quiet:
|
|
93
92
|
logger.info(__('Creating file %s.'), fname)
|
|
94
93
|
with FileAvoidWrite(fname) as f:
|
|
95
94
|
f.write(text)
|
|
95
|
+
return fname
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
def create_module_file(
|
|
99
|
-
|
|
98
|
+
def create_module_file(
|
|
99
|
+
package: str | None, basename: str, opts: CliOptions, user_template_dir: str | None = None
|
|
100
|
+
) -> Path:
|
|
100
101
|
"""Build the text of the file and write the file."""
|
|
101
102
|
options = copy(OPTIONS)
|
|
102
103
|
if opts.includeprivate and 'private-members' not in options:
|
|
@@ -113,28 +114,41 @@ def create_module_file(package: str | None, basename: str, opts: Any,
|
|
|
113
114
|
template_path = [user_template_dir, template_dir]
|
|
114
115
|
else:
|
|
115
116
|
template_path = [template_dir]
|
|
116
|
-
text = ReSTRenderer(template_path).render('module.
|
|
117
|
-
write_file(qualname, text, opts)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def create_package_file(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
text = ReSTRenderer(template_path).render('module.rst.jinja', context)
|
|
118
|
+
return write_file(qualname, text, opts)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def create_package_file(
|
|
122
|
+
root: str,
|
|
123
|
+
master_package: str | None,
|
|
124
|
+
subroot: str,
|
|
125
|
+
py_files: list[str],
|
|
126
|
+
opts: CliOptions,
|
|
127
|
+
subs: list[str],
|
|
128
|
+
is_namespace: bool,
|
|
129
|
+
excludes: Sequence[re.Pattern[str]] = (),
|
|
130
|
+
user_template_dir: str | None = None,
|
|
131
|
+
) -> list[Path]:
|
|
132
|
+
"""Build the text of the file and write the file.
|
|
133
|
+
|
|
134
|
+
Also create submodules if necessary.
|
|
135
|
+
|
|
136
|
+
:returns: list of written files
|
|
137
|
+
"""
|
|
127
138
|
# build a list of sub packages (directories containing an __init__ file)
|
|
128
|
-
subpackages = [
|
|
129
|
-
|
|
130
|
-
|
|
139
|
+
subpackages = [
|
|
140
|
+
module_join(master_package, subroot, pkgname)
|
|
141
|
+
for pkgname in subs
|
|
142
|
+
if not is_skipped_package(Path(root, pkgname), opts, excludes)
|
|
143
|
+
]
|
|
131
144
|
# build a list of sub modules
|
|
132
|
-
submodules = [
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
submodules = [
|
|
146
|
+
sub.split('.')[0]
|
|
147
|
+
for sub in py_files
|
|
148
|
+
if not is_skipped_module(Path(root, sub), opts, excludes) and not is_initpy(sub)
|
|
149
|
+
]
|
|
135
150
|
submodules = sorted(set(submodules))
|
|
136
|
-
submodules = [module_join(master_package, subroot, modname)
|
|
137
|
-
for modname in submodules]
|
|
151
|
+
submodules = [module_join(master_package, subroot, modname) for modname in submodules]
|
|
138
152
|
options = copy(OPTIONS)
|
|
139
153
|
if opts.includeprivate and 'private-members' not in options:
|
|
140
154
|
options.append('private-members')
|
|
@@ -155,16 +169,27 @@ def create_package_file(root: str, master_package: str | None, subroot: str,
|
|
|
155
169
|
template_path = [user_template_dir, template_dir]
|
|
156
170
|
else:
|
|
157
171
|
template_path = [template_dir]
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
|
|
173
|
+
written: list[Path] = []
|
|
174
|
+
|
|
175
|
+
text = ReSTRenderer(template_path).render('package.rst.jinja', context)
|
|
176
|
+
written.append(write_file(pkgname, text, opts))
|
|
160
177
|
|
|
161
178
|
if submodules and opts.separatemodules:
|
|
162
|
-
|
|
179
|
+
written.extend([
|
|
163
180
|
create_module_file(None, submodule, opts, user_template_dir)
|
|
181
|
+
for submodule in submodules
|
|
182
|
+
])
|
|
164
183
|
|
|
184
|
+
return written
|
|
165
185
|
|
|
166
|
-
|
|
167
|
-
|
|
186
|
+
|
|
187
|
+
def create_modules_toc_file(
|
|
188
|
+
modules: list[str],
|
|
189
|
+
opts: CliOptions,
|
|
190
|
+
name: str = 'modules',
|
|
191
|
+
user_template_dir: str | None = None,
|
|
192
|
+
) -> Path:
|
|
168
193
|
"""Create the module's index."""
|
|
169
194
|
modules.sort()
|
|
170
195
|
prev_module = ''
|
|
@@ -184,87 +209,99 @@ def create_modules_toc_file(modules: list[str], opts: Any, name: str = 'modules'
|
|
|
184
209
|
template_path = [user_template_dir, template_dir]
|
|
185
210
|
else:
|
|
186
211
|
template_path = [template_dir]
|
|
187
|
-
text = ReSTRenderer(template_path).render('toc.
|
|
188
|
-
write_file(name, text, opts)
|
|
212
|
+
text = ReSTRenderer(template_path).render('toc.rst.jinja', context)
|
|
213
|
+
return write_file(name, text, opts)
|
|
189
214
|
|
|
190
215
|
|
|
191
|
-
def is_skipped_package(
|
|
192
|
-
|
|
216
|
+
def is_skipped_package(
|
|
217
|
+
dirname: str | Path, opts: CliOptions, excludes: Sequence[re.Pattern[str]] = ()
|
|
218
|
+
) -> bool:
|
|
193
219
|
"""Check if we want to skip this module."""
|
|
194
|
-
if not
|
|
220
|
+
if not Path(dirname).is_dir():
|
|
195
221
|
return False
|
|
196
222
|
|
|
197
|
-
files = glob.glob(
|
|
223
|
+
files = glob.glob(str(Path(dirname, '*.py')))
|
|
198
224
|
regular_package = any(f for f in files if is_initpy(f))
|
|
199
225
|
if not regular_package and not opts.implicit_namespaces:
|
|
200
226
|
# *dirname* is not both a regular package and an implicit namespace package
|
|
201
227
|
return True
|
|
202
228
|
|
|
203
229
|
# Check there is some showable module inside package
|
|
204
|
-
return all(is_excluded(
|
|
230
|
+
return all(is_excluded(Path(dirname, f), excludes) for f in files)
|
|
205
231
|
|
|
206
232
|
|
|
207
|
-
def is_skipped_module(
|
|
233
|
+
def is_skipped_module(
|
|
234
|
+
filename: str | Path, opts: CliOptions, _excludes: Sequence[re.Pattern[str]]
|
|
235
|
+
) -> bool:
|
|
208
236
|
"""Check if we want to skip this module."""
|
|
209
|
-
|
|
237
|
+
filename = Path(filename)
|
|
238
|
+
if not filename.exists():
|
|
210
239
|
# skip if the file doesn't exist
|
|
211
240
|
return True
|
|
212
241
|
# skip if the module has a "private" name
|
|
213
|
-
return
|
|
242
|
+
return filename.name.startswith('_') and not opts.includeprivate
|
|
214
243
|
|
|
215
244
|
|
|
216
|
-
def walk(
|
|
217
|
-
|
|
245
|
+
def walk(
|
|
246
|
+
rootpath: str,
|
|
247
|
+
excludes: Sequence[re.Pattern[str]],
|
|
248
|
+
opts: CliOptions,
|
|
249
|
+
) -> Iterator[tuple[str, list[str], list[str]]]:
|
|
218
250
|
"""Walk through the directory and list files and subdirectories up."""
|
|
219
|
-
|
|
220
|
-
includeprivate = getattr(opts, 'includeprivate', False)
|
|
221
|
-
|
|
222
|
-
for root, subs, files in os.walk(rootpath, followlinks=followlinks):
|
|
251
|
+
for root, subs, files in os.walk(rootpath, followlinks=opts.followlinks):
|
|
223
252
|
# document only Python module files (that aren't excluded)
|
|
224
|
-
files = sorted(
|
|
225
|
-
|
|
226
|
-
|
|
253
|
+
files = sorted(
|
|
254
|
+
f
|
|
255
|
+
for f in files
|
|
256
|
+
if f.endswith(PY_SUFFIXES) and not is_excluded(Path(root, f), excludes)
|
|
257
|
+
)
|
|
227
258
|
|
|
228
259
|
# remove hidden ('.') and private ('_') directories, as well as
|
|
229
260
|
# excluded dirs
|
|
230
|
-
if includeprivate:
|
|
261
|
+
if opts.includeprivate:
|
|
231
262
|
exclude_prefixes: tuple[str, ...] = ('.',)
|
|
232
263
|
else:
|
|
233
264
|
exclude_prefixes = ('.', '_')
|
|
234
265
|
|
|
235
|
-
subs[:] = sorted(
|
|
236
|
-
|
|
266
|
+
subs[:] = sorted(
|
|
267
|
+
sub
|
|
268
|
+
for sub in subs
|
|
269
|
+
if not sub.startswith(exclude_prefixes)
|
|
270
|
+
and not is_excluded(Path(root, sub), excludes)
|
|
271
|
+
)
|
|
237
272
|
|
|
238
273
|
yield root, subs, files
|
|
239
274
|
|
|
240
275
|
|
|
241
|
-
def has_child_module(
|
|
276
|
+
def has_child_module(
|
|
277
|
+
rootpath: str, excludes: Sequence[re.Pattern[str]], opts: CliOptions
|
|
278
|
+
) -> bool:
|
|
242
279
|
"""Check the given directory contains child module/s (at least one)."""
|
|
243
|
-
return any(
|
|
244
|
-
files
|
|
245
|
-
for _root, _subs, files in walk(rootpath, excludes, opts)
|
|
246
|
-
)
|
|
280
|
+
return any(files for _root, _subs, files in walk(rootpath, excludes, opts))
|
|
247
281
|
|
|
248
282
|
|
|
249
|
-
def recurse_tree(
|
|
250
|
-
|
|
283
|
+
def recurse_tree(
|
|
284
|
+
rootpath: str,
|
|
285
|
+
excludes: Sequence[re.Pattern[str]],
|
|
286
|
+
opts: CliOptions,
|
|
287
|
+
user_template_dir: str | None = None,
|
|
288
|
+
) -> tuple[list[Path], list[str]]:
|
|
251
289
|
"""
|
|
252
290
|
Look for every file in the directory tree and create the corresponding
|
|
253
291
|
ReST files.
|
|
254
292
|
"""
|
|
255
|
-
implicit_namespaces = getattr(opts, 'implicit_namespaces', False)
|
|
256
|
-
|
|
257
293
|
# check if the base directory is a package and get its name
|
|
258
|
-
if is_packagedir(rootpath) or implicit_namespaces:
|
|
294
|
+
if is_packagedir(rootpath) or opts.implicit_namespaces:
|
|
259
295
|
root_package = rootpath.split(path.sep)[-1]
|
|
260
296
|
else:
|
|
261
297
|
# otherwise, the base is a directory with packages
|
|
262
298
|
root_package = None
|
|
263
299
|
|
|
264
300
|
toplevels = []
|
|
301
|
+
written_files = []
|
|
265
302
|
for root, subs, files in walk(rootpath, excludes, opts):
|
|
266
303
|
is_pkg = is_packagedir(None, files)
|
|
267
|
-
is_namespace = not is_pkg and implicit_namespaces
|
|
304
|
+
is_namespace = not is_pkg and opts.implicit_namespaces
|
|
268
305
|
if is_pkg:
|
|
269
306
|
for f in files.copy():
|
|
270
307
|
if is_initpy(f):
|
|
@@ -272,48 +309,59 @@ def recurse_tree(rootpath: str, excludes: Sequence[re.Pattern[str]], opts: Any,
|
|
|
272
309
|
files.insert(0, f)
|
|
273
310
|
elif root != rootpath:
|
|
274
311
|
# only accept non-package at toplevel unless using implicit namespaces
|
|
275
|
-
if not implicit_namespaces:
|
|
312
|
+
if not opts.implicit_namespaces:
|
|
276
313
|
subs.clear()
|
|
277
314
|
continue
|
|
278
315
|
|
|
279
316
|
if is_pkg or is_namespace:
|
|
280
317
|
# we are in a package with something to document
|
|
281
318
|
if subs or len(files) > 1 or not is_skipped_package(root, opts):
|
|
282
|
-
subpackage = root[len(rootpath):].lstrip(path.sep)
|
|
283
|
-
replace(path.sep, '.')
|
|
319
|
+
subpackage = root[len(rootpath) :].lstrip(path.sep).replace(path.sep, '.')
|
|
284
320
|
# if this is not a namespace or
|
|
285
321
|
# a namespace and there is something there to document
|
|
286
322
|
if not is_namespace or has_child_module(root, excludes, opts):
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
323
|
+
written_files.extend(
|
|
324
|
+
create_package_file(
|
|
325
|
+
root,
|
|
326
|
+
root_package,
|
|
327
|
+
subpackage,
|
|
328
|
+
files,
|
|
329
|
+
opts,
|
|
330
|
+
subs,
|
|
331
|
+
is_namespace,
|
|
332
|
+
excludes,
|
|
333
|
+
user_template_dir,
|
|
334
|
+
)
|
|
335
|
+
)
|
|
290
336
|
toplevels.append(module_join(root_package, subpackage))
|
|
291
337
|
else:
|
|
292
338
|
# if we are at the root level, we don't require it to be a package
|
|
293
339
|
assert root == rootpath
|
|
294
340
|
assert root_package is None
|
|
295
341
|
for py_file in files:
|
|
296
|
-
if not is_skipped_module(
|
|
342
|
+
if not is_skipped_module(Path(rootpath, py_file), opts, excludes):
|
|
297
343
|
module = py_file.split('.')[0]
|
|
298
|
-
|
|
344
|
+
written_files.append(
|
|
345
|
+
create_module_file(root_package, module, opts, user_template_dir)
|
|
346
|
+
)
|
|
299
347
|
toplevels.append(module)
|
|
300
348
|
|
|
301
|
-
return toplevels
|
|
349
|
+
return written_files, toplevels
|
|
302
350
|
|
|
303
351
|
|
|
304
|
-
def is_excluded(root: str, excludes: Sequence[re.Pattern[str]]) -> bool:
|
|
352
|
+
def is_excluded(root: str | Path, excludes: Sequence[re.Pattern[str]]) -> bool:
|
|
305
353
|
"""Check if the directory is in the exclude list.
|
|
306
354
|
|
|
307
355
|
Note: by having trailing slashes, we avoid common prefix issues, like
|
|
308
356
|
e.g. an exclude "foo" also accidentally excluding "foobar".
|
|
309
357
|
"""
|
|
310
|
-
|
|
358
|
+
root_str = str(root)
|
|
359
|
+
return any(exclude.match(root_str) for exclude in excludes)
|
|
311
360
|
|
|
312
361
|
|
|
313
362
|
def get_parser() -> argparse.ArgumentParser:
|
|
314
363
|
parser = argparse.ArgumentParser(
|
|
315
|
-
usage='%(prog)s [OPTIONS] -o <OUTPUT_PATH> <MODULE_PATH> '
|
|
316
|
-
'[EXCLUDE_PATTERN, ...]',
|
|
364
|
+
usage='%(prog)s [OPTIONS] -o <OUTPUT_PATH> <MODULE_PATH> ' '[EXCLUDE_PATTERN, ...]',
|
|
317
365
|
epilog=__('For more information, visit <https://www.sphinx-doc.org/>.'),
|
|
318
366
|
description=__("""
|
|
319
367
|
Look recursively in <MODULE_PATH> for Python modules and packages and create
|
|
@@ -322,98 +370,243 @@ one reST file with automodule directives per package in the <OUTPUT_PATH>.
|
|
|
322
370
|
The <EXCLUDE_PATTERN>s can be file and/or directory patterns that will be
|
|
323
371
|
excluded from generation.
|
|
324
372
|
|
|
325
|
-
Note: By default this script will not overwrite already created files.""")
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
parser.add_argument(
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
parser.add_argument(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
parser.add_argument(
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
373
|
+
Note: By default this script will not overwrite already created files."""),
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
parser.add_argument(
|
|
377
|
+
'--version',
|
|
378
|
+
action='version',
|
|
379
|
+
dest='show_version',
|
|
380
|
+
version='%%(prog)s %s' % __display_version__,
|
|
381
|
+
)
|
|
382
|
+
|
|
383
|
+
parser.add_argument('module_path', help=__('path to module to document'))
|
|
384
|
+
parser.add_argument(
|
|
385
|
+
'exclude_pattern',
|
|
386
|
+
nargs='*',
|
|
387
|
+
help=__('fnmatch-style file and/or directory patterns ' 'to exclude from generation'),
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
parser.add_argument(
|
|
391
|
+
'-o',
|
|
392
|
+
'--output-dir',
|
|
393
|
+
action='store',
|
|
394
|
+
dest='destdir',
|
|
395
|
+
required=True,
|
|
396
|
+
help=__('directory to place all output'),
|
|
397
|
+
)
|
|
398
|
+
parser.add_argument(
|
|
399
|
+
'-q',
|
|
400
|
+
action='store_true',
|
|
401
|
+
dest='quiet',
|
|
402
|
+
help=__('no output on stdout, just warnings on stderr'),
|
|
403
|
+
)
|
|
404
|
+
parser.add_argument(
|
|
405
|
+
'-d',
|
|
406
|
+
'--maxdepth',
|
|
407
|
+
action='store',
|
|
408
|
+
dest='maxdepth',
|
|
409
|
+
type=int,
|
|
410
|
+
default=4,
|
|
411
|
+
help=__('maximum depth of submodules to show in the TOC ' '(default: 4)'),
|
|
412
|
+
)
|
|
413
|
+
parser.add_argument(
|
|
414
|
+
'-f', '--force', action='store_true', dest='force', help=__('overwrite existing files')
|
|
415
|
+
)
|
|
416
|
+
parser.add_argument(
|
|
417
|
+
'-l',
|
|
418
|
+
'--follow-links',
|
|
419
|
+
action='store_true',
|
|
420
|
+
dest='followlinks',
|
|
421
|
+
default=False,
|
|
422
|
+
help=__(
|
|
423
|
+
'follow symbolic links. Powerful when combined ' 'with collective.recipe.omelette.'
|
|
424
|
+
),
|
|
425
|
+
)
|
|
426
|
+
parser.add_argument(
|
|
427
|
+
'-n',
|
|
428
|
+
'--dry-run',
|
|
429
|
+
action='store_true',
|
|
430
|
+
dest='dryrun',
|
|
431
|
+
help=__('run the script without creating files'),
|
|
432
|
+
)
|
|
433
|
+
parser.add_argument(
|
|
434
|
+
'-e',
|
|
435
|
+
'--separate',
|
|
436
|
+
action='store_true',
|
|
437
|
+
dest='separatemodules',
|
|
438
|
+
help=__('put documentation for each module on its own page'),
|
|
439
|
+
)
|
|
440
|
+
parser.add_argument(
|
|
441
|
+
'-P',
|
|
442
|
+
'--private',
|
|
443
|
+
action='store_true',
|
|
444
|
+
dest='includeprivate',
|
|
445
|
+
help=__('include "_private" modules'),
|
|
446
|
+
)
|
|
447
|
+
parser.add_argument(
|
|
448
|
+
'--tocfile',
|
|
449
|
+
action='store',
|
|
450
|
+
dest='tocfile',
|
|
451
|
+
default='modules',
|
|
452
|
+
help=__('filename of table of contents (default: modules)'),
|
|
453
|
+
)
|
|
454
|
+
parser.add_argument(
|
|
455
|
+
'-T',
|
|
456
|
+
'--no-toc',
|
|
457
|
+
action='store_false',
|
|
458
|
+
dest='tocfile',
|
|
459
|
+
help=__("don't create a table of contents file"),
|
|
460
|
+
)
|
|
461
|
+
parser.add_argument(
|
|
462
|
+
'-E',
|
|
463
|
+
'--no-headings',
|
|
464
|
+
action='store_true',
|
|
465
|
+
dest='noheadings',
|
|
466
|
+
help=__(
|
|
467
|
+
"don't create headings for the module/package "
|
|
468
|
+
'packages (e.g. when the docstrings already '
|
|
469
|
+
'contain them)'
|
|
470
|
+
),
|
|
471
|
+
)
|
|
472
|
+
parser.add_argument(
|
|
473
|
+
'-M',
|
|
474
|
+
'--module-first',
|
|
475
|
+
action='store_true',
|
|
476
|
+
dest='modulefirst',
|
|
477
|
+
help=__('put module documentation before submodule ' 'documentation'),
|
|
478
|
+
)
|
|
479
|
+
parser.add_argument(
|
|
480
|
+
'--implicit-namespaces',
|
|
481
|
+
action='store_true',
|
|
482
|
+
dest='implicit_namespaces',
|
|
483
|
+
help=__(
|
|
484
|
+
'interpret module paths according to PEP-0420 ' 'implicit namespaces specification'
|
|
485
|
+
),
|
|
486
|
+
)
|
|
487
|
+
parser.add_argument(
|
|
488
|
+
'-s',
|
|
489
|
+
'--suffix',
|
|
490
|
+
action='store',
|
|
491
|
+
dest='suffix',
|
|
492
|
+
default='rst',
|
|
493
|
+
help=__('file suffix (default: rst)'),
|
|
494
|
+
)
|
|
495
|
+
exclusive_group = parser.add_mutually_exclusive_group()
|
|
496
|
+
exclusive_group.add_argument(
|
|
497
|
+
'--remove-old',
|
|
498
|
+
action='store_true',
|
|
499
|
+
dest='remove_old',
|
|
500
|
+
help=__('Remove existing files in the output directory that were not generated'),
|
|
501
|
+
)
|
|
502
|
+
exclusive_group.add_argument(
|
|
503
|
+
'-F',
|
|
504
|
+
'--full',
|
|
505
|
+
action='store_true',
|
|
506
|
+
dest='full',
|
|
507
|
+
help=__('generate a full project with sphinx-quickstart'),
|
|
508
|
+
)
|
|
509
|
+
parser.add_argument(
|
|
510
|
+
'-a',
|
|
511
|
+
'--append-syspath',
|
|
512
|
+
action='store_true',
|
|
513
|
+
dest='append_syspath',
|
|
514
|
+
help=__('append module_path to sys.path, used when --full is given'),
|
|
515
|
+
)
|
|
516
|
+
parser.add_argument(
|
|
517
|
+
'-H',
|
|
518
|
+
'--doc-project',
|
|
519
|
+
action='store',
|
|
520
|
+
dest='header',
|
|
521
|
+
help=__('project name (default: root module name)'),
|
|
522
|
+
)
|
|
523
|
+
parser.add_argument(
|
|
524
|
+
'-A',
|
|
525
|
+
'--doc-author',
|
|
526
|
+
action='store',
|
|
527
|
+
dest='author',
|
|
528
|
+
help=__('project author(s), used when --full is given'),
|
|
529
|
+
)
|
|
530
|
+
parser.add_argument(
|
|
531
|
+
'-V',
|
|
532
|
+
'--doc-version',
|
|
533
|
+
action='store',
|
|
534
|
+
dest='version',
|
|
535
|
+
help=__('project version, used when --full is given'),
|
|
536
|
+
)
|
|
537
|
+
parser.add_argument(
|
|
538
|
+
'-R',
|
|
539
|
+
'--doc-release',
|
|
540
|
+
action='store',
|
|
541
|
+
dest='release',
|
|
542
|
+
help=__('project release, used when --full is given, ' 'defaults to --doc-version'),
|
|
543
|
+
)
|
|
393
544
|
|
|
394
545
|
group = parser.add_argument_group(__('extension options'))
|
|
395
|
-
group.add_argument(
|
|
396
|
-
|
|
546
|
+
group.add_argument(
|
|
547
|
+
'--extensions',
|
|
548
|
+
metavar='EXTENSIONS',
|
|
549
|
+
dest='extensions',
|
|
550
|
+
action='append',
|
|
551
|
+
help=__('enable arbitrary extensions'),
|
|
552
|
+
)
|
|
397
553
|
for ext in EXTENSIONS:
|
|
398
|
-
group.add_argument(
|
|
399
|
-
|
|
400
|
-
|
|
554
|
+
group.add_argument(
|
|
555
|
+
'--ext-%s' % ext,
|
|
556
|
+
action='append_const',
|
|
557
|
+
const='sphinx.ext.%s' % ext,
|
|
558
|
+
dest='extensions',
|
|
559
|
+
help=__('enable %s extension') % ext,
|
|
560
|
+
)
|
|
401
561
|
|
|
402
562
|
group = parser.add_argument_group(__('Project templating'))
|
|
403
|
-
group.add_argument(
|
|
404
|
-
|
|
405
|
-
|
|
563
|
+
group.add_argument(
|
|
564
|
+
'-t',
|
|
565
|
+
'--templatedir',
|
|
566
|
+
metavar='TEMPLATEDIR',
|
|
567
|
+
dest='templatedir',
|
|
568
|
+
help=__('template directory for template files'),
|
|
569
|
+
)
|
|
406
570
|
|
|
407
571
|
return parser
|
|
408
572
|
|
|
409
573
|
|
|
574
|
+
class CliOptions(Protocol):
|
|
575
|
+
"""Arguments parsed from the command line."""
|
|
576
|
+
|
|
577
|
+
module_path: str
|
|
578
|
+
exclude_pattern: list[str]
|
|
579
|
+
destdir: str
|
|
580
|
+
quiet: bool
|
|
581
|
+
maxdepth: int
|
|
582
|
+
force: bool
|
|
583
|
+
followlinks: bool
|
|
584
|
+
dryrun: bool
|
|
585
|
+
separatemodules: bool
|
|
586
|
+
includeprivate: bool
|
|
587
|
+
tocfile: str
|
|
588
|
+
noheadings: bool
|
|
589
|
+
modulefirst: bool
|
|
590
|
+
implicit_namespaces: bool
|
|
591
|
+
suffix: str
|
|
592
|
+
full: bool
|
|
593
|
+
append_syspath: bool
|
|
594
|
+
header: str | None
|
|
595
|
+
author: str | None
|
|
596
|
+
version: str | None
|
|
597
|
+
release: str | None
|
|
598
|
+
extensions: list[str] | None
|
|
599
|
+
templatedir: str | None
|
|
600
|
+
remove_old: bool
|
|
601
|
+
|
|
602
|
+
|
|
410
603
|
def main(argv: Sequence[str] = (), /) -> int:
|
|
411
604
|
"""Parse and check the command line arguments."""
|
|
412
605
|
locale.setlocale(locale.LC_ALL, '')
|
|
413
606
|
sphinx.locale.init_console()
|
|
414
607
|
|
|
415
608
|
parser = get_parser()
|
|
416
|
-
args = parser.parse_args(argv or sys.argv[1:])
|
|
609
|
+
args: CliOptions = parser.parse_args(argv or sys.argv[1:])
|
|
417
610
|
|
|
418
611
|
rootpath = path.abspath(args.module_path)
|
|
419
612
|
|
|
@@ -423,7 +616,7 @@ def main(argv: Sequence[str] = (), /) -> int:
|
|
|
423
616
|
args.header = rootpath.split(path.sep)[-1]
|
|
424
617
|
if args.suffix.startswith('.'):
|
|
425
618
|
args.suffix = args.suffix[1:]
|
|
426
|
-
if not
|
|
619
|
+
if not Path(rootpath).is_dir():
|
|
427
620
|
logger.error(__('%s is not a directory.'), rootpath)
|
|
428
621
|
raise SystemExit(1)
|
|
429
622
|
if not args.dryrun:
|
|
@@ -432,10 +625,11 @@ def main(argv: Sequence[str] = (), /) -> int:
|
|
|
432
625
|
re.compile(fnmatch.translate(path.abspath(exclude)))
|
|
433
626
|
for exclude in dict.fromkeys(args.exclude_pattern)
|
|
434
627
|
)
|
|
435
|
-
modules = recurse_tree(rootpath, excludes, args, args.templatedir)
|
|
628
|
+
written_files, modules = recurse_tree(rootpath, excludes, args, args.templatedir)
|
|
436
629
|
|
|
437
630
|
if args.full:
|
|
438
631
|
from sphinx.cmd import quickstart as qs
|
|
632
|
+
|
|
439
633
|
modules.sort()
|
|
440
634
|
prev_module = ''
|
|
441
635
|
text = ''
|
|
@@ -444,7 +638,7 @@ def main(argv: Sequence[str] = (), /) -> int:
|
|
|
444
638
|
continue
|
|
445
639
|
prev_module = module
|
|
446
640
|
text += ' %s\n' % module
|
|
447
|
-
d = {
|
|
641
|
+
d: dict[str, Any] = {
|
|
448
642
|
'path': args.destdir,
|
|
449
643
|
'sep': False,
|
|
450
644
|
'dot': '_',
|
|
@@ -455,8 +649,7 @@ def main(argv: Sequence[str] = (), /) -> int:
|
|
|
455
649
|
'suffix': '.' + args.suffix,
|
|
456
650
|
'master': 'index',
|
|
457
651
|
'epub': True,
|
|
458
|
-
'extensions': ['sphinx.ext.autodoc', 'sphinx.ext.viewcode',
|
|
459
|
-
'sphinx.ext.todo'],
|
|
652
|
+
'extensions': ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.todo'],
|
|
460
653
|
'makefile': True,
|
|
461
654
|
'batchfile': True,
|
|
462
655
|
'make_mode': True,
|
|
@@ -477,14 +670,28 @@ def main(argv: Sequence[str] = (), /) -> int:
|
|
|
477
670
|
d['extensions'].extend(ext.split(','))
|
|
478
671
|
|
|
479
672
|
if not args.dryrun:
|
|
480
|
-
qs.generate(d, silent=True, overwrite=args.force,
|
|
481
|
-
templatedir=args.templatedir)
|
|
673
|
+
qs.generate(d, silent=True, overwrite=args.force, templatedir=args.templatedir)
|
|
482
674
|
elif args.tocfile:
|
|
483
|
-
|
|
675
|
+
written_files.append(
|
|
676
|
+
create_modules_toc_file(modules, args, args.tocfile, args.templatedir)
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
if args.remove_old and not args.dryrun:
|
|
680
|
+
for existing in Path(args.destdir).glob(f'**/*.{args.suffix}'):
|
|
681
|
+
if existing not in written_files:
|
|
682
|
+
try:
|
|
683
|
+
existing.unlink()
|
|
684
|
+
except OSError as exc:
|
|
685
|
+
logger.warning(
|
|
686
|
+
__('Failed to remove %s: %s'),
|
|
687
|
+
existing,
|
|
688
|
+
exc.strerror,
|
|
689
|
+
type='autodoc',
|
|
690
|
+
)
|
|
484
691
|
|
|
485
692
|
return 0
|
|
486
693
|
|
|
487
694
|
|
|
488
695
|
# So program can be started with "python -m sphinx.apidoc ..."
|
|
489
|
-
if __name__ ==
|
|
696
|
+
if __name__ == '__main__':
|
|
490
697
|
raise SystemExit(main(sys.argv[1:]))
|