summaryrefslogtreecommitdiff
path: root/sphinx/application.py
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2019-12-25 11:41:54 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2019-12-25 11:41:54 +0900
commitd717f5ae31d17533a5a20b581f571eb4a95b1b30 (patch)
tree65bb3a38edc57d2b5e70b19ca8996ccebd1e3951 /sphinx/application.py
parentd82e7c12a177a6a547ba1e72540f079f64590f8a (diff)
parent869ba4f67947b97af90dc706fb7e6ed17946ccd3 (diff)
downloadsphinx-git-d717f5ae31d17533a5a20b581f571eb4a95b1b30.tar.gz
Merge branch '2.0'
Diffstat (limited to 'sphinx/application.py')
-rw-r--r--sphinx/application.py199
1 files changed, 82 insertions, 117 deletions
diff --git a/sphinx/application.py b/sphinx/application.py
index 99490cecd..65b6c4eb2 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -18,8 +18,12 @@ import warnings
from collections import deque
from io import StringIO
from os import path
+from typing import Any, Callable, Dict, IO, List, Tuple, Union
+from docutils import nodes
+from docutils.nodes import Element, TextElement
from docutils.parsers.rst import Directive, roles
+from docutils.transforms import Transform
from pygments.lexer import Lexer
import sphinx
@@ -27,12 +31,16 @@ from sphinx import package_dir, locale
from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.environment import BuildEnvironment
+from sphinx.environment.collectors import EnvironmentCollector
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
from sphinx.events import EventManager
+from sphinx.extension import Extension
from sphinx.highlighting import lexer_classes, lexers
from sphinx.locale import __
from sphinx.project import Project
from sphinx.registry import SphinxComponentRegistry
+from sphinx.roles import XRefRole
+from sphinx.theming import Theme
from sphinx.util import docutils
from sphinx.util import logging
from sphinx.util import progress_message
@@ -42,21 +50,14 @@ from sphinx.util.i18n import CatalogRepository
from sphinx.util.logging import prefixed_warnings
from sphinx.util.osutil import abspath, ensuredir, relpath
from sphinx.util.tags import Tags
+from sphinx.util.typing import RoleFunction, TitleGetter
if False:
# For type annotation
- from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Tuple, Union # NOQA
+ from docutils.nodes import Node # NOQA
from typing import Type # for python3.5.1
- from docutils import nodes # NOQA
- from docutils.parsers import Parser # NOQA
- from docutils.transforms import Transform # NOQA
- from sphinx.builders import Builder # NOQA
- from sphinx.domains import Domain, Index # NOQA
- from sphinx.environment.collectors import EnvironmentCollector # NOQA
- from sphinx.extension import Extension # NOQA
- from sphinx.roles import XRefRole # NOQA
- from sphinx.theming import Theme # NOQA
- from sphinx.util.typing import RoleFunction, TitleGetter # NOQA
+ from sphinx.builders import Builder
+
builtin_extensions = (
'sphinx.addnodes',
@@ -132,11 +133,11 @@ class Sphinx:
:ivar outdir: Directory for storing build documents.
"""
- def __init__(self, srcdir, confdir, outdir, doctreedir, buildername,
- confoverrides=None, status=sys.stdout, warning=sys.stderr,
- freshenv=False, warningiserror=False, tags=None, verbosity=0,
- parallel=0, keep_going=False):
- # type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None # NOQA
+ def __init__(self, srcdir: str, confdir: str, outdir: str, doctreedir: str,
+ buildername: str, confoverrides: Dict = None,
+ status: IO = sys.stdout, warning: IO = sys.stderr,
+ freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
+ verbosity: int = 0, parallel: int = 0, keep_going: bool = False) -> None:
self.phase = BuildPhase.INITIALIZATION
self.verbosity = verbosity
self.extensions = {} # type: Dict[str, Extension]
@@ -270,8 +271,7 @@ class Sphinx:
# set up the builder
self._init_builder()
- def _init_i18n(self):
- # type: () -> None
+ def _init_i18n(self) -> None:
"""Load translated strings from the configured localedirs if enabled in
the configuration.
"""
@@ -296,8 +296,7 @@ class Sphinx:
else:
logger.info(__('not available for built-in messages'))
- def _init_env(self, freshenv):
- # type: (bool) -> None
+ def _init_env(self, freshenv: bool) -> None:
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
if freshenv or not os.path.exists(filename):
self.env = BuildEnvironment()
@@ -313,28 +312,24 @@ class Sphinx:
logger.info(__('failed: %s'), err)
self._init_env(freshenv=True)
- def preload_builder(self, name):
- # type: (str) -> None
+ def preload_builder(self, name: str) -> None:
self.registry.preload_builder(self, name)
- def create_builder(self, name):
- # type: (str) -> Builder
+ def create_builder(self, name: str) -> "Builder":
if name is None:
logger.info(__('No builder selected, using default: html'))
name = 'html'
return self.registry.create_builder(self, name)
- def _init_builder(self):
- # type: () -> None
+ def _init_builder(self) -> None:
self.builder.set_environment(self.env)
self.builder.init()
self.events.emit('builder-inited')
# ---- main "build" method -------------------------------------------------
- def build(self, force_all=False, filenames=None):
- # type: (bool, List[str]) -> None
+ def build(self, force_all: bool = False, filenames: List[str] = None) -> None:
self.phase = BuildPhase.READING
try:
if force_all:
@@ -385,8 +380,7 @@ class Sphinx:
# ---- general extensibility interface -------------------------------------
- def setup_extension(self, extname):
- # type: (str) -> None
+ def setup_extension(self, extname: str) -> None:
"""Import and setup a Sphinx extension module.
Load the extension given by the module *name*. Use this if your
@@ -396,8 +390,7 @@ class Sphinx:
logger.debug('[app] setting up extension: %r', extname)
self.registry.load_extension(self, extname)
- def require_sphinx(self, version):
- # type: (str) -> None
+ def require_sphinx(self, version: str) -> None:
"""Check the Sphinx version if requested.
Compare *version* (which must be a ``major.minor`` version string, e.g.
@@ -410,8 +403,7 @@ class Sphinx:
raise VersionRequirementError(version)
# event interface
- def connect(self, event, callback):
- # type: (str, Callable) -> int
+ def connect(self, event: str, callback: Callable) -> int:
"""Register *callback* to be called when *event* is emitted.
For details on available core events and the arguments of callback
@@ -424,14 +416,12 @@ class Sphinx:
logger.debug('[app] connecting event %r: %r [id=%s]', event, callback, listener_id)
return listener_id
- def disconnect(self, listener_id):
- # type: (int) -> None
+ def disconnect(self, listener_id: int) -> None:
"""Unregister callback by *listener_id*."""
logger.debug('[app] disconnecting event: [id=%s]', listener_id)
self.events.disconnect(listener_id)
- def emit(self, event, *args):
- # type: (str, Any) -> List
+ def emit(self, event: str, *args) -> List:
"""Emit *event* and pass *arguments* to the callback functions.
Return the return values of all callbacks as a list. Do not emit core
@@ -439,8 +429,7 @@ class Sphinx:
"""
return self.events.emit(event, *args)
- def emit_firstresult(self, event, *args):
- # type: (str, Any) -> Any
+ def emit_firstresult(self, event: str, *args) -> Any:
"""Emit *event* and pass *arguments* to the callback functions.
Return the result of the first callback that doesn't return ``None``.
@@ -451,8 +440,7 @@ class Sphinx:
# registering addon parts
- def add_builder(self, builder, override=False):
- # type: (Type[Builder], bool) -> None
+ def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
"""Register a new builder.
*builder* must be a class that inherits from
@@ -464,8 +452,8 @@ class Sphinx:
self.registry.add_builder(builder, override=override)
# TODO(stephenfin): Describe 'types' parameter
- def add_config_value(self, name, default, rebuild, types=()):
- # type: (str, Any, Union[bool, str], Any) -> None
+ def add_config_value(self, name: str, default: Any, rebuild: Union[bool, str],
+ types: Any = ()) -> None:
"""Register a configuration value.
This is necessary for Sphinx to recognize new values and set default
@@ -497,8 +485,7 @@ class Sphinx:
rebuild = 'env' if rebuild else ''
self.config.add(name, default, rebuild, types)
- def add_event(self, name):
- # type: (str) -> None
+ def add_event(self, name: str) -> None:
"""Register an event called *name*.
This is needed to be able to emit it.
@@ -506,8 +493,8 @@ class Sphinx:
logger.debug('[app] adding event: %r', name)
self.events.add(name)
- def set_translator(self, name, translator_class, override=False):
- # type: (str, Type[nodes.NodeVisitor], bool) -> None
+ def set_translator(self, name: str, translator_class: "Type[nodes.NodeVisitor]",
+ override: bool = False) -> None:
"""Register or override a Docutils translator class.
This is used to register a custom output translator or to replace a
@@ -520,8 +507,7 @@ class Sphinx:
"""
self.registry.add_translator(name, translator_class, override=override)
- def add_node(self, node, override=False, **kwds):
- # type: (Type[nodes.Element], bool, Any) -> None
+ def add_node(self, node: "Type[Element]", override: bool = False, **kwds) -> None:
"""Register a Docutils node class.
This is necessary for Docutils internals. It may also be used in the
@@ -559,8 +545,9 @@ class Sphinx:
docutils.register_node(node)
self.registry.add_translation_handlers(node, **kwds)
- def add_enumerable_node(self, node, figtype, title_getter=None, override=False, **kwds):
- # type: (Type[nodes.Element], str, TitleGetter, bool, Any) -> None
+ def add_enumerable_node(self, node: "Type[Element]", figtype: str,
+ title_getter: TitleGetter = None, override: bool = False,
+ **kwds) -> None:
"""Register a Docutils node class as a numfig target.
Sphinx numbers the node automatically. And then the users can refer it
@@ -587,8 +574,7 @@ class Sphinx:
self.registry.add_enumerable_node(node, figtype, title_getter, override=override)
self.add_node(node, override=override, **kwds)
- def add_directive(self, name, cls, override=False):
- # type: (str, Type[Directive], bool) -> None
+ def add_directive(self, name: str, cls: "Type[Directive]", override: bool = False):
"""Register a Docutils directive.
*name* must be the prospective directive name. *cls* is a directive
@@ -632,8 +618,7 @@ class Sphinx:
docutils.register_directive(name, cls)
- def add_role(self, name, role, override=False):
- # type: (str, Any, bool) -> None
+ def add_role(self, name: str, role: Any, override: bool = False) -> None:
"""Register a Docutils role.
*name* must be the role name that occurs in the source, *role* the role
@@ -650,8 +635,7 @@ class Sphinx:
name, type='app', subtype='add_role')
docutils.register_role(name, role)
- def add_generic_role(self, name, nodeclass, override=False):
- # type: (str, Any, bool) -> None
+ def add_generic_role(self, name: str, nodeclass: Any, override: bool = False) -> None:
"""Register a generic Docutils role.
Register a Docutils role that does nothing but wrap its contents in the
@@ -670,8 +654,7 @@ class Sphinx:
role = roles.GenericRole(name, nodeclass)
docutils.register_role(name, role)
- def add_domain(self, domain, override=False):
- # type: (Type[Domain], bool) -> None
+ def add_domain(self, domain: "Type[Domain]", override: bool = False) -> None:
"""Register a domain.
Make the given *domain* (which must be a class; more precisely, a
@@ -683,8 +666,8 @@ class Sphinx:
"""
self.registry.add_domain(domain, override=override)
- def add_directive_to_domain(self, domain, name, cls, override=False):
- # type: (str, str, Type[Directive], bool) -> None
+ def add_directive_to_domain(self, domain: str, name: str,
+ cls: "Type[Directive]", override: bool = False) -> None:
"""Register a Docutils directive in a domain.
Like :meth:`add_directive`, but the directive is added to the domain
@@ -696,8 +679,8 @@ class Sphinx:
"""
self.registry.add_directive_to_domain(domain, name, cls, override=override)
- def add_role_to_domain(self, domain, name, role, override=False):
- # type: (str, str, Union[RoleFunction, XRefRole], bool) -> None
+ def add_role_to_domain(self, domain: str, name: str, role: Union[RoleFunction, XRefRole],
+ override: bool = False) -> None:
"""Register a Docutils role in a domain.
Like :meth:`add_role`, but the role is added to the domain named
@@ -709,8 +692,8 @@ class Sphinx:
"""
self.registry.add_role_to_domain(domain, name, role, override=override)
- def add_index_to_domain(self, domain, index, override=False):
- # type: (str, Type[Index], bool) -> None
+ def add_index_to_domain(self, domain: str, index: "Type[Index]", override: bool = False
+ ) -> None:
"""Register a custom index for a domain.
Add a custom *index* class to the domain named *domain*. *index* must
@@ -722,10 +705,10 @@ class Sphinx:
"""
self.registry.add_index_to_domain(domain, index)
- def add_object_type(self, directivename, rolename, indextemplate='',
- parse_node=None, ref_nodeclass=None, objname='',
- doc_field_types=[], override=False):
- # type: (str, str, str, Callable, Type[nodes.TextElement], str, List, bool) -> None
+ def add_object_type(self, directivename: str, rolename: str, indextemplate: str = '',
+ parse_node: Callable = None, ref_nodeclass: "Type[TextElement]" = None,
+ objname: str = '', doc_field_types: List = [], override: bool = False
+ ) -> None:
"""Register a new object type.
This method is a very convenient way to add a new :term:`object` type
@@ -786,9 +769,9 @@ class Sphinx:
ref_nodeclass, objname, doc_field_types,
override=override)
- def add_crossref_type(self, directivename, rolename, indextemplate='',
- ref_nodeclass=None, objname='', override=False):
- # type: (str, str, str, Type[nodes.TextElement], str, bool) -> None
+ def add_crossref_type(self, directivename: str, rolename: str, indextemplate: str = '',
+ ref_nodeclass: "Type[TextElement]" = None, objname: str = '',
+ override: bool = False) -> None:
"""Register a new crossref object type.
This method is very similar to :meth:`add_object_type` except that the
@@ -822,8 +805,7 @@ class Sphinx:
indextemplate, ref_nodeclass, objname,
override=override)
- def add_transform(self, transform):
- # type: (Type[Transform]) -> None
+ def add_transform(self, transform: "Type[Transform]") -> None:
"""Register a Docutils transform to be applied after parsing.
Add the standard docutils :class:`Transform` subclass *transform* to
@@ -856,8 +838,7 @@ class Sphinx:
""" # NOQA
self.registry.add_transform(transform)
- def add_post_transform(self, transform):
- # type: (Type[Transform]) -> None
+ def add_post_transform(self, transform: "Type[Transform]") -> None:
"""Register a Docutils transform to be applied before writing.
Add the standard docutils :class:`Transform` subclass *transform* to
@@ -866,16 +847,14 @@ class Sphinx:
"""
self.registry.add_post_transform(transform)
- def add_javascript(self, filename, **kwargs):
- # type: (str, **str) -> None
+ def add_javascript(self, filename: str, **kwargs: str) -> None:
"""An alias of :meth:`add_js_file`."""
warnings.warn('The app.add_javascript() is deprecated. '
'Please use app.add_js_file() instead.',
RemovedInSphinx40Warning, stacklevel=2)
self.add_js_file(filename, **kwargs)
- def add_js_file(self, filename, **kwargs):
- # type: (str, **str) -> None
+ def add_js_file(self, filename: str, **kwargs: str) -> None:
"""Register a JavaScript file to include in the HTML output.
Add *filename* to the list of JavaScript files that the default HTML
@@ -901,8 +880,7 @@ class Sphinx:
if hasattr(self.builder, 'add_js_file'):
self.builder.add_js_file(filename, **kwargs) # type: ignore
- def add_css_file(self, filename, **kwargs):
- # type: (str, **str) -> None
+ def add_css_file(self, filename: str, **kwargs: str) -> None:
"""Register a stylesheet to include in the HTML output.
Add *filename* to the list of CSS files that the default HTML template
@@ -941,8 +919,8 @@ class Sphinx:
if hasattr(self.builder, 'add_css_file'):
self.builder.add_css_file(filename, **kwargs) # type: ignore
- def add_stylesheet(self, filename, alternate=False, title=None):
- # type: (str, bool, str) -> None
+ def add_stylesheet(self, filename: str, alternate: bool = False, title: str = None
+ ) -> None:
"""An alias of :meth:`add_css_file`."""
warnings.warn('The app.add_stylesheet() is deprecated. '
'Please use app.add_css_file() instead.',
@@ -959,8 +937,7 @@ class Sphinx:
self.add_css_file(filename, **attributes)
- def add_latex_package(self, packagename, options=None):
- # type: (str, str) -> None
+ def add_latex_package(self, packagename: str, options: str = None) -> None:
r"""Register a package to include in the LaTeX source code.
Add *packagename* to the list of packages that LaTeX source code will
@@ -978,8 +955,7 @@ class Sphinx:
"""
self.registry.add_latex_package(packagename, options)
- def add_lexer(self, alias, lexer):
- # type: (str, Union[Lexer, Type[Lexer]]) -> None
+ def add_lexer(self, alias: str, lexer: Union[Lexer, "Type[Lexer]"]) -> None:
"""Register a new lexer for source code.
Use *lexer* to highlight code blocks with the given language *alias*.
@@ -998,8 +974,7 @@ class Sphinx:
else:
lexer_classes[alias] = lexer
- def add_autodocumenter(self, cls, override=False):
- # type: (Any, bool) -> None
+ def add_autodocumenter(self, cls: Any, override: bool = False) -> None:
"""Register a new documenter class for the autodoc extension.
Add *cls* as a new documenter class for the :mod:`sphinx.ext.autodoc`
@@ -1019,8 +994,8 @@ class Sphinx:
self.registry.add_documenter(cls.objtype, cls)
self.add_directive('auto' + cls.objtype, AutodocDirective, override=override)
- def add_autodoc_attrgetter(self, typ, getter):
- # type: (Type, Callable[[Any, str, Any], Any]) -> None
+ def add_autodoc_attrgetter(self, typ: "Type", getter: Callable[[Any, str, Any], Any]
+ ) -> None:
"""Register a new ``getattr``-like function for the autodoc extension.
Add *getter*, which must be a function with an interface compatible to
@@ -1034,8 +1009,7 @@ class Sphinx:
logger.debug('[app] adding autodoc attrgetter: %r', (typ, getter))
self.registry.add_autodoc_attrgetter(typ, getter)
- def add_search_language(self, cls):
- # type: (Any) -> None
+ def add_search_language(self, cls: Any) -> None:
"""Register a new language for the HTML search index.
Add *cls*, which must be a subclass of
@@ -1051,8 +1025,7 @@ class Sphinx:
assert issubclass(cls, SearchLanguage)
languages[cls.lang] = cls
- def add_source_suffix(self, suffix, filetype, override=False):
- # type: (str, str, bool) -> None
+ def add_source_suffix(self, suffix: str, filetype: str, override: bool = False) -> None:
"""Register a suffix of source files.
Same as :confval:`source_suffix`. The users can override this
@@ -1062,8 +1035,7 @@ class Sphinx:
"""
self.registry.add_source_suffix(suffix, filetype, override=override)
- def add_source_parser(self, *args, **kwargs):
- # type: (Any, Any) -> None
+ def add_source_parser(self, *args, **kwargs) -> None:
"""Register a parser class.
.. versionadded:: 1.4
@@ -1075,8 +1047,7 @@ class Sphinx:
"""
self.registry.add_source_parser(*args, **kwargs)
- def add_env_collector(self, collector):
- # type: (Type[EnvironmentCollector]) -> None
+ def add_env_collector(self, collector: "Type[EnvironmentCollector]") -> None:
"""Register an environment collector class.
Refer to :ref:`collector-api`.
@@ -1086,8 +1057,7 @@ class Sphinx:
logger.debug('[app] adding environment collector: %r', collector)
collector().enable(self)
- def add_html_theme(self, name, theme_path):
- # type: (str, str) -> None
+ def add_html_theme(self, name: str, theme_path: str) -> None:
"""Register a HTML Theme.
The *name* is a name of theme, and *path* is a full path to the theme
@@ -1098,8 +1068,9 @@ class Sphinx:
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path
- def add_html_math_renderer(self, name, inline_renderers=None, block_renderers=None):
- # type: (str, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
+ def add_html_math_renderer(self, name: str,
+ inline_renderers: Tuple[Callable, Callable] = None,
+ block_renderers: Tuple[Callable, Callable] = None) -> None:
"""Register a math renderer for HTML.
The *name* is a name of math renderer. Both *inline_renderers* and
@@ -1113,8 +1084,7 @@ class Sphinx:
"""
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
- def add_message_catalog(self, catalog, locale_dir):
- # type: (str, str) -> None
+ def add_message_catalog(self, catalog: str, locale_dir: str) -> None:
"""Register a message catalog.
The *catalog* is a name of catalog, and *locale_dir* is a base path
@@ -1127,8 +1097,7 @@ class Sphinx:
locale.init_console(locale_dir, catalog)
# ---- other methods -------------------------------------------------
- def is_parallel_allowed(self, typ):
- # type: (str) -> bool
+ def is_parallel_allowed(self, typ: str) -> bool:
"""Check parallel processing is allowed or not.
``typ`` is a type of processing; ``'read'`` or ``'write'``.
@@ -1170,8 +1139,7 @@ class TemplateBridge:
that renders templates given a template name and a context.
"""
- def init(self, builder, theme=None, dirs=None):
- # type: (Builder, Theme, List[str]) -> None
+ def init(self, builder: "Builder", theme: Theme = None, dirs: List[str] = None) -> None:
"""Called by the builder to initialize the template system.
*builder* is the builder object; you'll probably want to look at the
@@ -1182,23 +1150,20 @@ class TemplateBridge:
"""
raise NotImplementedError('must be implemented in subclasses')
- def newest_template_mtime(self):
- # type: () -> float
+ def newest_template_mtime(self) -> float:
"""Called by the builder to determine if output files are outdated
because of template changes. Return the mtime of the newest template
file that was changed. The default implementation returns ``0``.
"""
return 0
- def render(self, template, context):
- # type: (str, Dict) -> None
+ def render(self, template: str, context: Dict) -> None:
"""Called by the builder to render a template given as a filename with
a specified context (a Python dictionary).
"""
raise NotImplementedError('must be implemented in subclasses')
- def render_string(self, template, context):
- # type: (str, Dict) -> str
+ def render_string(self, template: str, context: Dict) -> str:
"""Called by the builder to render a template given as a string with a
specified context (a Python dictionary).
"""