Skip to content

Commit

Permalink
👌 Make ExtensionMetadata type public and use it in internal extensi…
Browse files Browse the repository at this point in the history
…ons (#12153)

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>
  • Loading branch information
chrisjsewell and picnixz authored Mar 21, 2024
1 parent ace9d97 commit d59b158
Show file tree
Hide file tree
Showing 75 changed files with 200 additions and 122 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
5 changes: 4 additions & 1 deletion doc/development/tutorials/examples/helloworld.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
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):
paragraph_node = nodes.paragraph(text='Hello World!')
return [paragraph_node]


def setup(app):
def setup(app: Sphinx) -> ExtensionMetadata:
app.add_directive('helloworld', HelloWorld)

return {
Expand Down
4 changes: 3 additions & 1 deletion doc/development/tutorials/examples/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion doc/development/tutorials/examples/todo.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down Expand Up @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions doc/extdev/utils.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,9 @@ Utility components

.. autoclass:: sphinx.events.EventManager
:members:

Utility types
-------------

.. autoclass:: sphinx.util.typing.ExtensionMetadata
:members:
3 changes: 2 additions & 1 deletion sphinx/addnodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions sphinx/builders/dirhtml.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
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
from sphinx.util.osutil import SEP, os_path

if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions sphinx/builders/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 __
Expand All @@ -11,6 +11,7 @@
from docutils.nodes import Node

from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata


class DummyBuilder(Builder):
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/epub3.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/gettext.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

from sphinx.application import Sphinx
from sphinx.config import Config
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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})
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/html/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/html/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

if TYPE_CHECKING:
from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata


class KeyboardTransform(SphinxPostTransform):
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/latex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/latex/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:')

Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/linkcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@

from sphinx.application import Sphinx
from sphinx.config import Config
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/manpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand Down Expand Up @@ -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, '')
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/singlehtml.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from docutils.nodes import Node

from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion sphinx/builders/texinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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, '')
Expand Down
5 changes: 3 additions & 2 deletions sphinx/builders/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -19,6 +19,7 @@
from docutils.nodes import Node

from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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')
Expand Down
5 changes: 3 additions & 2 deletions sphinx/builders/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -21,6 +21,7 @@
from docutils.nodes import Node

from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -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)

Expand Down
Loading

0 comments on commit d59b158

Please sign in to comment.