Migrate to py3 style type annotation: sphinx.application

This commit is contained in:
Takeshi KOMIYA 2019-12-25 01:35:31 +09:00
parent 6e88d66543
commit 337780c89f
2 changed files with 101 additions and 134 deletions

View File

@ -19,8 +19,12 @@ from collections import deque
from inspect import isclass from inspect import isclass
from io import StringIO from io import StringIO
from os import path 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.parsers.rst import Directive, roles
from docutils.transforms import Transform
from pygments.lexer import Lexer from pygments.lexer import Lexer
import sphinx import sphinx
@ -29,13 +33,18 @@ from sphinx.config import Config
from sphinx.deprecation import ( from sphinx.deprecation import (
RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias
) )
from sphinx.domains import Domain, Index
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.environment.collectors import EnvironmentCollector
from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError
from sphinx.events import EventManager from sphinx.events import EventManager
from sphinx.extension import Extension
from sphinx.highlighting import lexer_classes, lexers from sphinx.highlighting import lexer_classes, lexers
from sphinx.locale import __ from sphinx.locale import __
from sphinx.project import Project from sphinx.project import Project
from sphinx.registry import SphinxComponentRegistry from sphinx.registry import SphinxComponentRegistry
from sphinx.roles import XRefRole
from sphinx.theming import Theme
from sphinx.util import docutils from sphinx.util import docutils
from sphinx.util import import_object, progress_message from sphinx.util import import_object, progress_message
from sphinx.util import logging from sphinx.util import logging
@ -46,21 +55,14 @@ from sphinx.util.i18n import CatalogRepository
from sphinx.util.logging import prefixed_warnings from sphinx.util.logging import prefixed_warnings
from sphinx.util.osutil import abspath, ensuredir, relpath from sphinx.util.osutil import abspath, ensuredir, relpath
from sphinx.util.tags import Tags from sphinx.util.tags import Tags
from sphinx.util.typing import RoleFunction, TitleGetter
if False: if False:
# For type annotation # 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 typing import Type # for python3.5.1
from docutils import nodes # NOQA from sphinx.builders import Builder
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
builtin_extensions = ( builtin_extensions = (
'sphinx.addnodes', 'sphinx.addnodes',
@ -137,11 +139,11 @@ class Sphinx:
:ivar outdir: Directory for storing build documents. :ivar outdir: Directory for storing build documents.
""" """
def __init__(self, srcdir, confdir, outdir, doctreedir, buildername, def __init__(self, srcdir: str, confdir: str, outdir: str, doctreedir: str,
confoverrides=None, status=sys.stdout, warning=sys.stderr, buildername: str, confoverrides: Dict = None,
freshenv=False, warningiserror=False, tags=None, verbosity=0, status: IO = sys.stdout, warning: IO = sys.stderr,
parallel=0, keep_going=False): freshenv: bool = False, warningiserror: bool = False, tags: List[str] = None,
# type: (str, str, str, str, str, Dict, IO, IO, bool, bool, List[str], int, int, bool) -> None # NOQA verbosity: int = 0, parallel: int = 0, keep_going: bool = False) -> None:
self.phase = BuildPhase.INITIALIZATION self.phase = BuildPhase.INITIALIZATION
self.verbosity = verbosity self.verbosity = verbosity
self.extensions = {} # type: Dict[str, Extension] self.extensions = {} # type: Dict[str, Extension]
@ -275,8 +277,7 @@ class Sphinx:
# set up the builder # set up the builder
self._init_builder() self._init_builder()
def _init_i18n(self): def _init_i18n(self) -> None:
# type: () -> None
"""Load translated strings from the configured localedirs if enabled in """Load translated strings from the configured localedirs if enabled in
the configuration. the configuration.
""" """
@ -301,8 +302,7 @@ class Sphinx:
else: else:
logger.info(__('not available for built-in messages')) logger.info(__('not available for built-in messages'))
def _init_env(self, freshenv): def _init_env(self, freshenv: bool) -> None:
# type: (bool) -> None
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME) filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
if freshenv or not os.path.exists(filename): if freshenv or not os.path.exists(filename):
self.env = BuildEnvironment() self.env = BuildEnvironment()
@ -318,28 +318,24 @@ class Sphinx:
logger.info(__('failed: %s'), err) logger.info(__('failed: %s'), err)
self._init_env(freshenv=True) self._init_env(freshenv=True)
def preload_builder(self, name): def preload_builder(self, name: str) -> None:
# type: (str) -> None
self.registry.preload_builder(self, name) self.registry.preload_builder(self, name)
def create_builder(self, name): def create_builder(self, name: str) -> "Builder":
# type: (str) -> Builder
if name is None: if name is None:
logger.info(__('No builder selected, using default: html')) logger.info(__('No builder selected, using default: html'))
name = 'html' name = 'html'
return self.registry.create_builder(self, name) return self.registry.create_builder(self, name)
def _init_builder(self): def _init_builder(self) -> None:
# type: () -> None
self.builder.set_environment(self.env) self.builder.set_environment(self.env)
self.builder.init() self.builder.init()
self.events.emit('builder-inited') self.events.emit('builder-inited')
# ---- main "build" method ------------------------------------------------- # ---- main "build" method -------------------------------------------------
def build(self, force_all=False, filenames=None): def build(self, force_all: bool = False, filenames: List[str] = None) -> None:
# type: (bool, List[str]) -> None
self.phase = BuildPhase.READING self.phase = BuildPhase.READING
try: try:
if force_all: if force_all:
@ -390,8 +386,7 @@ class Sphinx:
# ---- general extensibility interface ------------------------------------- # ---- general extensibility interface -------------------------------------
def setup_extension(self, extname): def setup_extension(self, extname: str) -> None:
# type: (str) -> None
"""Import and setup a Sphinx extension module. """Import and setup a Sphinx extension module.
Load the extension given by the module *name*. Use this if your Load the extension given by the module *name*. Use this if your
@ -401,8 +396,7 @@ class Sphinx:
logger.debug('[app] setting up extension: %r', extname) logger.debug('[app] setting up extension: %r', extname)
self.registry.load_extension(self, extname) self.registry.load_extension(self, extname)
def require_sphinx(self, version): def require_sphinx(self, version: str) -> None:
# type: (str) -> None
"""Check the Sphinx version if requested. """Check the Sphinx version if requested.
Compare *version* (which must be a ``major.minor`` version string, e.g. Compare *version* (which must be a ``major.minor`` version string, e.g.
@ -414,8 +408,7 @@ class Sphinx:
if version > sphinx.__display_version__[:3]: if version > sphinx.__display_version__[:3]:
raise VersionRequirementError(version) raise VersionRequirementError(version)
def import_object(self, objname, source=None): def import_object(self, objname: str, source: str = None) -> Any:
# type: (str, str) -> Any
"""Import an object from a ``module.name`` string. """Import an object from a ``module.name`` string.
.. deprecated:: 1.8 .. deprecated:: 1.8
@ -427,8 +420,7 @@ class Sphinx:
return import_object(objname, source=None) return import_object(objname, source=None)
# event interface # event interface
def connect(self, event, callback): def connect(self, event: str, callback: Callable) -> int:
# type: (str, Callable) -> int
"""Register *callback* to be called when *event* is emitted. """Register *callback* to be called when *event* is emitted.
For details on available core events and the arguments of callback For details on available core events and the arguments of callback
@ -441,14 +433,12 @@ class Sphinx:
logger.debug('[app] connecting event %r: %r [id=%s]', event, callback, listener_id) logger.debug('[app] connecting event %r: %r [id=%s]', event, callback, listener_id)
return listener_id return listener_id
def disconnect(self, listener_id): def disconnect(self, listener_id: int) -> None:
# type: (int) -> None
"""Unregister callback by *listener_id*.""" """Unregister callback by *listener_id*."""
logger.debug('[app] disconnecting event: [id=%s]', listener_id) logger.debug('[app] disconnecting event: [id=%s]', listener_id)
self.events.disconnect(listener_id) self.events.disconnect(listener_id)
def emit(self, event, *args): def emit(self, event: str, *args) -> List:
# type: (str, Any) -> List
"""Emit *event* and pass *arguments* to the callback functions. """Emit *event* and pass *arguments* to the callback functions.
Return the return values of all callbacks as a list. Do not emit core Return the return values of all callbacks as a list. Do not emit core
@ -456,8 +446,7 @@ class Sphinx:
""" """
return self.events.emit(event, *args) return self.events.emit(event, *args)
def emit_firstresult(self, event, *args): def emit_firstresult(self, event: str, *args) -> Any:
# type: (str, Any) -> Any
"""Emit *event* and pass *arguments* to the callback functions. """Emit *event* and pass *arguments* to the callback functions.
Return the result of the first callback that doesn't return ``None``. Return the result of the first callback that doesn't return ``None``.
@ -468,8 +457,7 @@ class Sphinx:
# registering addon parts # registering addon parts
def add_builder(self, builder, override=False): def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
# type: (Type[Builder], bool) -> None
"""Register a new builder. """Register a new builder.
*builder* must be a class that inherits from *builder* must be a class that inherits from
@ -481,8 +469,8 @@ class Sphinx:
self.registry.add_builder(builder, override=override) self.registry.add_builder(builder, override=override)
# TODO(stephenfin): Describe 'types' parameter # TODO(stephenfin): Describe 'types' parameter
def add_config_value(self, name, default, rebuild, types=()): def add_config_value(self, name: str, default: Any, rebuild: Union[bool, str],
# type: (str, Any, Union[bool, str], Any) -> None types: Any = ()) -> None:
"""Register a configuration value. """Register a configuration value.
This is necessary for Sphinx to recognize new values and set default This is necessary for Sphinx to recognize new values and set default
@ -514,8 +502,7 @@ class Sphinx:
rebuild = 'env' if rebuild else '' rebuild = 'env' if rebuild else ''
self.config.add(name, default, rebuild, types) self.config.add(name, default, rebuild, types)
def add_event(self, name): def add_event(self, name: str) -> None:
# type: (str) -> None
"""Register an event called *name*. """Register an event called *name*.
This is needed to be able to emit it. This is needed to be able to emit it.
@ -523,8 +510,8 @@ class Sphinx:
logger.debug('[app] adding event: %r', name) logger.debug('[app] adding event: %r', name)
self.events.add(name) self.events.add(name)
def set_translator(self, name, translator_class, override=False): def set_translator(self, name: str, translator_class: "Type[nodes.NodeVisitor]",
# type: (str, Type[nodes.NodeVisitor], bool) -> None override: bool = False) -> None:
"""Register or override a Docutils translator class. """Register or override a Docutils translator class.
This is used to register a custom output translator or to replace a This is used to register a custom output translator or to replace a
@ -537,8 +524,7 @@ class Sphinx:
""" """
self.registry.add_translator(name, translator_class, override=override) self.registry.add_translator(name, translator_class, override=override)
def add_node(self, node, override=False, **kwds): def add_node(self, node: "Type[Element]", override: bool = False, **kwds) -> None:
# type: (Type[nodes.Element], bool, Any) -> None
"""Register a Docutils node class. """Register a Docutils node class.
This is necessary for Docutils internals. It may also be used in the This is necessary for Docutils internals. It may also be used in the
@ -576,8 +562,9 @@ class Sphinx:
docutils.register_node(node) docutils.register_node(node)
self.registry.add_translation_handlers(node, **kwds) self.registry.add_translation_handlers(node, **kwds)
def add_enumerable_node(self, node, figtype, title_getter=None, override=False, **kwds): def add_enumerable_node(self, node: "Type[Element]", figtype: str,
# type: (Type[nodes.Element], str, TitleGetter, bool, Any) -> None title_getter: TitleGetter = None, override: bool = False,
**kwds) -> None:
"""Register a Docutils node class as a numfig target. """Register a Docutils node class as a numfig target.
Sphinx numbers the node automatically. And then the users can refer it Sphinx numbers the node automatically. And then the users can refer it
@ -605,15 +592,15 @@ class Sphinx:
self.add_node(node, override=override, **kwds) self.add_node(node, override=override, **kwds)
@property @property
def enumerable_nodes(self): def enumerable_nodes(self) -> Dict["Type[Node]", Tuple[str, TitleGetter]]:
# type: () -> Dict[Type[nodes.Node], Tuple[str, TitleGetter]]
warnings.warn('app.enumerable_nodes() is deprecated. ' warnings.warn('app.enumerable_nodes() is deprecated. '
'Use app.get_domain("std").enumerable_nodes instead.', 'Use app.get_domain("std").enumerable_nodes instead.',
RemovedInSphinx30Warning, stacklevel=2) RemovedInSphinx30Warning, stacklevel=2)
return self.registry.enumerable_nodes return self.registry.enumerable_nodes
def add_directive(self, name, obj, content=None, arguments=None, override=False, **options): # NOQA def add_directive(self, name: str, obj: Any, content: bool = None,
# type: (str, Any, bool, Tuple[int, int, bool], bool, Any) -> None arguments: Tuple[int, int, bool] = None, override: bool = False,
**options) -> None:
"""Register a Docutils directive. """Register a Docutils directive.
*name* must be the prospective directive name. There are two possible *name* must be the prospective directive name. There are two possible
@ -676,8 +663,7 @@ class Sphinx:
else: else:
docutils.register_directive(name, obj) docutils.register_directive(name, obj)
def add_role(self, name, role, override=False): def add_role(self, name: str, role: Any, override: bool = False) -> None:
# type: (str, Any, bool) -> None
"""Register a Docutils role. """Register a Docutils role.
*name* must be the role name that occurs in the source, *role* the role *name* must be the role name that occurs in the source, *role* the role
@ -694,8 +680,7 @@ class Sphinx:
name, type='app', subtype='add_role') name, type='app', subtype='add_role')
docutils.register_role(name, role) docutils.register_role(name, role)
def add_generic_role(self, name, nodeclass, override=False): def add_generic_role(self, name: str, nodeclass: Any, override: bool = False) -> None:
# type: (str, Any, bool) -> None
"""Register a generic Docutils role. """Register a generic Docutils role.
Register a Docutils role that does nothing but wrap its contents in the Register a Docutils role that does nothing but wrap its contents in the
@ -714,8 +699,7 @@ class Sphinx:
role = roles.GenericRole(name, nodeclass) role = roles.GenericRole(name, nodeclass)
docutils.register_role(name, role) docutils.register_role(name, role)
def add_domain(self, domain, override=False): def add_domain(self, domain: "Type[Domain]", override: bool = False) -> None:
# type: (Type[Domain], bool) -> None
"""Register a domain. """Register a domain.
Make the given *domain* (which must be a class; more precisely, a Make the given *domain* (which must be a class; more precisely, a
@ -727,8 +711,7 @@ class Sphinx:
""" """
self.registry.add_domain(domain, override=override) self.registry.add_domain(domain, override=override)
def override_domain(self, domain): def override_domain(self, domain: "Type[Domain]") -> None:
# type: (Type[Domain]) -> None
"""Override a registered domain. """Override a registered domain.
Make the given *domain* class known to Sphinx, assuming that there is Make the given *domain* class known to Sphinx, assuming that there is
@ -744,9 +727,9 @@ class Sphinx:
RemovedInSphinx30Warning, stacklevel=2) RemovedInSphinx30Warning, stacklevel=2)
self.registry.add_domain(domain, override=True) self.registry.add_domain(domain, override=True)
def add_directive_to_domain(self, domain, name, obj, has_content=None, argument_spec=None, def add_directive_to_domain(self, domain: str, name: str, obj: Any,
override=False, **option_spec): has_content: bool = None, argument_spec: Any = None,
# type: (str, str, Any, bool, Any, bool, Any) -> None override: bool = False, **option_spec) -> None:
"""Register a Docutils directive in a domain. """Register a Docutils directive in a domain.
Like :meth:`add_directive`, but the directive is added to the domain Like :meth:`add_directive`, but the directive is added to the domain
@ -760,8 +743,8 @@ class Sphinx:
has_content, argument_spec, override=override, has_content, argument_spec, override=override,
**option_spec) **option_spec)
def add_role_to_domain(self, domain, name, role, override=False): def add_role_to_domain(self, domain: str, name: str, role: Union[RoleFunction, XRefRole],
# type: (str, str, Union[RoleFunction, XRefRole], bool) -> None override: bool = False) -> None:
"""Register a Docutils role in a domain. """Register a Docutils role in a domain.
Like :meth:`add_role`, but the role is added to the domain named Like :meth:`add_role`, but the role is added to the domain named
@ -773,8 +756,8 @@ class Sphinx:
""" """
self.registry.add_role_to_domain(domain, name, role, override=override) self.registry.add_role_to_domain(domain, name, role, override=override)
def add_index_to_domain(self, domain, index, override=False): def add_index_to_domain(self, domain: str, index: "Type[Index]", override: bool = False
# type: (str, Type[Index], bool) -> None ) -> None:
"""Register a custom index for a domain. """Register a custom index for a domain.
Add a custom *index* class to the domain named *domain*. *index* must Add a custom *index* class to the domain named *domain*. *index* must
@ -786,10 +769,10 @@ class Sphinx:
""" """
self.registry.add_index_to_domain(domain, index) self.registry.add_index_to_domain(domain, index)
def add_object_type(self, directivename, rolename, indextemplate='', def add_object_type(self, directivename: str, rolename: str, indextemplate: str = '',
parse_node=None, ref_nodeclass=None, objname='', parse_node: Callable = None, ref_nodeclass: "Type[TextElement]" = None,
doc_field_types=[], override=False): objname: str = '', doc_field_types: List = [], override: bool = False
# type: (str, str, str, Callable, Type[nodes.TextElement], str, List, bool) -> None ) -> None:
"""Register a new object type. """Register a new object type.
This method is a very convenient way to add a new :term:`object` type This method is a very convenient way to add a new :term:`object` type
@ -850,9 +833,9 @@ class Sphinx:
ref_nodeclass, objname, doc_field_types, ref_nodeclass, objname, doc_field_types,
override=override) override=override)
def add_crossref_type(self, directivename, rolename, indextemplate='', def add_crossref_type(self, directivename: str, rolename: str, indextemplate: str = '',
ref_nodeclass=None, objname='', override=False): ref_nodeclass: "Type[TextElement]" = None, objname: str = '',
# type: (str, str, str, Type[nodes.TextElement], str, bool) -> None override: bool = False) -> None:
"""Register a new crossref object type. """Register a new crossref object type.
This method is very similar to :meth:`add_object_type` except that the This method is very similar to :meth:`add_object_type` except that the
@ -886,8 +869,7 @@ class Sphinx:
indextemplate, ref_nodeclass, objname, indextemplate, ref_nodeclass, objname,
override=override) override=override)
def add_transform(self, transform): def add_transform(self, transform: "Type[Transform]") -> None:
# type: (Type[Transform]) -> None
"""Register a Docutils transform to be applied after parsing. """Register a Docutils transform to be applied after parsing.
Add the standard docutils :class:`Transform` subclass *transform* to Add the standard docutils :class:`Transform` subclass *transform* to
@ -920,8 +902,7 @@ class Sphinx:
""" # NOQA """ # NOQA
self.registry.add_transform(transform) self.registry.add_transform(transform)
def add_post_transform(self, transform): def add_post_transform(self, transform: "Type[Transform]") -> None:
# type: (Type[Transform]) -> None
"""Register a Docutils transform to be applied before writing. """Register a Docutils transform to be applied before writing.
Add the standard docutils :class:`Transform` subclass *transform* to Add the standard docutils :class:`Transform` subclass *transform* to
@ -930,16 +911,14 @@ class Sphinx:
""" """
self.registry.add_post_transform(transform) self.registry.add_post_transform(transform)
def add_javascript(self, filename, **kwargs): def add_javascript(self, filename: str, **kwargs: str) -> None:
# type: (str, **str) -> None
"""An alias of :meth:`add_js_file`.""" """An alias of :meth:`add_js_file`."""
warnings.warn('The app.add_javascript() is deprecated. ' warnings.warn('The app.add_javascript() is deprecated. '
'Please use app.add_js_file() instead.', 'Please use app.add_js_file() instead.',
RemovedInSphinx40Warning, stacklevel=2) RemovedInSphinx40Warning, stacklevel=2)
self.add_js_file(filename, **kwargs) self.add_js_file(filename, **kwargs)
def add_js_file(self, filename, **kwargs): def add_js_file(self, filename: str, **kwargs: str) -> None:
# type: (str, **str) -> None
"""Register a JavaScript file to include in the HTML output. """Register a JavaScript file to include in the HTML output.
Add *filename* to the list of JavaScript files that the default HTML Add *filename* to the list of JavaScript files that the default HTML
@ -965,8 +944,7 @@ class Sphinx:
if hasattr(self.builder, 'add_js_file'): if hasattr(self.builder, 'add_js_file'):
self.builder.add_js_file(filename, **kwargs) # type: ignore self.builder.add_js_file(filename, **kwargs) # type: ignore
def add_css_file(self, filename, **kwargs): def add_css_file(self, filename: str, **kwargs: str) -> None:
# type: (str, **str) -> None
"""Register a stylesheet to include in the HTML output. """Register a stylesheet to include in the HTML output.
Add *filename* to the list of CSS files that the default HTML template Add *filename* to the list of CSS files that the default HTML template
@ -1005,8 +983,8 @@ class Sphinx:
if hasattr(self.builder, 'add_css_file'): if hasattr(self.builder, 'add_css_file'):
self.builder.add_css_file(filename, **kwargs) # type: ignore self.builder.add_css_file(filename, **kwargs) # type: ignore
def add_stylesheet(self, filename, alternate=False, title=None): def add_stylesheet(self, filename: str, alternate: bool = False, title: str = None
# type: (str, bool, str) -> None ) -> None:
"""An alias of :meth:`add_css_file`.""" """An alias of :meth:`add_css_file`."""
warnings.warn('The app.add_stylesheet() is deprecated. ' warnings.warn('The app.add_stylesheet() is deprecated. '
'Please use app.add_css_file() instead.', 'Please use app.add_css_file() instead.',
@ -1023,8 +1001,7 @@ class Sphinx:
self.add_css_file(filename, **attributes) self.add_css_file(filename, **attributes)
def add_latex_package(self, packagename, options=None): def add_latex_package(self, packagename: str, options: str = None) -> None:
# type: (str, str) -> None
r"""Register a package to include in the LaTeX source code. r"""Register a package to include in the LaTeX source code.
Add *packagename* to the list of packages that LaTeX source code will Add *packagename* to the list of packages that LaTeX source code will
@ -1042,8 +1019,7 @@ class Sphinx:
""" """
self.registry.add_latex_package(packagename, options) self.registry.add_latex_package(packagename, options)
def add_lexer(self, alias, lexer): def add_lexer(self, alias: str, lexer: Union[Lexer, "Type[Lexer]"]) -> None:
# type: (str, Union[Lexer, Type[Lexer]]) -> None
"""Register a new lexer for source code. """Register a new lexer for source code.
Use *lexer* to highlight code blocks with the given language *alias*. Use *lexer* to highlight code blocks with the given language *alias*.
@ -1062,8 +1038,7 @@ class Sphinx:
else: else:
lexer_classes[alias] = lexer lexer_classes[alias] = lexer
def add_autodocumenter(self, cls, override=False): def add_autodocumenter(self, cls: Any, override: bool = False) -> None:
# type: (Any, bool) -> None
"""Register a new documenter class for the autodoc extension. """Register a new documenter class for the autodoc extension.
Add *cls* as a new documenter class for the :mod:`sphinx.ext.autodoc` Add *cls* as a new documenter class for the :mod:`sphinx.ext.autodoc`
@ -1083,8 +1058,8 @@ class Sphinx:
self.registry.add_documenter(cls.objtype, cls) self.registry.add_documenter(cls.objtype, cls)
self.add_directive('auto' + cls.objtype, AutodocDirective, override=override) self.add_directive('auto' + cls.objtype, AutodocDirective, override=override)
def add_autodoc_attrgetter(self, typ, getter): def add_autodoc_attrgetter(self, typ: "Type", getter: Callable[[Any, str, Any], Any]
# type: (Type, Callable[[Any, str, Any], Any]) -> None ) -> None:
"""Register a new ``getattr``-like function for the autodoc extension. """Register a new ``getattr``-like function for the autodoc extension.
Add *getter*, which must be a function with an interface compatible to Add *getter*, which must be a function with an interface compatible to
@ -1098,8 +1073,7 @@ class Sphinx:
logger.debug('[app] adding autodoc attrgetter: %r', (typ, getter)) logger.debug('[app] adding autodoc attrgetter: %r', (typ, getter))
self.registry.add_autodoc_attrgetter(typ, getter) self.registry.add_autodoc_attrgetter(typ, getter)
def add_search_language(self, cls): def add_search_language(self, cls: Any) -> None:
# type: (Any) -> None
"""Register a new language for the HTML search index. """Register a new language for the HTML search index.
Add *cls*, which must be a subclass of Add *cls*, which must be a subclass of
@ -1115,8 +1089,7 @@ class Sphinx:
assert issubclass(cls, SearchLanguage) assert issubclass(cls, SearchLanguage)
languages[cls.lang] = cls languages[cls.lang] = cls
def add_source_suffix(self, suffix, filetype, override=False): def add_source_suffix(self, suffix: str, filetype: str, override: bool = False) -> None:
# type: (str, str, bool) -> None
"""Register a suffix of source files. """Register a suffix of source files.
Same as :confval:`source_suffix`. The users can override this Same as :confval:`source_suffix`. The users can override this
@ -1126,8 +1099,7 @@ class Sphinx:
""" """
self.registry.add_source_suffix(suffix, filetype, override=override) self.registry.add_source_suffix(suffix, filetype, override=override)
def add_source_parser(self, *args, **kwargs): def add_source_parser(self, *args, **kwargs) -> None:
# type: (Any, Any) -> None
"""Register a parser class. """Register a parser class.
.. versionadded:: 1.4 .. versionadded:: 1.4
@ -1139,8 +1111,7 @@ class Sphinx:
""" """
self.registry.add_source_parser(*args, **kwargs) self.registry.add_source_parser(*args, **kwargs)
def add_env_collector(self, collector): def add_env_collector(self, collector: "Type[EnvironmentCollector]") -> None:
# type: (Type[EnvironmentCollector]) -> None
"""Register an environment collector class. """Register an environment collector class.
Refer to :ref:`collector-api`. Refer to :ref:`collector-api`.
@ -1150,8 +1121,7 @@ class Sphinx:
logger.debug('[app] adding environment collector: %r', collector) logger.debug('[app] adding environment collector: %r', collector)
collector().enable(self) collector().enable(self)
def add_html_theme(self, name, theme_path): def add_html_theme(self, name: str, theme_path: str) -> None:
# type: (str, str) -> None
"""Register a HTML Theme. """Register a HTML Theme.
The *name* is a name of theme, and *path* is a full path to the theme The *name* is a name of theme, and *path* is a full path to the theme
@ -1162,8 +1132,9 @@ class Sphinx:
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path) logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path self.html_themes[name] = theme_path
def add_html_math_renderer(self, name, inline_renderers=None, block_renderers=None): def add_html_math_renderer(self, name: str,
# type: (str, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None inline_renderers: Tuple[Callable, Callable] = None,
block_renderers: Tuple[Callable, Callable] = None) -> None:
"""Register a math renderer for HTML. """Register a math renderer for HTML.
The *name* is a name of math renderer. Both *inline_renderers* and The *name* is a name of math renderer. Both *inline_renderers* and
@ -1177,8 +1148,7 @@ class Sphinx:
""" """
self.registry.add_html_math_renderer(name, inline_renderers, block_renderers) self.registry.add_html_math_renderer(name, inline_renderers, block_renderers)
def add_message_catalog(self, catalog, locale_dir): def add_message_catalog(self, catalog: str, locale_dir: str) -> None:
# type: (str, str) -> None
"""Register a message catalog. """Register a message catalog.
The *catalog* is a name of catalog, and *locale_dir* is a base path The *catalog* is a name of catalog, and *locale_dir* is a base path
@ -1191,8 +1161,7 @@ class Sphinx:
locale.init_console(locale_dir, catalog) locale.init_console(locale_dir, catalog)
# ---- other methods ------------------------------------------------- # ---- other methods -------------------------------------------------
def is_parallel_allowed(self, typ): def is_parallel_allowed(self, typ: str) -> bool:
# type: (str) -> bool
"""Check parallel processing is allowed or not. """Check parallel processing is allowed or not.
``typ`` is a type of processing; ``'read'`` or ``'write'``. ``typ`` is a type of processing; ``'read'`` or ``'write'``.
@ -1228,8 +1197,7 @@ class Sphinx:
return True return True
@property @property
def _setting_up_extension(self): def _setting_up_extension(self) -> List[str]:
# type: () -> List[str]
warnings.warn('app._setting_up_extension is deprecated.', warnings.warn('app._setting_up_extension is deprecated.',
RemovedInSphinx30Warning) RemovedInSphinx30Warning)
return ['?'] return ['?']
@ -1241,8 +1209,7 @@ class TemplateBridge:
that renders templates given a template name and a context. that renders templates given a template name and a context.
""" """
def init(self, builder, theme=None, dirs=None): def init(self, builder: "Builder", theme: Theme = None, dirs: List[str] = None) -> None:
# type: (Builder, Theme, List[str]) -> None
"""Called by the builder to initialize the template system. """Called by the builder to initialize the template system.
*builder* is the builder object; you'll probably want to look at the *builder* is the builder object; you'll probably want to look at the
@ -1253,23 +1220,20 @@ class TemplateBridge:
""" """
raise NotImplementedError('must be implemented in subclasses') raise NotImplementedError('must be implemented in subclasses')
def newest_template_mtime(self): def newest_template_mtime(self) -> float:
# type: () -> float
"""Called by the builder to determine if output files are outdated """Called by the builder to determine if output files are outdated
because of template changes. Return the mtime of the newest template because of template changes. Return the mtime of the newest template
file that was changed. The default implementation returns ``0``. file that was changed. The default implementation returns ``0``.
""" """
return 0 return 0
def render(self, template, context): def render(self, template: str, context: Dict) -> None:
# type: (str, Dict) -> None
"""Called by the builder to render a template given as a filename with """Called by the builder to render a template given as a filename with
a specified context (a Python dictionary). a specified context (a Python dictionary).
""" """
raise NotImplementedError('must be implemented in subclasses') raise NotImplementedError('must be implemented in subclasses')
def render_string(self, template, context): def render_string(self, template: str, context: Dict) -> str:
# type: (str, Dict) -> str
"""Called by the builder to render a template given as a string with a """Called by the builder to render a template given as a string with a
specified context (a Python dictionary). specified context (a Python dictionary).
""" """

View File

@ -12,9 +12,12 @@ from typing import Dict, List, Set
from docutils import nodes from docutils import nodes
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
if False:
# For type annotation
from sphinx.application import Sphinx
class EnvironmentCollector: class EnvironmentCollector:
"""An EnvironmentCollector is a specific data collector from each document. """An EnvironmentCollector is a specific data collector from each document.
@ -27,7 +30,7 @@ class EnvironmentCollector:
listener_ids = None # type: Dict[str, int] listener_ids = None # type: Dict[str, int]
def enable(self, app: Sphinx) -> None: def enable(self, app: "Sphinx") -> None:
assert self.listener_ids is None assert self.listener_ids is None
self.listener_ids = { self.listener_ids = {
'doctree-read': app.connect('doctree-read', self.process_doc), 'doctree-read': app.connect('doctree-read', self.process_doc),
@ -37,38 +40,38 @@ class EnvironmentCollector:
'env-get-outdated': app.connect('env-get-outdated', self.get_outdated_docs), 'env-get-outdated': app.connect('env-get-outdated', self.get_outdated_docs),
} }
def disable(self, app: Sphinx) -> None: def disable(self, app: "Sphinx") -> None:
assert self.listener_ids is not None assert self.listener_ids is not None
for listener_id in self.listener_ids.values(): for listener_id in self.listener_ids.values():
app.disconnect(listener_id) app.disconnect(listener_id)
self.listener_ids = None self.listener_ids = None
def clear_doc(self, app: Sphinx, env: BuildEnvironment, docname: str) -> None: def clear_doc(self, app: "Sphinx", env: BuildEnvironment, docname: str) -> None:
"""Remove specified data of a document. """Remove specified data of a document.
This method is called on the removal of the document.""" This method is called on the removal of the document."""
raise NotImplementedError raise NotImplementedError
def merge_other(self, app: Sphinx, env: BuildEnvironment, def merge_other(self, app: "Sphinx", env: BuildEnvironment,
docnames: Set[str], other: BuildEnvironment) -> None: docnames: Set[str], other: BuildEnvironment) -> None:
"""Merge in specified data regarding docnames from a different `BuildEnvironment` """Merge in specified data regarding docnames from a different `BuildEnvironment`
object which coming from a subprocess in parallel builds.""" object which coming from a subprocess in parallel builds."""
raise NotImplementedError raise NotImplementedError
def process_doc(self, app: Sphinx, doctree: nodes.document) -> None: def process_doc(self, app: "Sphinx", doctree: nodes.document) -> None:
"""Process a document and gather specific data from it. """Process a document and gather specific data from it.
This method is called after the document is read.""" This method is called after the document is read."""
raise NotImplementedError raise NotImplementedError
def get_updated_docs(self, app: Sphinx, env: BuildEnvironment) -> List[str]: def get_updated_docs(self, app: "Sphinx", env: BuildEnvironment) -> List[str]:
"""Return a list of docnames to re-read. """Return a list of docnames to re-read.
This methods is called after reading the whole of documents (experimental). This methods is called after reading the whole of documents (experimental).
""" """
return [] return []
def get_outdated_docs(self, app: Sphinx, env: BuildEnvironment, def get_outdated_docs(self, app: "Sphinx", env: BuildEnvironment,
added: Set[str], changed: Set[str], removed: Set[str]) -> List[str]: added: Set[str], changed: Set[str], removed: Set[str]) -> List[str]:
"""Return a list of docnames to re-read. """Return a list of docnames to re-read.