From d59b158371fc3e477a5ce8dbe9f9500bc962aeeb Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Thu, 21 Mar 2024 16:19:26 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=8C=20Make=20`ExtensionMetadata`=20typ?= =?UTF-8?q?e=20public=20and=20use=20it=20in=20internal=20extensions=20(#12?= =?UTF-8?q?153)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This type alias has now been fully documented for public consumption. This will be beneficial to the sphinx ecosystem, to aide/encourage extension developers to provide the correct metadata. Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- CHANGES.rst | 5 +++++ .../tutorials/examples/helloworld.py | 5 ++++- doc/development/tutorials/examples/recipe.py | 4 +++- doc/development/tutorials/examples/todo.py | 4 +++- doc/extdev/utils.rst | 6 ++++++ sphinx/addnodes.py | 3 ++- sphinx/builders/changes.py | 3 ++- sphinx/builders/dirhtml.py | 5 +++-- sphinx/builders/dummy.py | 5 +++-- sphinx/builders/epub3.py | 3 ++- sphinx/builders/gettext.py | 3 ++- sphinx/builders/html/__init__.py | 3 ++- sphinx/builders/html/transforms.py | 3 ++- sphinx/builders/latex/__init__.py | 3 ++- sphinx/builders/latex/transforms.py | 3 ++- sphinx/builders/linkcheck.py | 3 ++- sphinx/builders/manpage.py | 3 ++- sphinx/builders/singlehtml.py | 3 ++- sphinx/builders/texinfo.py | 3 ++- sphinx/builders/text.py | 5 +++-- sphinx/builders/xml.py | 5 +++-- sphinx/config.py | 4 ++-- sphinx/directives/__init__.py | 6 +++--- sphinx/directives/code.py | 4 ++-- sphinx/directives/other.py | 4 ++-- sphinx/directives/patches.py | 6 +++--- sphinx/domains/c/__init__.py | 4 ++-- sphinx/domains/changeset.py | 4 ++-- sphinx/domains/citation.py | 3 ++- sphinx/domains/cpp/__init__.py | 4 ++-- sphinx/domains/index.py | 4 ++-- sphinx/domains/javascript.py | 4 ++-- sphinx/domains/math.py | 3 ++- sphinx/domains/python/__init__.py | 4 ++-- sphinx/domains/rst.py | 4 ++-- sphinx/domains/std/__init__.py | 4 ++-- sphinx/environment/collectors/asset.py | 5 +++-- sphinx/environment/collectors/dependencies.py | 5 +++-- sphinx/environment/collectors/metadata.py | 5 +++-- sphinx/environment/collectors/title.py | 5 +++-- sphinx/environment/collectors/toctree.py | 5 +++-- sphinx/ext/autodoc/__init__.py | 10 ++++++++-- sphinx/ext/autodoc/preserve_defaults.py | 3 ++- sphinx/ext/autodoc/type_comment.py | 3 ++- sphinx/ext/autodoc/typehints.py | 4 ++-- sphinx/ext/autosectionlabel.py | 5 +++-- sphinx/ext/autosummary/__init__.py | 4 ++-- sphinx/ext/coverage.py | 3 ++- sphinx/ext/doctest.py | 4 ++-- sphinx/ext/extlinks.py | 4 ++-- sphinx/ext/githubpages.py | 5 +++-- sphinx/ext/graphviz.py | 4 ++-- sphinx/ext/ifconfig.py | 6 +++--- sphinx/ext/imgconverter.py | 5 +++-- sphinx/ext/imgmath.py | 5 +++-- sphinx/ext/inheritance_diagram.py | 4 ++-- sphinx/ext/intersphinx.py | 4 ++-- sphinx/ext/linkcode.py | 5 +++-- sphinx/ext/mathjax.py | 3 ++- sphinx/ext/napoleon/__init__.py | 3 ++- sphinx/ext/todo.py | 4 ++-- sphinx/ext/viewcode.py | 3 ++- sphinx/extension.py | 6 +++--- sphinx/parsers.py | 5 +++-- sphinx/registry.py | 6 +++--- sphinx/roles.py | 4 ++-- sphinx/transforms/__init__.py | 3 ++- sphinx/transforms/compact_bullet_list.py | 3 ++- sphinx/transforms/i18n.py | 3 ++- sphinx/transforms/post_transforms/__init__.py | 3 ++- sphinx/transforms/post_transforms/code.py | 3 ++- sphinx/transforms/post_transforms/images.py | 3 ++- sphinx/transforms/references.py | 3 ++- sphinx/util/typing.py | 19 +++++++++++++++---- sphinx/versioning.py | 3 ++- 75 files changed, 200 insertions(+), 122 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1f5ea7bd830..afaab82308f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -22,6 +22,11 @@ Deprecated Features added -------------- +* Add public type alias :class:`sphinx.util.typing.ExtensionMetadata`. + This can be used by extension developers + to annotate the return type of their ``setup`` function. + Patch by Chris Sewell. + * #12133: Allow ``external`` roles to reference object types (rather than role names). Patch by Chris Sewell. diff --git a/doc/development/tutorials/examples/helloworld.py b/doc/development/tutorials/examples/helloworld.py index 55ed1fd0226..da295621e31 100644 --- a/doc/development/tutorials/examples/helloworld.py +++ b/doc/development/tutorials/examples/helloworld.py @@ -1,6 +1,9 @@ from docutils import nodes from docutils.parsers.rst import Directive +from sphinx.application import Sphinx +from sphinx.util.typing import ExtensionMetadata + class HelloWorld(Directive): def run(self): @@ -8,7 +11,7 @@ def run(self): return [paragraph_node] -def setup(app): +def setup(app: Sphinx) -> ExtensionMetadata: app.add_directive('helloworld', HelloWorld) return { diff --git a/doc/development/tutorials/examples/recipe.py b/doc/development/tutorials/examples/recipe.py index 18d948f9c05..28d25f21f62 100644 --- a/doc/development/tutorials/examples/recipe.py +++ b/doc/development/tutorials/examples/recipe.py @@ -3,10 +3,12 @@ from docutils.parsers.rst import directives from sphinx import addnodes +from sphinx.application import Sphinx from sphinx.directives import ObjectDescription from sphinx.domains import Domain, Index from sphinx.roles import XRefRole from sphinx.util.nodes import make_refnode +from sphinx.util.typing import ExtensionMetadata class RecipeDirective(ObjectDescription): @@ -153,7 +155,7 @@ def add_recipe(self, signature, ingredients): self.data['recipes'].append((name, signature, 'Recipe', self.env.docname, anchor, 0)) -def setup(app): +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(RecipeDomain) return { diff --git a/doc/development/tutorials/examples/todo.py b/doc/development/tutorials/examples/todo.py index c84a5858e76..2baac5c6f6c 100644 --- a/doc/development/tutorials/examples/todo.py +++ b/doc/development/tutorials/examples/todo.py @@ -1,8 +1,10 @@ from docutils import nodes from docutils.parsers.rst import Directive +from sphinx.application import Sphinx from sphinx.locale import _ from sphinx.util.docutils import SphinxDirective +from sphinx.util.typing import ExtensionMetadata class todo(nodes.Admonition, nodes.Element): @@ -111,7 +113,7 @@ def process_todo_nodes(app, doctree, fromdocname): node.replace_self(content) -def setup(app): +def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value('todo_include_todos', False, 'html') app.add_node(todolist) diff --git a/doc/extdev/utils.rst b/doc/extdev/utils.rst index e842f3032df..ff8dc4e2741 100644 --- a/doc/extdev/utils.rst +++ b/doc/extdev/utils.rst @@ -35,3 +35,9 @@ Utility components .. autoclass:: sphinx.events.EventManager :members: + +Utility types +------------- + +.. autoclass:: sphinx.util.typing.ExtensionMetadata + :members: diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index 12ed0dc5cdc..7896fbaef05 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -12,6 +12,7 @@ from docutils.nodes import Element from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata # deprecated name -> (object to return, canonical path or empty string) _DEPRECATED_OBJECTS = { @@ -573,7 +574,7 @@ class manpage(nodes.Inline, nodes.FixedTextElement): """Node for references to manpages.""" -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_node(toctree) app.add_node(desc) diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py index a3934663009..7d5e0044e23 100644 --- a/sphinx/builders/changes.py +++ b/sphinx/builders/changes.py @@ -18,6 +18,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -155,7 +156,7 @@ def finish(self) -> None: pass -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(ChangesBuilder) return { diff --git a/sphinx/builders/dirhtml.py b/sphinx/builders/dirhtml.py index e4660b449da..dbfced3a748 100644 --- a/sphinx/builders/dirhtml.py +++ b/sphinx/builders/dirhtml.py @@ -3,7 +3,7 @@ from __future__ import annotations from os import path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.util import logging @@ -11,6 +11,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -42,7 +43,7 @@ def get_outfilename(self, pagename: str) -> str: return outfilename -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.setup_extension('sphinx.builders.html') app.add_builder(DirectoryHTMLBuilder) diff --git a/sphinx/builders/dummy.py b/sphinx/builders/dummy.py index f025311e5ea..9c7ce834e23 100644 --- a/sphinx/builders/dummy.py +++ b/sphinx/builders/dummy.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from sphinx.builders import Builder from sphinx.locale import __ @@ -11,6 +11,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata class DummyBuilder(Builder): @@ -38,7 +39,7 @@ def finish(self) -> None: pass -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(DummyBuilder) return { diff --git a/sphinx/builders/epub3.py b/sphinx/builders/epub3.py index 8550b89ff78..91c76e41c32 100644 --- a/sphinx/builders/epub3.py +++ b/sphinx/builders/epub3.py @@ -22,6 +22,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -257,7 +258,7 @@ def convert_epub_css_files(app: Sphinx, config: Config) -> None: config.epub_css_files = epub_css_files # type: ignore[attr-defined] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(Epub3Builder) # config values diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index 0f29abe5d25..572aa8c6e23 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -33,6 +33,7 @@ from sphinx.application import Sphinx from sphinx.config import Config + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -302,7 +303,7 @@ def _gettext_compact_validator(app: Sphinx, config: Config) -> None: config.gettext_compact = True # type: ignore[attr-defined] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(MessageCatalogBuilder) app.add_config_value('gettext_compact', True, 'gettext', {bool, str}) diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index 9c405d0ba54..02f29186339 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -58,6 +58,7 @@ from sphinx.config import _ConfigRebuild from sphinx.environment import BuildEnvironment from sphinx.util.tags import Tags + from sphinx.util.typing import ExtensionMetadata #: the filename for the inventory of objects INVENTORY_FILENAME = 'objects.inv' @@ -1296,7 +1297,7 @@ def error_on_html_4(_app: Sphinx, config: Config) -> None: )) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: # builders app.add_builder(StandaloneHTMLBuilder) diff --git a/sphinx/builders/html/transforms.py b/sphinx/builders/html/transforms.py index 3e0b0681032..a36588c7b3b 100644 --- a/sphinx/builders/html/transforms.py +++ b/sphinx/builders/html/transforms.py @@ -12,6 +12,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata class KeyboardTransform(SphinxPostTransform): @@ -77,7 +78,7 @@ def is_multiwords_key(self, parts: list[str]) -> bool: return False -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_post_transform(KeyboardTransform) return { diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index 4c01223eced..fd140dd062e 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -39,6 +39,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata XINDY_LANG_OPTIONS = { # language codes from docutils.writers.latex2e.Babel @@ -521,7 +522,7 @@ def default_latex_documents(config: Config) -> list[tuple[str, str, str, str, st config.latex_theme)] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.setup_extension('sphinx.builders.latex.transforms') app.add_builder(LaTeXBuilder) diff --git a/sphinx/builders/latex/transforms.py b/sphinx/builders/latex/transforms.py index 4ebc11d745c..f1807f5ad38 100644 --- a/sphinx/builders/latex/transforms.py +++ b/sphinx/builders/latex/transforms.py @@ -25,6 +25,7 @@ from docutils.nodes import Element, Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:') @@ -631,7 +632,7 @@ def run(self, **kwargs: Any) -> None: node.parent.insert(i + 1, index) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_transform(FootnoteDocnameUpdater) app.add_post_transform(SubstitutionDefinitionsRemover) app.add_post_transform(BibliographyTransform) diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py index 5c6876881f0..83f45e4719c 100644 --- a/sphinx/builders/linkcheck.py +++ b/sphinx/builders/linkcheck.py @@ -42,6 +42,7 @@ from sphinx.application import Sphinx from sphinx.config import Config + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -655,7 +656,7 @@ def compile_linkcheck_allowed_redirects(app: Sphinx, config: Config) -> None: app.config.linkcheck_allowed_redirects.pop(url) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(CheckExternalLinksBuilder) app.add_post_transform(HyperlinkCollector) diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py index 4b4bc202758..bf01d017c24 100644 --- a/sphinx/builders/manpage.py +++ b/sphinx/builders/manpage.py @@ -22,6 +22,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx from sphinx.config import Config + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -114,7 +115,7 @@ def default_man_pages(config: Config) -> list[tuple[str, str, str, list[str], in [config.author], 1)] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(ManualPageBuilder) app.add_config_value('man_pages', default_man_pages, '') diff --git a/sphinx/builders/singlehtml.py b/sphinx/builders/singlehtml.py index 9addbe23db5..f9ce8cea28d 100644 --- a/sphinx/builders/singlehtml.py +++ b/sphinx/builders/singlehtml.py @@ -19,6 +19,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -190,7 +191,7 @@ def write_additional_files(self) -> None: self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.setup_extension('sphinx.builders.html') app.add_builder(SingleFileHTMLBuilder) diff --git a/sphinx/builders/texinfo.py b/sphinx/builders/texinfo.py index b45cc3472ad..226ce690fad 100644 --- a/sphinx/builders/texinfo.py +++ b/sphinx/builders/texinfo.py @@ -32,6 +32,7 @@ from sphinx.application import Sphinx from sphinx.config import Config + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) template_dir = os.path.join(package_dir, 'templates', 'texinfo') @@ -214,7 +215,7 @@ def default_texinfo_documents( 'One line description of project', 'Miscellaneous')] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(TexinfoBuilder) app.add_config_value('texinfo_documents', default_texinfo_documents, '') diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py index 43a8d1f714d..483e7fadee0 100644 --- a/sphinx/builders/text.py +++ b/sphinx/builders/text.py @@ -3,7 +3,7 @@ from __future__ import annotations from os import path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils.io import StringOutput @@ -19,6 +19,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -79,7 +80,7 @@ def finish(self) -> None: pass -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(TextBuilder) app.add_config_value('text_sectionchars', '*=-~"+`', 'env') diff --git a/sphinx/builders/xml.py b/sphinx/builders/xml.py index 2e7efdbc914..1f2c105714b 100644 --- a/sphinx/builders/xml.py +++ b/sphinx/builders/xml.py @@ -3,7 +3,7 @@ from __future__ import annotations from os import path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils import nodes from docutils.io import StringOutput @@ -21,6 +21,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -112,7 +113,7 @@ class PseudoXMLBuilder(XMLBuilder): _writer_class = PseudoXMLWriter -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(XMLBuilder) app.add_builder(PseudoXMLBuilder) diff --git a/sphinx/config.py b/sphinx/config.py index dc8c1c11d72..ef1eaa848e3 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -15,7 +15,7 @@ from sphinx.locale import _, __ from sphinx.util import logging from sphinx.util.osutil import fs_encoding -from sphinx.util.typing import NoneType +from sphinx.util.typing import ExtensionMetadata, NoneType if sys.version_info >= (3, 11): from contextlib import chdir @@ -703,7 +703,7 @@ def check_root_doc(app: Sphinx, env: BuildEnvironment, added: set[str], return changed -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.connect('config-inited', convert_source_suffix, priority=800) app.connect('config-inited', convert_highlight_options, priority=800) app.connect('config-inited', init_numfig_format, priority=800) diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index d4bc240ec96..cac6c031f4e 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -3,7 +3,7 @@ from __future__ import annotations import re -from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast +from typing import TYPE_CHECKING, Generic, TypeVar, cast from docutils import nodes from docutils.parsers.rst import directives, roles @@ -14,7 +14,7 @@ from sphinx.util.docfields import DocFieldTransformer, Field, TypedField from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import nested_parse_with_titles -from sphinx.util.typing import OptionSpec # NoQA: TCH001 +from sphinx.util.typing import ExtensionMetadata, OptionSpec # NoQA: TCH001 if TYPE_CHECKING: from docutils.nodes import Node @@ -356,7 +356,7 @@ def run(self) -> list[Node]: return [] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value("strip_signature_backslash", False, 'env') directives.register_directive('default-role', DefaultRole) directives.register_directive('default-domain', DefaultDomain) diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index faafb77ee6c..a0629cec650 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -20,7 +20,7 @@ from sphinx.application import Sphinx from sphinx.config import Config - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -469,7 +469,7 @@ def run(self) -> list[Node]: return [document.reporter.warning(exc, line=self.lineno)] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: directives.register_directive('highlight', Highlight) directives.register_directive('code-block', CodeBlock) directives.register_directive('sourcecode', CodeBlock) diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 365fb2ebcb8..96ba93b7a5b 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -25,7 +25,7 @@ from docutils.nodes import Element, Node from sphinx.application import Sphinx - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec glob_re = re.compile(r'.*[*?\[].*') @@ -425,7 +425,7 @@ def _insert_input(include_lines: list[str], source: str) -> None: return super().run() -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: directives.register_directive('toctree', TocTree) directives.register_directive('sectionauthor', Author) directives.register_directive('moduleauthor', Author) diff --git a/sphinx/directives/patches.py b/sphinx/directives/patches.py index b14805c85ce..b46713f63d3 100644 --- a/sphinx/directives/patches.py +++ b/sphinx/directives/patches.py @@ -2,7 +2,7 @@ import os from os import path -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, cast from docutils import nodes from docutils.nodes import Node, make_id @@ -21,7 +21,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -176,7 +176,7 @@ def add_target(self, ret: list[Node]) -> None: ret.insert(0, target) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: directives.register_directive('figure', Figure) directives.register_directive('meta', Meta) directives.register_directive('csv-table', CSVTable) diff --git a/sphinx/domains/c/__init__.py b/sphinx/domains/c/__init__.py index b2bd862eb15..ba7fa06ead5 100644 --- a/sphinx/domains/c/__init__.py +++ b/sphinx/domains/c/__init__.py @@ -42,7 +42,7 @@ from sphinx.builders import Builder from sphinx.domains.c._symbol import LookupKey from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -780,7 +780,7 @@ def get_objects(self) -> Iterator[tuple[str, str, str, str, str, int]]: yield (name, dispname, objectType, docname, newestId, 1) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(CDomain) app.add_config_value("c_id_attributes", [], 'env') app.add_config_value("c_paren_attributes", [], 'env') diff --git a/sphinx/domains/changeset.py b/sphinx/domains/changeset.py index 87959610283..9a06287453f 100644 --- a/sphinx/domains/changeset.py +++ b/sphinx/domains/changeset.py @@ -16,7 +16,7 @@ from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec versionlabels = { @@ -150,7 +150,7 @@ def get_changesets_for(self, version: str) -> list[ChangeSet]: return self.changesets.get(version, []) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(ChangeSetDomain) app.add_directive('deprecated', VersionChange) app.add_directive('versionadded', VersionChange) diff --git a/sphinx/domains/citation.py b/sphinx/domains/citation.py index 72e95083d0e..fc0990789f4 100644 --- a/sphinx/domains/citation.py +++ b/sphinx/domains/citation.py @@ -19,6 +19,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -143,7 +144,7 @@ def apply(self, **kwargs: Any) -> None: domain.note_citation_reference(ref) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(CitationDomain) app.add_transform(CitationDefinitionTransform) app.add_transform(CitationReferenceTransform) diff --git a/sphinx/domains/cpp/__init__.py b/sphinx/domains/cpp/__init__.py index 8fc23796922..5c567e7144e 100644 --- a/sphinx/domains/cpp/__init__.py +++ b/sphinx/domains/cpp/__init__.py @@ -46,7 +46,7 @@ from sphinx.builders import Builder from sphinx.domains.cpp._symbol import LookupKey from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -1063,7 +1063,7 @@ def get_full_qualified_name(self, node: Element) -> str | None: return f'{parentName}::{target}' -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(CPPDomain) app.add_config_value("cpp_index_common_prefix", [], 'env') app.add_config_value("cpp_id_attributes", [], 'env') diff --git a/sphinx/domains/index.py b/sphinx/domains/index.py index 42ac2b460a7..115277bf76c 100644 --- a/sphinx/domains/index.py +++ b/sphinx/domains/index.py @@ -21,7 +21,7 @@ from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -115,7 +115,7 @@ def run(self) -> tuple[list[Node], list[system_message]]: return [index, target, text], [] -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(IndexDomain) app.add_directive('index', IndexDirective) app.add_role('index', IndexRole()) diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py index e2b34cf2eae..de6c3507c32 100644 --- a/sphinx/domains/javascript.py +++ b/sphinx/domains/javascript.py @@ -28,7 +28,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -498,7 +498,7 @@ def get_full_qualified_name(self, node: Element) -> str | None: return '.'.join(filter(None, [modname, prefix, target])) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(JavaScriptDomain) app.add_config_value( 'javascript_maximum_signature_line_length', None, 'env', {int, type(None)}, diff --git a/sphinx/domains/math.py b/sphinx/domains/math.py index d266fe06367..708a4d57943 100644 --- a/sphinx/domains/math.py +++ b/sphinx/domains/math.py @@ -20,6 +20,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -144,7 +145,7 @@ def has_equations(self, docname: str | None = None) -> bool: ) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(MathDomain) app.add_role('eq', MathReferenceRole(warn_dangling=True)) diff --git a/sphinx/domains/python/__init__.py b/sphinx/domains/python/__init__.py index 6367b26d8f4..5b574ed6ef7 100644 --- a/sphinx/domains/python/__init__.py +++ b/sphinx/domains/python/__init__.py @@ -34,7 +34,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -870,7 +870,7 @@ def istyping(s: str) -> bool: return None -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.setup_extension('sphinx.directives') app.add_domain(PythonDomain) diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py index fcf5ac6a7da..1ff9d4247e4 100644 --- a/sphinx/domains/rst.py +++ b/sphinx/domains/rst.py @@ -24,7 +24,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -293,7 +293,7 @@ def get_objects(self) -> Iterator[tuple[str, str, str, str, str, int]]: yield name, name, typ, docname, node_id, 1 -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(ReSTDomain) return { diff --git a/sphinx/domains/std/__init__.py b/sphinx/domains/std/__init__.py index 8383f552fa9..ca879378c05 100644 --- a/sphinx/domains/std/__init__.py +++ b/sphinx/domains/std/__init__.py @@ -27,7 +27,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec, RoleFunction + from sphinx.util.typing import ExtensionMetadata, OptionSpec, RoleFunction logger = logging.getLogger(__name__) @@ -1114,7 +1114,7 @@ def warn_missing_reference(app: Sphinx, domain: Domain, node: pending_xref, return True -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_domain(StandardDomain) app.connect('warn-missing-reference', warn_missing_reference) diff --git a/sphinx/environment/collectors/asset.py b/sphinx/environment/collectors/asset.py index 358c6b43ee9..451d6594b54 100644 --- a/sphinx/environment/collectors/asset.py +++ b/sphinx/environment/collectors/asset.py @@ -5,7 +5,7 @@ import os from glob import glob from os import path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils import nodes from docutils.utils import relative_path @@ -22,6 +22,7 @@ from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -136,7 +137,7 @@ def process_doc(self, app: Sphinx, doctree: nodes.document) -> None: node['filename'] = app.env.dlfiles.add_file(app.env.docname, rel_filename) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_env_collector(ImageCollector) app.add_env_collector(DownloadFileCollector) diff --git a/sphinx/environment/collectors/dependencies.py b/sphinx/environment/collectors/dependencies.py index df1f0c1a3d5..33b54b824a8 100644 --- a/sphinx/environment/collectors/dependencies.py +++ b/sphinx/environment/collectors/dependencies.py @@ -4,7 +4,7 @@ import os from os import path -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils.utils import relative_path @@ -16,6 +16,7 @@ from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata class DependenciesCollector(EnvironmentCollector): @@ -47,7 +48,7 @@ def process_doc(self, app: Sphinx, doctree: nodes.document) -> None: app.env.dependencies[app.env.docname].add(relpath) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_env_collector(DependenciesCollector) return { diff --git a/sphinx/environment/collectors/metadata.py b/sphinx/environment/collectors/metadata.py index 0209fb86adc..b64a9fa0836 100644 --- a/sphinx/environment/collectors/metadata.py +++ b/sphinx/environment/collectors/metadata.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, cast from docutils import nodes @@ -11,6 +11,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata class MetadataCollector(EnvironmentCollector): @@ -60,7 +61,7 @@ def process_doc(self, app: Sphinx, doctree: nodes.document) -> None: doctree.pop(index) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_env_collector(MetadataCollector) return { diff --git a/sphinx/environment/collectors/title.py b/sphinx/environment/collectors/title.py index 014d77aea38..07605576560 100644 --- a/sphinx/environment/collectors/title.py +++ b/sphinx/environment/collectors/title.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils import nodes @@ -12,6 +12,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata class TitleCollector(EnvironmentCollector): @@ -51,7 +52,7 @@ def process_doc(self, app: Sphinx, doctree: nodes.document) -> None: app.env.longtitles[app.env.docname] = longtitlenode -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_env_collector(TitleCollector) return { diff --git a/sphinx/environment/collectors/toctree.py b/sphinx/environment/collectors/toctree.py index 55e44147878..6ea148c631e 100644 --- a/sphinx/environment/collectors/toctree.py +++ b/sphinx/environment/collectors/toctree.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, TypeVar, cast +from typing import TYPE_CHECKING, TypeVar, cast from docutils import nodes @@ -20,6 +20,7 @@ from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata N = TypeVar('N') @@ -345,7 +346,7 @@ def _make_anchor_name(ids: list[str], num_entries: list[int]) -> str: return anchorname -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_env_collector(TocTreeCollector) return { diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index c57ecd8d5fa..873212c073c 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -33,7 +33,13 @@ safe_getattr, stringify_signature, ) -from sphinx.util.typing import OptionSpec, get_type_hints, restify, stringify_annotation +from sphinx.util.typing import ( + ExtensionMetadata, + OptionSpec, + get_type_hints, + restify, + stringify_annotation, +) if TYPE_CHECKING: from collections.abc import Iterator, Sequence @@ -2844,7 +2850,7 @@ def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any: return safe_getattr(obj, name, *defargs) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_autodocumenter(ModuleDocumenter) app.add_autodocumenter(ClassDocumenter) app.add_autodocumenter(ExceptionDocumenter) diff --git a/sphinx/ext/autodoc/preserve_defaults.py b/sphinx/ext/autodoc/preserve_defaults.py index 13fda26b58d..b0b32438773 100644 --- a/sphinx/ext/autodoc/preserve_defaults.py +++ b/sphinx/ext/autodoc/preserve_defaults.py @@ -22,6 +22,7 @@ from typing import Any from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) _LAMBDA_NAME = (lambda: None).__name__ @@ -189,7 +190,7 @@ def update_defvalue(app: Sphinx, obj: Any, bound_method: bool) -> None: logger.warning(__("Failed to parse a default argument value for %r: %s"), obj, exc) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value('autodoc_preserve_defaults', False, 'env') app.connect('autodoc-before-process-signature', update_defvalue) diff --git a/sphinx/ext/autodoc/type_comment.py b/sphinx/ext/autodoc/type_comment.py index e2c9ae24945..e0a5a63b91d 100644 --- a/sphinx/ext/autodoc/type_comment.py +++ b/sphinx/ext/autodoc/type_comment.py @@ -15,6 +15,7 @@ from collections.abc import Sequence from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -134,7 +135,7 @@ def update_annotations_using_type_comments(app: Sphinx, obj: Any, bound_method: logger.warning(__("Failed to parse type_comment for %r: %s"), obj, exc) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.connect('autodoc-before-process-signature', update_annotations_using_type_comments) return {'version': sphinx.__display_version__, 'parallel_read_safe': True} diff --git a/sphinx/ext/autodoc/typehints.py b/sphinx/ext/autodoc/typehints.py index ac90c58df79..df0c4684dc8 100644 --- a/sphinx/ext/autodoc/typehints.py +++ b/sphinx/ext/autodoc/typehints.py @@ -11,7 +11,7 @@ import sphinx from sphinx import addnodes from sphinx.util import inspect -from sphinx.util.typing import stringify_annotation +from sphinx.util.typing import ExtensionMetadata, stringify_annotation if TYPE_CHECKING: from docutils.nodes import Element @@ -209,7 +209,7 @@ def augment_descriptions_with_types( node += field -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.connect('autodoc-process-signature', record_typehints) app.connect('object-description-transform', merge_typehints) diff --git a/sphinx/ext/autosectionlabel.py b/sphinx/ext/autosectionlabel.py index d423fcc0589..c1eb46bf04f 100644 --- a/sphinx/ext/autosectionlabel.py +++ b/sphinx/ext/autosectionlabel.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, cast from docutils import nodes @@ -16,6 +16,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -57,7 +58,7 @@ def register_sections_as_label(app: Sphinx, document: Node) -> None: domain.labels[name] = docname, labelid, sectname -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value('autosectionlabel_prefix_document', False, 'env') app.add_config_value('autosectionlabel_maxdepth', None, 'env') app.connect('doctree-read', register_sections_as_label) diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 22e616c3fbf..93ce819e14a 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -95,7 +95,7 @@ from sphinx.application import Sphinx from sphinx.extension import Extension - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec from sphinx.writers.html import HTML5Translator logger = logging.getLogger(__name__) @@ -821,7 +821,7 @@ def process_generate_options(app: Sphinx) -> None: encoding=app.config.source_encoding) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: # I need autodoc app.setup_extension('sphinx.ext.autodoc') app.add_node(autosummary_toc, diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py index 91d8bba78a8..92afd868ca4 100644 --- a/sphinx/ext/coverage.py +++ b/sphinx/ext/coverage.py @@ -26,6 +26,7 @@ from collections.abc import Iterator from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -388,7 +389,7 @@ def finish(self) -> None: self.py_undocumented, self.py_documented), dumpfile) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_builder(CoverageBuilder) app.add_config_value('coverage_ignore_modules', [], '') app.add_config_value('coverage_ignore_functions', [], '') diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 0c38ff36a8f..b76a9422bf2 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -32,7 +32,7 @@ from docutils.nodes import Element, Node, TextElement from sphinx.application import Sphinx - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec logger = logging.getLogger(__name__) @@ -563,7 +563,7 @@ def run_setup_cleanup(runner: Any, testcodes: list[TestCode], what: Any) -> bool run_setup_cleanup(self.cleanup_runner, group.cleanup, 'cleanup') -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_directive('testsetup', TestsetupDirective) app.add_directive('testcleanup', TestcleanupDirective) app.add_directive('doctest', DoctestDirective) diff --git a/sphinx/ext/extlinks.py b/sphinx/ext/extlinks.py index 1e9bf7760a0..a880278f2cd 100644 --- a/sphinx/ext/extlinks.py +++ b/sphinx/ext/extlinks.py @@ -37,7 +37,7 @@ from docutils.parsers.rst.states import Inliner from sphinx.application import Sphinx - from sphinx.util.typing import RoleFunction + from sphinx.util.typing import ExtensionMetadata, RoleFunction logger = logging.getLogger(__name__) @@ -117,7 +117,7 @@ def setup_link_roles(app: Sphinx) -> None: app.add_role(name, make_link_role(name, base_url, caption)) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value('extlinks', {}, 'env') app.add_config_value('extlinks_detect_hardcoded_links', False, 'env') diff --git a/sphinx/ext/githubpages.py b/sphinx/ext/githubpages.py index c9be928e8b1..aac47975a14 100644 --- a/sphinx/ext/githubpages.py +++ b/sphinx/ext/githubpages.py @@ -5,13 +5,14 @@ import contextlib import os import urllib.parse -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING import sphinx if TYPE_CHECKING: from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata def _get_domain_from_url(url: str) -> str: @@ -52,6 +53,6 @@ def create_nojekyll_and_cname(app: Sphinx, env: BuildEnvironment) -> None: os.unlink(cname_path) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.connect('env-updated', create_nojekyll_and_cname) return {'version': sphinx.__display_version__, 'parallel_read_safe': True} diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py index b27aea5f6fa..50c60596b2c 100644 --- a/sphinx/ext/graphviz.py +++ b/sphinx/ext/graphviz.py @@ -31,7 +31,7 @@ from sphinx.application import Sphinx from sphinx.config import Config - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec from sphinx.writers.html import HTML5Translator from sphinx.writers.latex import LaTeXTranslator from sphinx.writers.manpage import ManualPageTranslator @@ -452,7 +452,7 @@ def on_config_inited(_app: Sphinx, config: Config) -> None: config.html_static_path.append(css_path) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_node(graphviz, html=(html_visit_graphviz, None), latex=(latex_visit_graphviz, None), diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py index 7e3b23bae0b..b1adff3f4bd 100644 --- a/sphinx/ext/ifconfig.py +++ b/sphinx/ext/ifconfig.py @@ -16,7 +16,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils import nodes @@ -28,7 +28,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec class ifconfig(nodes.Element): @@ -74,7 +74,7 @@ def process_ifconfig_nodes(app: Sphinx, doctree: nodes.document, docname: str) - node.replace_self(node.children) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_node(ifconfig) app.add_directive('ifconfig', IfConfig) app.connect('doctree-resolved', process_ifconfig_nodes) diff --git a/sphinx/ext/imgconverter.py b/sphinx/ext/imgconverter.py index 90f7688f3fe..5a9fa30db88 100644 --- a/sphinx/ext/imgconverter.py +++ b/sphinx/ext/imgconverter.py @@ -5,7 +5,7 @@ import subprocess import sys from subprocess import CalledProcessError -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING import sphinx from sphinx.errors import ExtensionError @@ -15,6 +15,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -73,7 +74,7 @@ def convert(self, _from: str, _to: str) -> bool: (exc.stderr, exc.stdout)) from exc -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_post_transform(ImagemagickConverter) if sys.platform == 'win32': # On Windows, we use Imagemagik v7 by default to avoid the trouble for diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py index 4f8d4b7a0a7..0074bc5a390 100644 --- a/sphinx/ext/imgmath.py +++ b/sphinx/ext/imgmath.py @@ -11,7 +11,7 @@ from hashlib import sha1 from os import path from subprocess import CalledProcessError -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils import nodes @@ -33,6 +33,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.config import Config + from sphinx.util.typing import ExtensionMetadata from sphinx.writers.html import HTML5Translator logger = logging.getLogger(__name__) @@ -384,7 +385,7 @@ def html_visit_displaymath(self: HTML5Translator, node: nodes.math_block) -> Non raise nodes.SkipNode -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_html_math_renderer('imgmath', (html_visit_math, None), (html_visit_displaymath, None)) diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py index 8d09fdb418d..a1933fdfd79 100644 --- a/sphinx/ext/inheritance_diagram.py +++ b/sphinx/ext/inheritance_diagram.py @@ -58,7 +58,7 @@ class E(B): pass from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec from sphinx.writers.html import HTML5Translator from sphinx.writers.latex import LaTeXTranslator from sphinx.writers.texinfo import TexinfoTranslator @@ -477,7 +477,7 @@ def skip(self: nodes.NodeVisitor, node: inheritance_diagram) -> None: raise nodes.SkipNode -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.setup_extension('sphinx.ext.graphviz') app.add_node( inheritance_diagram, diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 6f734f81901..abc596f998b 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -53,7 +53,7 @@ from sphinx.config import Config from sphinx.domains import Domain from sphinx.environment import BuildEnvironment - from sphinx.util.typing import Inventory, InventoryItem, RoleFunction + from sphinx.util.typing import ExtensionMetadata, Inventory, InventoryItem, RoleFunction InventoryCacheEntry = tuple[Union[str, None], int, Inventory] @@ -707,7 +707,7 @@ def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None: config.intersphinx_mapping.pop(key) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value('intersphinx_mapping', {}, 'env') app.add_config_value('intersphinx_cache_limit', 5, '') app.add_config_value('intersphinx_timeout', None, '') diff --git a/sphinx/ext/linkcode.py b/sphinx/ext/linkcode.py index ee104062342..93118cd6745 100644 --- a/sphinx/ext/linkcode.py +++ b/sphinx/ext/linkcode.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING from docutils import nodes @@ -15,6 +15,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata class LinkcodeError(SphinxError): @@ -71,7 +72,7 @@ def doctree_read(app: Sphinx, doctree: Node) -> None: signode += onlynode -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.connect('doctree-read', doctree_read) app.add_config_value('linkcode_resolve', None, '') return {'version': sphinx.__display_version__, 'parallel_read_safe': True} diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py index 41d18b92d17..24109ee9809 100644 --- a/sphinx/ext/mathjax.py +++ b/sphinx/ext/mathjax.py @@ -21,6 +21,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata from sphinx.writers.html import HTML5Translator # more information for mathjax secure url is here: @@ -109,7 +110,7 @@ def install_mathjax(app: Sphinx, pagename: str, templatename: str, context: dict builder.add_js_file(app.config.mathjax_path, **options) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_html_math_renderer('mathjax', (html_visit_math, None), (html_visit_displaymath, None)) diff --git a/sphinx/ext/napoleon/__init__.py b/sphinx/ext/napoleon/__init__.py index 536b288f9f3..581f3ea4442 100644 --- a/sphinx/ext/napoleon/__init__.py +++ b/sphinx/ext/napoleon/__init__.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: from sphinx.config import _ConfigRebuild + from sphinx.util.typing import ExtensionMetadata class Config: @@ -292,7 +293,7 @@ def __init__(self, **settings: Any) -> None: setattr(self, name, value) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: """Sphinx extension setup function. When the extension is loaded, Sphinx imports this module and executes diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py index ef099fdc083..d206866830b 100644 --- a/sphinx/ext/todo.py +++ b/sphinx/ext/todo.py @@ -28,7 +28,7 @@ from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment - from sphinx.util.typing import OptionSpec + from sphinx.util.typing import ExtensionMetadata, OptionSpec from sphinx.writers.html import HTML5Translator from sphinx.writers.latex import LaTeXTranslator @@ -224,7 +224,7 @@ def latex_depart_todo_node(self: LaTeXTranslator, node: todo_node) -> None: self.body.append('\\end{sphinxadmonition}\n') -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_event('todo-defined') app.add_config_value('todo_include_todos', False, 'html') app.add_config_value('todo_link_only', False, 'html') diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 0d66ad66ecc..e1594f72190 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -27,6 +27,7 @@ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -341,7 +342,7 @@ def collect_pages(app: Sphinx) -> Generator[tuple[str, dict[str, Any], str], Non yield (posixpath.join(OUTPUT_DIRNAME, 'index'), context, 'page.html') -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_config_value('viewcode_import', None, '') app.add_config_value('viewcode_enable_epub', False, '') app.add_config_value('viewcode_follow_imported_members', True, '') diff --git a/sphinx/extension.py b/sphinx/extension.py index b22d3b13f4c..88b9d420acd 100644 --- a/sphinx/extension.py +++ b/sphinx/extension.py @@ -13,7 +13,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx from sphinx.config import Config - from sphinx.util.typing import _ExtensionMetadata + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -22,7 +22,7 @@ class Extension: def __init__(self, name: str, module: Any, **kwargs: Any) -> None: self.name = name self.module = module - self.metadata: _ExtensionMetadata = kwargs # type: ignore[assignment] + self.metadata: ExtensionMetadata = kwargs # type: ignore[assignment] self.version = kwargs.pop('version', 'unknown version') # The extension supports parallel read or not. The default value @@ -82,7 +82,7 @@ def verify_needs_extensions(app: Sphinx, config: Config) -> None: ) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.connect('config-inited', verify_needs_extensions, priority=800) return { diff --git a/sphinx/parsers.py b/sphinx/parsers.py index 477c1425588..955d59b3b79 100644 --- a/sphinx/parsers.py +++ b/sphinx/parsers.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING import docutils.parsers import docutils.parsers.rst @@ -19,6 +19,7 @@ from sphinx.application import Sphinx from sphinx.config import Config from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata class Parser(docutils.parsers.Parser): @@ -88,7 +89,7 @@ def decorate(self, content: StringList) -> None: append_epilog(content, self.config.rst_epilog) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_source_parser(RSTParser) return { diff --git a/sphinx/registry.py b/sphinx/registry.py index 62d1e3e5cf7..1c58ba71341 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -40,9 +40,9 @@ from sphinx.environment import BuildEnvironment from sphinx.ext.autodoc import Documenter from sphinx.util.typing import ( + ExtensionMetadata, RoleFunction, TitleGetter, - _ExtensionMetadata, _ExtensionSetupFunc, ) @@ -460,7 +460,7 @@ def load_extension(self, app: Sphinx, extname: str) -> None: if setup is None: logger.warning(__('extension %r has no setup() function; is it really ' 'a Sphinx extension module?'), extname) - metadata: _ExtensionMetadata = {} + metadata: ExtensionMetadata = {} else: try: metadata = setup(app) @@ -513,7 +513,7 @@ def merge_source_suffix(app: Sphinx, config: Config) -> None: app.registry.source_suffix = app.config.source_suffix -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.connect('config-inited', merge_source_suffix, priority=800) return { diff --git a/sphinx/roles.py b/sphinx/roles.py index 7409a77356f..830fe04994f 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -22,7 +22,7 @@ from sphinx.application import Sphinx from sphinx.environment import BuildEnvironment - from sphinx.util.typing import RoleFunction + from sphinx.util.typing import ExtensionMetadata, RoleFunction generic_docroles = { @@ -457,7 +457,7 @@ def code_role( } -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: from docutils.parsers.rst import roles for rolename, nodeclass in generic_docroles.items(): diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py index 5a49d99d745..224b0e3bfd3 100644 --- a/sphinx/transforms/__init__.py +++ b/sphinx/transforms/__init__.py @@ -29,6 +29,7 @@ from sphinx.config import Config from sphinx.domains.std import StandardDomain from sphinx.environment import BuildEnvironment + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -488,7 +489,7 @@ def _sort_key(node: nodes.Node) -> int: raise ValueError(msg) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_transform(ApplySourceWorkaround) app.add_transform(ExtraTranslatableNodes) app.add_transform(DefaultSubstitutions) diff --git a/sphinx/transforms/compact_bullet_list.py b/sphinx/transforms/compact_bullet_list.py index ca34826a7b7..acd8634783b 100644 --- a/sphinx/transforms/compact_bullet_list.py +++ b/sphinx/transforms/compact_bullet_list.py @@ -13,6 +13,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata class RefOnlyListChecker(nodes.GenericNodeVisitor): @@ -80,7 +81,7 @@ def check_refonly_list(node: Node) -> bool: item.replace(para, compact_para) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_transform(RefOnlyBulletListTransform) return { diff --git a/sphinx/transforms/i18n.py b/sphinx/transforms/i18n.py index a52a6427850..3239dcd73a2 100644 --- a/sphinx/transforms/i18n.py +++ b/sphinx/transforms/i18n.py @@ -33,6 +33,7 @@ from sphinx.application import Sphinx from sphinx.config import Config + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -611,7 +612,7 @@ def apply(self, **kwargs: Any) -> None: inline.parent += inline.children -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_transform(PreserveTranslatableMessages) app.add_transform(Locale) app.add_transform(TranslationProgressTotaliser) diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py index efb5272c11f..cfaa31c3fab 100644 --- a/sphinx/transforms/post_transforms/__init__.py +++ b/sphinx/transforms/post_transforms/__init__.py @@ -23,6 +23,7 @@ from sphinx.addnodes import pending_xref from sphinx.application import Sphinx from sphinx.domains import Domain + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -288,7 +289,7 @@ def run(self, **kwargs: Any) -> None: node['classes'].append(node.parent['domain']) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_post_transform(ReferencesResolver) app.add_post_transform(OnlyNodeTransform) app.add_post_transform(SigElementFallbackTransform) diff --git a/sphinx/transforms/post_transforms/code.py b/sphinx/transforms/post_transforms/code.py index 047766a1126..4375b4d89c2 100644 --- a/sphinx/transforms/post_transforms/code.py +++ b/sphinx/transforms/post_transforms/code.py @@ -16,6 +16,7 @@ from docutils.nodes import Node, TextElement from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata class HighlightSetting(NamedTuple): @@ -130,7 +131,7 @@ def is_pyconsole(node: nodes.literal_block) -> bool: return False -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_post_transform(HighlightLanguageTransform) app.add_post_transform(TrimDoctestFlagsTransform) diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py index c70254b42a1..04e2ac2f40d 100644 --- a/sphinx/transforms/post_transforms/images.py +++ b/sphinx/transforms/post_transforms/images.py @@ -19,6 +19,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata logger = logging.getLogger(__name__) @@ -275,7 +276,7 @@ def convert(self, _from: str, _to: str) -> bool: raise NotImplementedError -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_post_transform(ImageDownloader) app.add_post_transform(DataURIExtractor) diff --git a/sphinx/transforms/references.py b/sphinx/transforms/references.py index fdada70ffd0..e0dfeb19088 100644 --- a/sphinx/transforms/references.py +++ b/sphinx/transforms/references.py @@ -10,6 +10,7 @@ if TYPE_CHECKING: from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata class SphinxDanglingReferences(DanglingReferences): @@ -37,7 +38,7 @@ def apply(self, **kwargs: Any) -> None: domain.process_doc(self.env, self.env.docname, self.document) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_transform(SphinxDanglingReferences) app.add_transform(SphinxDomains) diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py index 67e7fc1d3cf..9739c1842d0 100644 --- a/sphinx/util/typing.py +++ b/sphinx/util/typing.py @@ -90,17 +90,28 @@ def is_invalid_builtin_class(obj: Any) -> bool: Inventory = dict[str, dict[str, InventoryItem]] -# return of a setup() function -# https://www.sphinx-doc.org/en/master/extdev/index.html#extension-metadata -class _ExtensionMetadata(TypedDict, total=False): +class ExtensionMetadata(TypedDict, total=False): + """The metadata returned by an extension's ``setup()`` function. + + See :ref:`ext-metadata`. + """ + version: str + """The extension version (default: ``'unknown version'``).""" env_version: int + """An integer that identifies the version of env data added by the extension.""" parallel_read_safe: bool + """Indicate whether parallel reading of source files is supported + by the extension. + """ parallel_write_safe: bool + """Indicate whether parallel writing of output files is supported + by the extension (default: ``True``). + """ if TYPE_CHECKING: - _ExtensionSetupFunc = Callable[[Sphinx], _ExtensionMetadata] + _ExtensionSetupFunc = Callable[[Sphinx], ExtensionMetadata] def get_type_hints( diff --git a/sphinx/versioning.py b/sphinx/versioning.py index da58f5e58d7..a5ec7019282 100644 --- a/sphinx/versioning.py +++ b/sphinx/versioning.py @@ -17,6 +17,7 @@ from docutils.nodes import Node from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata try: import Levenshtein # type: ignore[import-not-found] @@ -171,7 +172,7 @@ def apply(self, **kwargs: Any) -> None: list(merge_doctrees(old_doctree, self.document, env.versioning_condition)) -def setup(app: Sphinx) -> dict[str, Any]: +def setup(app: Sphinx) -> ExtensionMetadata: app.add_transform(UIDTransform) return {