Migrate to py3 style type annotation: sphinx.registry

This commit is contained in:
Takeshi KOMIYA 2019-12-25 02:13:16 +09:00
parent 29878876b2
commit 6bde6b2bae

View File

@ -13,38 +13,38 @@ import warnings
from importlib import import_module
from inspect import isclass
from types import MethodType
from typing import Any, Callable, Dict, Iterator, List, Tuple, Union
from docutils import nodes
from docutils.io import Input
from docutils.nodes import Element, Node, TextElement
from docutils.parsers import Parser
from docutils.parsers.rst import Directive
from docutils.transforms import Transform
from pkg_resources import iter_entry_points
from sphinx.builders import Builder
from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.domains import ObjType
from sphinx.domains import Domain, Index, ObjType
from sphinx.domains.std import GenericObject, Target
from sphinx.environment import BuildEnvironment
from sphinx.errors import ExtensionError, SphinxError, VersionRequirementError
from sphinx.extension import Extension
from sphinx.io import SphinxFileInput
from sphinx.locale import __
from sphinx.parsers import Parser as SphinxParser
from sphinx.roles import XRefRole
from sphinx.util import logging
from sphinx.util.docutils import directive_helper
from sphinx.util.logging import prefixed_warnings
from sphinx.util.typing import RoleFunction, TitleGetter
if False:
# For type annotation
from typing import Any, Callable, Dict, Iterator, List, Tuple, Union # NOQA
from typing import Type # for python3.5.1
from docutils import nodes # NOQA
from docutils.io import Input # NOQA
from docutils.parsers import Parser # NOQA
from docutils.transforms import Transform # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.config import Config # NOQA
from sphinx.domains import Domain, Index # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.ext.autodoc import Documenter # NOQA
from sphinx.io import SphinxFileInput # NOQA
from sphinx.util.typing import RoleFunction, TitleGetter # NOQA
from sphinx.application import Sphinx
from sphinx.ext.autodoc import Documenter
logger = logging.getLogger(__name__)
@ -56,8 +56,7 @@ EXTENSION_BLACKLIST = {
class SphinxComponentRegistry:
def __init__(self):
# type: () -> None
def __init__(self) -> None:
#: special attrgetter for autodoc; class object -> attrgetter
self.autodoc_attrgettrs = {} # type: Dict[Type, Callable[[Any, str, Any], Any]]
@ -91,7 +90,7 @@ class SphinxComponentRegistry:
#: additional enumerable nodes
#: a dict of node class -> tuple of figtype and title_getter function
self.enumerable_nodes = {} # type: Dict[Type[nodes.Node], Tuple[str, TitleGetter]]
self.enumerable_nodes = {} # type: Dict[Type[Node], Tuple[str, TitleGetter]]
#: HTML inline and block math renderers
#: a dict of name -> tuple of visit function and depart function
@ -126,8 +125,7 @@ class SphinxComponentRegistry:
#: additional transforms; list of transforms
self.transforms = [] # type: List[Type[Transform]]
def add_builder(self, builder, override=False):
# type: (Type[Builder], bool) -> None
def add_builder(self, builder: "Type[Builder]", override: bool = False) -> None:
logger.debug('[app] adding builder: %r', builder)
if not hasattr(builder, 'name'):
raise ExtensionError(__('Builder class %s has no "name" attribute') % builder)
@ -136,8 +134,7 @@ class SphinxComponentRegistry:
(builder.name, self.builders[builder.name].__module__))
self.builders[builder.name] = builder
def preload_builder(self, app, name):
# type: (Sphinx, str) -> None
def preload_builder(self, app: "Sphinx", name: str) -> None:
if name is None:
return
@ -151,26 +148,22 @@ class SphinxComponentRegistry:
self.load_extension(app, entry_point.module_name)
def create_builder(self, app, name):
# type: (Sphinx, str) -> Builder
def create_builder(self, app: "Sphinx", name: str) -> Builder:
if name not in self.builders:
raise SphinxError(__('Builder name %s not registered') % name)
return self.builders[name](app)
def add_domain(self, domain, override=False):
# type: (Type[Domain], bool) -> None
def add_domain(self, domain: "Type[Domain]", override: bool = False) -> None:
logger.debug('[app] adding domain: %r', domain)
if domain.name in self.domains and not override:
raise ExtensionError(__('domain %s already registered') % domain.name)
self.domains[domain.name] = domain
def has_domain(self, domain):
# type: (str) -> bool
def has_domain(self, domain: str) -> bool:
return domain in self.domains
def create_domains(self, env):
# type: (BuildEnvironment) -> Iterator[Domain]
def create_domains(self, env: BuildEnvironment) -> Iterator[Domain]:
for DomainClass in self.domains.values():
domain = DomainClass(env)
@ -183,16 +176,15 @@ class SphinxComponentRegistry:
yield domain
def override_domain(self, domain):
# type: (Type[Domain]) -> None
def override_domain(self, domain: "Type[Domain]") -> None:
warnings.warn('registry.override_domain() is deprecated. '
'Use app.add_domain(domain, override=True) instead.',
RemovedInSphinx30Warning, stacklevel=2)
self.add_domain(domain, override=True)
def add_directive_to_domain(self, domain, name, obj, has_content=None, argument_spec=None,
override=False, **option_spec):
# type: (str, str, Any, bool, Any, bool, Any) -> None
def add_directive_to_domain(self, domain: str, name: str, obj: Any,
has_content: bool = None, argument_spec: Any = None,
override: bool = False, **option_spec) -> None:
logger.debug('[app] adding directive to domain: %r',
(domain, name, obj, has_content, argument_spec, option_spec))
if domain not in self.domains:
@ -207,8 +199,9 @@ class SphinxComponentRegistry:
else:
directives[name] = obj
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:
logger.debug('[app] adding role to domain: %r', (domain, name, role))
if domain not in self.domains:
raise ExtensionError(__('domain %s not yet registered') % domain)
@ -218,8 +211,8 @@ class SphinxComponentRegistry:
(name, domain))
roles[name] = role
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:
logger.debug('[app] adding index to domain: %r', (domain, index))
if domain not in self.domains:
raise ExtensionError(__('domain %s not yet registered') % domain)
@ -229,10 +222,10 @@ class SphinxComponentRegistry:
(index.name, domain))
indices.append(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:
logger.debug('[app] adding object type: %r',
(directivename, rolename, indextemplate, parse_node,
ref_nodeclass, objname, doc_field_types))
@ -253,9 +246,9 @@ class SphinxComponentRegistry:
directivename)
object_types[directivename] = ObjType(objname or directivename, rolename)
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:
logger.debug('[app] adding crossref type: %r',
(directivename, rolename, indextemplate, ref_nodeclass, objname))
@ -273,16 +266,14 @@ class SphinxComponentRegistry:
directivename)
object_types[directivename] = ObjType(objname or directivename, rolename)
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:
logger.debug('[app] adding source_suffix: %r, %r', suffix, filetype)
if suffix in self.source_suffix and not override:
raise ExtensionError(__('source_suffix %r is already registered') % suffix)
else:
self.source_suffix[suffix] = filetype
def add_source_parser(self, *args, **kwargs):
# type: (Any, bool) -> None
def add_source_parser(self, *args, **kwargs) -> None:
logger.debug('[app] adding search source_parser: %r', args)
if len(args) == 1:
# new sytle arguments: (source_parser)
@ -318,27 +309,24 @@ class SphinxComponentRegistry:
if suffix:
self.source_parsers[suffix] = parser
def get_source_parser(self, filetype):
# type: (str) -> Type[Parser]
def get_source_parser(self, filetype: str) -> "Type[Parser]":
try:
return self.source_parsers[filetype]
except KeyError:
raise SphinxError(__('Source parser for %s not registered') % filetype)
def get_source_parsers(self):
# type: () -> Dict[str, Type[Parser]]
def get_source_parsers(self) -> Dict[str, "Type[Parser]"]:
return self.source_parsers
def create_source_parser(self, app, filename):
# type: (Sphinx, str) -> Parser
def create_source_parser(self, app: "Sphinx", filename: str) -> Parser:
parser_class = self.get_source_parser(filename)
parser = parser_class()
if isinstance(parser, SphinxParser):
parser.set_application(app)
return parser
def add_source_input(self, input_class, override=False):
# type: (Type[SphinxFileInput], bool) -> None
def add_source_input(self, input_class: "Type[SphinxFileInput]", override: bool = False
) -> None:
warnings.warn('registry.source_input() is deprecated.',
RemovedInSphinx30Warning, stacklevel=2)
for filetype in input_class.supported:
@ -347,8 +335,7 @@ class SphinxComponentRegistry:
filetype)
self.source_inputs[filetype] = input_class
def get_source_input(self, filetype):
# type: (str) -> Type[Input]
def get_source_input(self, filetype: str) -> "Type[Input]":
try:
return self.source_inputs[filetype]
except KeyError:
@ -358,15 +345,14 @@ class SphinxComponentRegistry:
except KeyError:
return None
def add_translator(self, name, translator, override=False):
# type: (str, Type[nodes.NodeVisitor], bool) -> None
def add_translator(self, name: str, translator: "Type[nodes.NodeVisitor]",
override: bool = False) -> None:
logger.debug('[app] Change of translator for the %s builder.' % name)
if name in self.translators and not override:
raise ExtensionError(__('Translator for %r already exists') % name)
self.translators[name] = translator
def add_translation_handlers(self, node, **kwargs):
# type: (Type[nodes.Element], Any) -> None
def add_translation_handlers(self, node: "Type[Element]", **kwargs) -> None:
logger.debug('[app] adding translation_handlers: %r, %r', node, kwargs)
for builder_name, handlers in kwargs.items():
translation_handlers = self.translation_handlers.setdefault(builder_name, {})
@ -377,13 +363,11 @@ class SphinxComponentRegistry:
raise ExtensionError(__('kwargs for add_node() must be a (visit, depart) '
'function tuple: %r=%r') % builder_name, handlers)
def get_translator_class(self, builder):
# type: (Builder) -> Type[nodes.NodeVisitor]
def get_translator_class(self, builder: Builder) -> "Type[nodes.NodeVisitor]":
return self.translators.get(builder.name,
builder.default_translator_class)
def create_translator(self, builder, *args):
# type: (Builder, Any) -> nodes.NodeVisitor
def create_translator(self, builder: Builder, *args) -> nodes.NodeVisitor:
translator_class = self.get_translator_class(builder)
assert translator_class, "translator not found for %s" % builder.name
translator = translator_class(*args)
@ -401,54 +385,48 @@ class SphinxComponentRegistry:
return translator
def add_transform(self, transform):
# type: (Type[Transform]) -> None
def add_transform(self, transform: "Type[Transform]") -> None:
logger.debug('[app] adding transform: %r', transform)
self.transforms.append(transform)
def get_transforms(self):
# type: () -> List[Type[Transform]]
def get_transforms(self) -> List["Type[Transform]"]:
return self.transforms
def add_post_transform(self, transform):
# type: (Type[Transform]) -> None
def add_post_transform(self, transform: "Type[Transform]") -> None:
logger.debug('[app] adding post transform: %r', transform)
self.post_transforms.append(transform)
def get_post_transforms(self):
# type: () -> List[Type[Transform]]
def get_post_transforms(self) -> List["Type[Transform]"]:
return self.post_transforms
def add_documenter(self, objtype, documenter):
# type: (str, Type[Documenter]) -> None
def add_documenter(self, objtype: str, documenter: "Type[Documenter]") -> None:
self.documenters[objtype] = documenter
def add_autodoc_attrgetter(self, typ, attrgetter):
# type: (Type, Callable[[Any, str, Any], Any]) -> None
def add_autodoc_attrgetter(self, typ: "Type",
attrgetter: Callable[[Any, str, Any], Any]) -> None:
self.autodoc_attrgettrs[typ] = attrgetter
def add_css_files(self, filename, **attributes):
self.css_files.append((filename, attributes))
def add_js_file(self, filename, **attributes):
# type: (str, **str) -> None
def add_js_file(self, filename: str, **attributes: str) -> None:
logger.debug('[app] adding js_file: %r, %r', filename, attributes)
self.js_files.append((filename, attributes))
def add_latex_package(self, name, options):
# type: (str, str) -> None
def add_latex_package(self, name: str, options: str) -> None:
logger.debug('[app] adding latex package: %r', name)
self.latex_packages.append((name, options))
def add_enumerable_node(self, node, figtype, title_getter=None, override=False):
# type: (Type[nodes.Node], str, TitleGetter, bool) -> None
def add_enumerable_node(self, node: "Type[Node]", figtype: str,
title_getter: TitleGetter = None, override: bool = False) -> None:
logger.debug('[app] adding enumerable node: (%r, %r, %r)', node, figtype, title_getter)
if node in self.enumerable_nodes and not override:
raise ExtensionError(__('enumerable_node %r already registered') % node)
self.enumerable_nodes[node] = (figtype, title_getter)
def add_html_math_renderer(self, name, inline_renderers, block_renderers):
# type: (str, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
def add_html_math_renderer(self, name: str,
inline_renderers: Tuple[Callable, Callable],
block_renderers: Tuple[Callable, Callable]) -> None:
logger.debug('[app] adding html_math_renderer: %s, %r, %r',
name, inline_renderers, block_renderers)
if name in self.html_inline_math_renderers:
@ -457,8 +435,7 @@ class SphinxComponentRegistry:
self.html_inline_math_renderers[name] = inline_renderers
self.html_block_math_renderers[name] = block_renderers
def load_extension(self, app, extname):
# type: (Sphinx, str) -> None
def load_extension(self, app: "Sphinx", extname: str) -> None:
"""Load a Sphinx extension."""
if extname in app.extensions: # alread loaded
return
@ -503,8 +480,7 @@ class SphinxComponentRegistry:
app.extensions[extname] = Extension(extname, mod, **metadata)
def get_envversion(self, app):
# type: (Sphinx) -> Dict[str, str]
def get_envversion(self, app: "Sphinx") -> Dict[str, str]:
from sphinx.environment import ENV_VERSION
envversion = {ext.name: ext.metadata['env_version'] for ext in app.extensions.values()
if ext.metadata.get('env_version')}
@ -512,8 +488,7 @@ class SphinxComponentRegistry:
return envversion
def merge_source_suffix(app, config):
# type: (Sphinx, Config) -> None
def merge_source_suffix(app: "Sphinx", config: Config) -> None:
"""Merge source_suffix which specified by user and added by extensions."""
for suffix, filetype in app.registry.source_suffix.items():
if suffix not in app.config.source_suffix:
@ -527,8 +502,7 @@ def merge_source_suffix(app, config):
app.registry.source_suffix = app.config.source_suffix
def setup(app):
# type: (Sphinx) -> Dict[str, Any]
def setup(app: "Sphinx") -> Dict[str, Any]:
app.connect('config-inited', merge_source_suffix)
return {