mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-13 00:42:11 -05:00
[builder] type Builder core methods with @final and improve docs (#12436)
This commit: - annotates the `Builder`'s "core" methods, with [`final`](https://docs.python.org/3/library/typing.html#typing.final) - adds a UML graph to the Builder API docs - Adds more methods to the Builder API docs to make it clearer for extension developers, what is expected from a new builder subclass.
This commit is contained in:
1 parent
e30430d2ba
commit
37ff33dff7
4 files changed
+87
-12
No files matched your search
@@ -18,6 +18,7 @@ extensions = [
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinx.ext.inheritance_diagram',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.graphviz',
|
||||
]
|
||||
coverage_statistics_to_report = coverage_statistics_to_stdout = True
|
||||
templates_path = ['_templates']
|
||||
|
||||
@@ -3,15 +3,66 @@
|
||||
Builder API
|
||||
===========
|
||||
|
||||
.. todo:: Expand this.
|
||||
|
||||
.. currentmodule:: sphinx.builders
|
||||
|
||||
.. class:: Builder
|
||||
|
||||
This is the base class for all builders.
|
||||
|
||||
These attributes should be set on builder classes:
|
||||
It follows this basic workflow:
|
||||
|
||||
.. graphviz::
|
||||
:caption: UML for the standard Sphinx build workflow
|
||||
|
||||
digraph build {
|
||||
graph [
|
||||
rankdir=LR
|
||||
];
|
||||
node [
|
||||
shape=rect
|
||||
style=rounded
|
||||
];
|
||||
|
||||
"Sphinx" [
|
||||
shape=record
|
||||
label = "Sphinx | <init> __init__ | <build> build"
|
||||
];
|
||||
"Sphinx":init -> "Builder.init";
|
||||
"Sphinx":build -> "Builder.build_all";
|
||||
"Sphinx":build -> "Builder.build_specific";
|
||||
"Builder.build_update" [
|
||||
shape=record
|
||||
label = "<p1> Builder.build_update | Builder.get_outdated_docs"
|
||||
];
|
||||
"Sphinx":build -> "Builder.build_update":p1 ;
|
||||
|
||||
"Builder.build_all" -> "Builder.build";
|
||||
"Builder.build_specific" -> "Builder.build";
|
||||
"Builder.build_update":p1 -> "Builder.build";
|
||||
|
||||
"Builder.build" -> "Builder.read";
|
||||
"Builder.write" [
|
||||
shape=record
|
||||
label = "<p1> Builder.write | Builder._write_serial | Builder._write_parallel"
|
||||
];
|
||||
"Builder.build" -> "Builder.write";
|
||||
"Builder.build" -> "Builder.finish";
|
||||
|
||||
"Builder.read" -> "Builder.read_doc";
|
||||
"Builder.read_doc" -> "Builder.write_doctree";
|
||||
|
||||
"Builder.write":p1 -> "Builder.prepare_writing";
|
||||
"Builder.write":p1 -> "Builder.copy_assets";
|
||||
"Builder.write":p1 -> "Builder.write_doc";
|
||||
|
||||
"Builder.write_doc" -> "Builder.get_relative_uri";
|
||||
|
||||
"Builder.get_relative_uri" -> "Builder.get_target_uri";
|
||||
}
|
||||
|
||||
.. rubric:: Overridable Attributes
|
||||
|
||||
These attributes should be set on builder sub-classes:
|
||||
|
||||
.. autoattribute:: name
|
||||
.. autoattribute:: format
|
||||
@@ -22,24 +73,39 @@ Builder API
|
||||
.. autoattribute:: supported_data_uri_images
|
||||
.. autoattribute:: default_translator_class
|
||||
|
||||
These methods are predefined and will be called from the application:
|
||||
.. rubric:: Core Methods
|
||||
|
||||
These methods are predefined and should generally not be overridden,
|
||||
since they form the core of the build process:
|
||||
|
||||
.. automethod:: get_relative_uri
|
||||
.. automethod:: build_all
|
||||
.. automethod:: build_specific
|
||||
.. automethod:: build_update
|
||||
.. automethod:: build
|
||||
.. automethod:: read
|
||||
.. automethod:: read_doc
|
||||
.. automethod:: write_doctree
|
||||
|
||||
These methods can be overridden in concrete builder classes:
|
||||
.. rubric:: Overridable Methods
|
||||
|
||||
These must be implemented in builder sub-classes:
|
||||
|
||||
.. automethod:: init
|
||||
.. automethod:: get_outdated_docs
|
||||
.. automethod:: get_target_uri
|
||||
.. automethod:: prepare_writing
|
||||
.. automethod:: write_doc
|
||||
.. automethod:: get_target_uri
|
||||
|
||||
These methods can be overridden in builder sub-classes:
|
||||
|
||||
.. automethod:: init
|
||||
.. automethod:: write
|
||||
.. automethod:: copy_assets
|
||||
.. automethod:: get_relative_uri
|
||||
.. automethod:: finish
|
||||
|
||||
**Attributes**
|
||||
.. rubric:: Attributes
|
||||
|
||||
Attributes that are callable from the builder instance:
|
||||
|
||||
.. attribute:: events
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import codecs
|
||||
import pickle
|
||||
import time
|
||||
from os import path
|
||||
from typing import TYPE_CHECKING, Any, Literal
|
||||
from typing import TYPE_CHECKING, Any, Literal, final
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.utils import DependencyList
|
||||
@@ -245,12 +245,14 @@ class Builder:
|
||||
|
||||
# build methods
|
||||
|
||||
@final
|
||||
def build_all(self) -> None:
|
||||
"""Build all source files."""
|
||||
self.compile_all_catalogs()
|
||||
|
||||
self.build(None, summary=__('all source files'), method='all')
|
||||
|
||||
@final
|
||||
def build_specific(self, filenames: list[str]) -> None:
|
||||
"""Only rebuild as much as needed for changes in the *filenames*."""
|
||||
docnames: list[str] = []
|
||||
@@ -281,6 +283,7 @@ class Builder:
|
||||
self.build(docnames, method='specific',
|
||||
summary=__('%d source files given on command line') % len(docnames))
|
||||
|
||||
@final
|
||||
def build_update(self) -> None:
|
||||
"""Only rebuild what was changed or added since last build."""
|
||||
self.compile_update_catalogs()
|
||||
@@ -294,6 +297,7 @@ class Builder:
|
||||
summary=__('targets for %d source files that are out of date') %
|
||||
len(to_build))
|
||||
|
||||
@final
|
||||
def build(
|
||||
self,
|
||||
docnames: Iterable[str] | None,
|
||||
@@ -367,6 +371,7 @@ class Builder:
|
||||
# wait for all tasks
|
||||
self.finish_tasks.join()
|
||||
|
||||
@final
|
||||
def read(self) -> list[str]:
|
||||
"""(Re-)read all files new or changed since last update.
|
||||
|
||||
@@ -473,6 +478,7 @@ class Builder:
|
||||
tasks.join()
|
||||
logger.info('')
|
||||
|
||||
@final
|
||||
def read_doc(self, docname: str, *, _cache: bool = True) -> None:
|
||||
"""Parse a file and add/update inventory entries for the doctree."""
|
||||
self.env.prepare_settings(docname)
|
||||
@@ -507,10 +513,11 @@ class Builder:
|
||||
|
||||
self.write_doctree(docname, doctree, _cache=_cache)
|
||||
|
||||
@final
|
||||
def write_doctree(
|
||||
self, docname: str, doctree: nodes.document, *, _cache: bool = True,
|
||||
) -> None:
|
||||
"""Write the doctree to a file."""
|
||||
"""Write the doctree to a file, to be used as a cache by re-builds."""
|
||||
# make it picklable
|
||||
doctree.reporter = None # type: ignore[assignment]
|
||||
doctree.transformer = None # type: ignore[assignment]
|
||||
@@ -539,6 +546,7 @@ class Builder:
|
||||
updated_docnames: Sequence[str],
|
||||
method: Literal['all', 'specific', 'update'] = 'update',
|
||||
) -> None:
|
||||
"""Write builder specific output files."""
|
||||
if build_docnames is None or build_docnames == ['__all__']:
|
||||
# build_all
|
||||
build_docnames = self.env.found_docs
|
||||
|
||||
@@ -257,7 +257,7 @@ class MessageCatalogBuilder(I18nBuilder):
|
||||
msg = f'{template}: {exc!r}'
|
||||
raise ThemeError(msg) from exc
|
||||
|
||||
def build(
|
||||
def build( # type: ignore[misc]
|
||||
self,
|
||||
docnames: Iterable[str] | None,
|
||||
summary: str | None = None,
|
||||
|
||||
Reference in new issue
Block a user