mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-25 14:40:22 -05:00
Merge pull request #6534 from tk0miya/refactor_type_annotation_ext
Migrate to py3 style type annotation: sphinx.ext (Part 1)
This commit is contained in:
14 files changed
+308
-506
No files matched your search
+20
-33
@@ -22,6 +22,7 @@ import sys
|
||||
import warnings
|
||||
from fnmatch import fnmatch
|
||||
from os import path
|
||||
from typing import Any, List, Tuple
|
||||
|
||||
import sphinx.locale
|
||||
from sphinx import __display_version__, package_dir
|
||||
@@ -32,10 +33,6 @@ from sphinx.util import rst
|
||||
from sphinx.util.osutil import FileAvoidWrite, ensuredir
|
||||
from sphinx.util.template import ReSTRenderer
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, List, Tuple # NOQA
|
||||
|
||||
# automodule options
|
||||
if 'SPHINX_APIDOC_OPTIONS' in os.environ:
|
||||
OPTIONS = os.environ['SPHINX_APIDOC_OPTIONS'].split(',')
|
||||
@@ -53,8 +50,7 @@ PY_SUFFIXES = {'.py', '.pyx'}
|
||||
template_dir = path.join(package_dir, 'templates', 'apidoc')
|
||||
|
||||
|
||||
def makename(package, module):
|
||||
# type: (str, str) -> str
|
||||
def makename(package: str, module: str) -> str:
|
||||
"""Join package and module with a dot."""
|
||||
warnings.warn('makename() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
@@ -68,14 +64,12 @@ def makename(package, module):
|
||||
return name
|
||||
|
||||
|
||||
def module_join(*modnames):
|
||||
# type: (*str) -> str
|
||||
def module_join(*modnames: str) -> str:
|
||||
"""Join module names with dots."""
|
||||
return '.'.join(filter(None, modnames))
|
||||
|
||||
|
||||
def write_file(name, text, opts):
|
||||
# type: (str, str, Any) -> None
|
||||
def write_file(name: str, text: str, opts: Any) -> None:
|
||||
"""Write the output file for module/package <name>."""
|
||||
fname = path.join(opts.destdir, '%s.%s' % (name, opts.suffix))
|
||||
if opts.dryrun:
|
||||
@@ -89,8 +83,7 @@ def write_file(name, text, opts):
|
||||
f.write(text)
|
||||
|
||||
|
||||
def format_heading(level, text, escape=True):
|
||||
# type: (int, str, bool) -> str
|
||||
def format_heading(level: int, text: str, escape: bool = True) -> str:
|
||||
"""Create a heading of <level> [1, 2 or 3 supported]."""
|
||||
warnings.warn('format_warning() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
@@ -100,8 +93,7 @@ def format_heading(level, text, escape=True):
|
||||
return '%s\n%s\n\n' % (text, underlining)
|
||||
|
||||
|
||||
def format_directive(module, package=None):
|
||||
# type: (str, str) -> str
|
||||
def format_directive(module: str, package: str = None) -> str:
|
||||
"""Create the automodule directive and add the options."""
|
||||
warnings.warn('format_directive() is deprecated.',
|
||||
RemovedInSphinx40Warning)
|
||||
@@ -111,8 +103,8 @@ def format_directive(module, package=None):
|
||||
return directive
|
||||
|
||||
|
||||
def create_module_file(package, basename, opts, user_template_dir=None):
|
||||
# type: (str, str, Any, str) -> None
|
||||
def create_module_file(package: str, basename: str, opts: Any,
|
||||
user_template_dir: str = None) -> None:
|
||||
"""Build the text of the file and write the file."""
|
||||
qualname = module_join(package, basename)
|
||||
context = {
|
||||
@@ -125,9 +117,9 @@ def create_module_file(package, basename, opts, user_template_dir=None):
|
||||
write_file(qualname, text, opts)
|
||||
|
||||
|
||||
def create_package_file(root, master_package, subroot, py_files, opts, subs,
|
||||
is_namespace, excludes=[], user_template_dir=None):
|
||||
# type: (str, str, str, List[str], Any, List[str], bool, List[str], str) -> None
|
||||
def create_package_file(root: str, master_package: str, subroot: str, py_files: List[str],
|
||||
opts: Any, subs: List[str], is_namespace: bool,
|
||||
excludes: List[str] = [], user_template_dir: str = None) -> None:
|
||||
"""Build the text of the file and write the file."""
|
||||
# build a list of sub packages (directories containing an INITPY file)
|
||||
subpackages = [sub for sub in subs if not
|
||||
@@ -160,8 +152,8 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs,
|
||||
create_module_file(None, submodule, opts, user_template_dir)
|
||||
|
||||
|
||||
def create_modules_toc_file(modules, opts, name='modules', user_template_dir=None):
|
||||
# type: (List[str], Any, str, str) -> None
|
||||
def create_modules_toc_file(modules: List[str], opts: Any, name: str = 'modules',
|
||||
user_template_dir: str = None) -> None:
|
||||
"""Create the module's index."""
|
||||
modules.sort()
|
||||
prev_module = ''
|
||||
@@ -181,8 +173,7 @@ def create_modules_toc_file(modules, opts, name='modules', user_template_dir=Non
|
||||
write_file(name, text, opts)
|
||||
|
||||
|
||||
def shall_skip(module, opts, excludes=[]):
|
||||
# type: (str, Any, List[str]) -> bool
|
||||
def shall_skip(module: str, opts: Any, excludes: List[str] = []) -> bool:
|
||||
"""Check if we want to skip this module."""
|
||||
# skip if the file doesn't exist and not using implicit namespaces
|
||||
if not opts.implicit_namespaces and not path.exists(module):
|
||||
@@ -208,8 +199,7 @@ def shall_skip(module, opts, excludes=[]):
|
||||
return False
|
||||
|
||||
|
||||
def is_skipped_module(filename, opts, excludes):
|
||||
# type: (str, Any, List[str]) -> bool
|
||||
def is_skipped_module(filename: str, opts: Any, excludes: List[str]) -> bool:
|
||||
"""Check if we want to skip this module."""
|
||||
if not path.exists(filename):
|
||||
# skip if the file doesn't exist
|
||||
@@ -221,8 +211,8 @@ def is_skipped_module(filename, opts, excludes):
|
||||
return False
|
||||
|
||||
|
||||
def recurse_tree(rootpath, excludes, opts, user_template_dir=None):
|
||||
# type: (str, List[str], Any, str) -> List[str]
|
||||
def recurse_tree(rootpath: str, excludes: List[str], opts: Any,
|
||||
user_template_dir: str = None) -> List[str]:
|
||||
"""
|
||||
Look for every file in the directory tree and create the corresponding
|
||||
ReST files.
|
||||
@@ -287,8 +277,7 @@ def recurse_tree(rootpath, excludes, opts, user_template_dir=None):
|
||||
return toplevels
|
||||
|
||||
|
||||
def is_excluded(root, excludes):
|
||||
# type: (str, List[str]) -> bool
|
||||
def is_excluded(root: str, excludes: List[str]) -> bool:
|
||||
"""Check if the directory is in the exclude list.
|
||||
|
||||
Note: by having trailing slashes, we avoid common prefix issues, like
|
||||
@@ -300,8 +289,7 @@ def is_excluded(root, excludes):
|
||||
return False
|
||||
|
||||
|
||||
def get_parser():
|
||||
# type: () -> argparse.ArgumentParser
|
||||
def get_parser() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(
|
||||
usage='%(prog)s [OPTIONS] -o <OUTPUT_PATH> <MODULE_PATH> '
|
||||
'[EXCLUDE_PATTERN, ...]',
|
||||
@@ -396,8 +384,7 @@ Note: By default this script will not overwrite already created files."""))
|
||||
return parser
|
||||
|
||||
|
||||
def main(argv=sys.argv[1:]):
|
||||
# type: (List[str]) -> int
|
||||
def main(argv: List[str] = sys.argv[1:]) -> int:
|
||||
"""Parse and check the command line arguments."""
|
||||
sphinx.locale.setlocale(locale.LC_ALL, '')
|
||||
sphinx.locale.init_console(os.path.join(package_dir, 'locale'), 'sphinx')
|
||||
|
||||
+119
-192
@@ -12,15 +12,18 @@
|
||||
|
||||
import re
|
||||
import warnings
|
||||
from typing import Any
|
||||
from types import ModuleType
|
||||
from typing import Any, Callable, Dict, Iterator, List, Sequence, Set, Tuple, Type, Union
|
||||
|
||||
from docutils.statemachine import StringList
|
||||
|
||||
import sphinx
|
||||
from sphinx.config import ENUM
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.config import Config, ENUM
|
||||
from sphinx.deprecation import (
|
||||
RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias
|
||||
)
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.ext.autodoc.importer import import_object, get_object_members
|
||||
from sphinx.ext.autodoc.mock import mock
|
||||
from sphinx.locale import _, __
|
||||
@@ -35,12 +38,8 @@ from sphinx.util.inspect import (
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from types import ModuleType # NOQA
|
||||
from typing import Callable, Dict, Iterator, List, Sequence, Set, Tuple, Type, Union # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.config import Config # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.ext.autodoc.directive import DocumenterBridge # NOQA
|
||||
from sphinx.ext.autodoc.directive import DocumenterBridge
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -61,8 +60,7 @@ py_ext_sig_re = re.compile(
|
||||
''', re.VERBOSE)
|
||||
|
||||
|
||||
def identity(x):
|
||||
# type: (Any) -> Any
|
||||
def identity(x: Any) -> Any:
|
||||
return x
|
||||
|
||||
|
||||
@@ -71,16 +69,14 @@ INSTANCEATTR = object()
|
||||
SLOTSATTR = object()
|
||||
|
||||
|
||||
def members_option(arg):
|
||||
# type: (Any) -> Union[object, List[str]]
|
||||
def members_option(arg: Any) -> Union[object, List[str]]:
|
||||
"""Used to convert the :members: option to auto directives."""
|
||||
if arg is None or arg is True:
|
||||
return ALL
|
||||
return [x.strip() for x in arg.split(',')]
|
||||
|
||||
|
||||
def members_set_option(arg):
|
||||
# type: (Any) -> Union[object, Set[str]]
|
||||
def members_set_option(arg: Any) -> Union[object, Set[str]]:
|
||||
"""Used to convert the :members: option to auto directives."""
|
||||
if arg is None:
|
||||
return ALL
|
||||
@@ -90,8 +86,7 @@ def members_set_option(arg):
|
||||
SUPPRESS = object()
|
||||
|
||||
|
||||
def annotation_option(arg):
|
||||
# type: (Any) -> Any
|
||||
def annotation_option(arg: Any) -> Any:
|
||||
if arg is None:
|
||||
# suppress showing the representation of the object
|
||||
return SUPPRESS
|
||||
@@ -99,16 +94,14 @@ def annotation_option(arg):
|
||||
return arg
|
||||
|
||||
|
||||
def bool_option(arg):
|
||||
# type: (Any) -> bool
|
||||
def bool_option(arg: Any) -> bool:
|
||||
"""Used to convert flag options to auto directives. (Instead of
|
||||
directives.flag(), which returns None).
|
||||
"""
|
||||
return True
|
||||
|
||||
|
||||
def merge_special_members_option(options):
|
||||
# type: (Dict) -> None
|
||||
def merge_special_members_option(options: Dict) -> None:
|
||||
"""Merge :special-members: option to :members: option."""
|
||||
if 'special-members' in options and options['special-members'] is not ALL:
|
||||
if options.get('members') is ALL:
|
||||
@@ -123,8 +116,7 @@ def merge_special_members_option(options):
|
||||
|
||||
# Some useful event listener factories for autodoc-process-docstring.
|
||||
|
||||
def cut_lines(pre, post=0, what=None):
|
||||
# type: (int, int, str) -> Callable
|
||||
def cut_lines(pre: int, post: int = 0, what: str = None) -> Callable:
|
||||
"""Return a listener that removes the first *pre* and last *post*
|
||||
lines of every docstring. If *what* is a sequence of strings,
|
||||
only docstrings of a type in *what* will be processed.
|
||||
@@ -136,8 +128,8 @@ def cut_lines(pre, post=0, what=None):
|
||||
|
||||
This can (and should) be used in place of :confval:`automodule_skip_lines`.
|
||||
"""
|
||||
def process(app, what_, name, obj, options, lines):
|
||||
# type: (Sphinx, str, str, Any, Any, List[str]) -> None
|
||||
def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: List[str]
|
||||
) -> None:
|
||||
if what and what_ not in what:
|
||||
return
|
||||
del lines[:pre]
|
||||
@@ -152,8 +144,8 @@ def cut_lines(pre, post=0, what=None):
|
||||
return process
|
||||
|
||||
|
||||
def between(marker, what=None, keepempty=False, exclude=False):
|
||||
# type: (str, Sequence[str], bool, bool) -> Callable
|
||||
def between(marker: str, what: Sequence[str] = None, keepempty: bool = False,
|
||||
exclude: bool = False) -> Callable:
|
||||
"""Return a listener that either keeps, or if *exclude* is True excludes,
|
||||
lines between lines that match the *marker* regular expression. If no line
|
||||
matches, the resulting docstring would be empty, so no change will be made
|
||||
@@ -164,8 +156,8 @@ def between(marker, what=None, keepempty=False, exclude=False):
|
||||
"""
|
||||
marker_re = re.compile(marker)
|
||||
|
||||
def process(app, what_, name, obj, options, lines):
|
||||
# type: (Sphinx, str, str, Any, Any, List[str]) -> None
|
||||
def process(app: Sphinx, what_: str, name: str, obj: Any, options: Any, lines: List[str]
|
||||
) -> None:
|
||||
if what and what_ not in what:
|
||||
return
|
||||
deleted = 0
|
||||
@@ -192,8 +184,7 @@ def between(marker, what=None, keepempty=False, exclude=False):
|
||||
# But we define this class here to keep compatibility (see #4538)
|
||||
class Options(dict):
|
||||
"""A dict/attribute hybrid that returns None on nonexisting keys."""
|
||||
def __getattr__(self, name):
|
||||
# type: (str) -> Any
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
try:
|
||||
return self[name.replace('_', '-')]
|
||||
except KeyError:
|
||||
@@ -229,19 +220,17 @@ class Documenter:
|
||||
|
||||
option_spec = {'noindex': bool_option} # type: Dict[str, Callable]
|
||||
|
||||
def get_attr(self, obj, name, *defargs):
|
||||
# type: (Any, str, Any) -> Any
|
||||
def get_attr(self, obj: Any, name: str, *defargs) -> Any:
|
||||
"""getattr() override for types such as Zope interfaces."""
|
||||
return autodoc_attrgetter(self.env.app, obj, name, *defargs)
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
"""Called to see if a member can be documented by this documenter."""
|
||||
raise NotImplementedError('must be implemented in subclasses')
|
||||
|
||||
def __init__(self, directive, name, indent=''):
|
||||
# type: (DocumenterBridge, str, str) -> None
|
||||
def __init__(self, directive: "DocumenterBridge", name: str, indent: str = '') -> None:
|
||||
self.directive = directive
|
||||
self.env = directive.env # type: BuildEnvironment
|
||||
self.options = directive.genopt
|
||||
@@ -266,18 +255,16 @@ class Documenter:
|
||||
self.analyzer = None # type: ModuleAnalyzer
|
||||
|
||||
@property
|
||||
def documenters(self):
|
||||
# type: () -> Dict[str, Type[Documenter]]
|
||||
def documenters(self) -> Dict[str, Type["Documenter"]]:
|
||||
"""Returns registered Documenter classes"""
|
||||
return get_documenters(self.env.app)
|
||||
|
||||
def add_line(self, line, source, *lineno):
|
||||
# type: (str, str, int) -> None
|
||||
def add_line(self, line: str, source: str, *lineno: int) -> None:
|
||||
"""Append one line of generated reST to the output."""
|
||||
self.directive.result.append(self.indent + line, source, *lineno)
|
||||
|
||||
def resolve_name(self, modname, parents, path, base):
|
||||
# type: (str, Any, str, Any) -> Tuple[str, List[str]]
|
||||
def resolve_name(self, modname: str, parents: Any, path: str, base: Any
|
||||
) -> Tuple[str, List[str]]:
|
||||
"""Resolve the module and name of the object to document given by the
|
||||
arguments and the current module/class.
|
||||
|
||||
@@ -287,8 +274,7 @@ class Documenter:
|
||||
"""
|
||||
raise NotImplementedError('must be implemented in subclasses')
|
||||
|
||||
def parse_name(self):
|
||||
# type: () -> bool
|
||||
def parse_name(self) -> bool:
|
||||
"""Determine what module to import and what attribute to document.
|
||||
|
||||
Returns True and sets *self.modname*, *self.objpath*, *self.fullname*,
|
||||
@@ -324,8 +310,7 @@ class Documenter:
|
||||
(self.objpath and '.' + '.'.join(self.objpath) or '')
|
||||
return True
|
||||
|
||||
def import_object(self):
|
||||
# type: () -> bool
|
||||
def import_object(self) -> bool:
|
||||
"""Import the object given by *self.modname* and *self.objpath* and set
|
||||
it as *self.object*.
|
||||
|
||||
@@ -343,8 +328,7 @@ class Documenter:
|
||||
self.env.note_reread()
|
||||
return False
|
||||
|
||||
def get_real_modname(self):
|
||||
# type: () -> str
|
||||
def get_real_modname(self) -> str:
|
||||
"""Get the real module name of an object to document.
|
||||
|
||||
It can differ from the name of the module through which the object was
|
||||
@@ -352,8 +336,7 @@ class Documenter:
|
||||
"""
|
||||
return self.get_attr(self.object, '__module__', None) or self.modname
|
||||
|
||||
def check_module(self):
|
||||
# type: () -> bool
|
||||
def check_module(self) -> bool:
|
||||
"""Check if *self.object* is really defined in the module given by
|
||||
*self.modname*.
|
||||
"""
|
||||
@@ -367,16 +350,14 @@ class Documenter:
|
||||
return False
|
||||
return True
|
||||
|
||||
def format_args(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_args(self, **kwargs) -> str:
|
||||
"""Format the argument signature of *self.object*.
|
||||
|
||||
Should return None if the object does not have a signature.
|
||||
"""
|
||||
return None
|
||||
|
||||
def format_name(self):
|
||||
# type: () -> str
|
||||
def format_name(self) -> str:
|
||||
"""Format the name of *self.object*.
|
||||
|
||||
This normally should be something that can be parsed by the generated
|
||||
@@ -387,8 +368,7 @@ class Documenter:
|
||||
# directives of course)
|
||||
return '.'.join(self.objpath) or self.modname
|
||||
|
||||
def format_signature(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_signature(self, **kwargs) -> str:
|
||||
"""Format the signature (arguments and return annotation) of the object.
|
||||
|
||||
Let the user process it via the ``autodoc-process-signature`` event.
|
||||
@@ -422,8 +402,7 @@ class Documenter:
|
||||
else:
|
||||
return ''
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
"""Add the directive header and options to the generated content."""
|
||||
domain = getattr(self, 'domain', 'py')
|
||||
directive = getattr(self, 'directivetype', self.objtype)
|
||||
@@ -438,8 +417,7 @@ class Documenter:
|
||||
# etc. don't support a prepended module name
|
||||
self.add_line(' :module: %s' % self.modname, sourcename)
|
||||
|
||||
def get_doc(self, encoding=None, ignore=1):
|
||||
# type: (str, int) -> List[List[str]]
|
||||
def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]:
|
||||
"""Decode and return lines of the docstring(s) for the object."""
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."
|
||||
@@ -452,8 +430,7 @@ class Documenter:
|
||||
return [prepare_docstring(docstring, ignore, tab_width)]
|
||||
return []
|
||||
|
||||
def process_doc(self, docstrings):
|
||||
# type: (List[List[str]]) -> Iterator[str]
|
||||
def process_doc(self, docstrings: List[List[str]]) -> Iterator[str]:
|
||||
"""Let the user process the docstrings before adding them."""
|
||||
for docstringlines in docstrings:
|
||||
if self.env.app:
|
||||
@@ -463,14 +440,12 @@ class Documenter:
|
||||
self.options, docstringlines)
|
||||
yield from docstringlines
|
||||
|
||||
def get_sourcename(self):
|
||||
# type: () -> str
|
||||
def get_sourcename(self) -> str:
|
||||
if self.analyzer:
|
||||
return '%s:docstring of %s' % (self.analyzer.srcname, self.fullname)
|
||||
return 'docstring of %s' % self.fullname
|
||||
|
||||
def add_content(self, more_content, no_docstring=False):
|
||||
# type: (Any, bool) -> None
|
||||
def add_content(self, more_content: Any, no_docstring: bool = False) -> None:
|
||||
"""Add content from docstrings, attribute documentation and user."""
|
||||
# set sourcename and add content from attribute documentation
|
||||
sourcename = self.get_sourcename()
|
||||
@@ -500,8 +475,7 @@ class Documenter:
|
||||
for line, src in zip(more_content.data, more_content.items):
|
||||
self.add_line(line, src[0], src[1])
|
||||
|
||||
def get_object_members(self, want_all):
|
||||
# type: (bool) -> Tuple[bool, List[Tuple[str, Any]]]
|
||||
def get_object_members(self, want_all: bool) -> Tuple[bool, List[Tuple[str, Any]]]:
|
||||
"""Return `(members_check_module, members)` where `members` is a
|
||||
list of `(membername, member)` pairs of the members of *self.object*.
|
||||
|
||||
@@ -527,8 +501,8 @@ class Documenter:
|
||||
return False, sorted((m.name, m.value) for m in members.values()
|
||||
if m.directly_defined)
|
||||
|
||||
def filter_members(self, members, want_all):
|
||||
# type: (List[Tuple[str, Any]], bool) -> List[Tuple[str, Any, bool]]
|
||||
def filter_members(self, members: List[Tuple[str, Any]], want_all: bool
|
||||
) -> List[Tuple[str, Any, bool]]:
|
||||
"""Filter the given member list.
|
||||
|
||||
Members are skipped if
|
||||
@@ -616,8 +590,7 @@ class Documenter:
|
||||
|
||||
return ret
|
||||
|
||||
def document_members(self, all_members=False):
|
||||
# type: (bool) -> None
|
||||
def document_members(self, all_members: bool = False) -> None:
|
||||
"""Generate reST for member documentation.
|
||||
|
||||
If *all_members* is True, do all members, else those given by
|
||||
@@ -669,8 +642,7 @@ class Documenter:
|
||||
# sort by source order, by virtue of the module analyzer
|
||||
tagorder = self.analyzer.tagorder
|
||||
|
||||
def keyfunc(entry):
|
||||
# type: (Tuple[Documenter, bool]) -> int
|
||||
def keyfunc(entry: Tuple[Documenter, bool]) -> int:
|
||||
fullname = entry[0].name.split('::')[1]
|
||||
return tagorder.get(fullname, len(tagorder))
|
||||
memberdocumenters.sort(key=keyfunc)
|
||||
@@ -684,9 +656,8 @@ class Documenter:
|
||||
self.env.temp_data['autodoc:module'] = None
|
||||
self.env.temp_data['autodoc:class'] = None
|
||||
|
||||
def generate(self, more_content=None, real_modname=None,
|
||||
check_module=False, all_members=False):
|
||||
# type: (Any, str, bool, bool) -> None
|
||||
def generate(self, more_content: Any = None, real_modname: str = None,
|
||||
check_module: bool = False, all_members: bool = False) -> None:
|
||||
"""Generate reST for the object given by *self.name*, and possibly for
|
||||
its members.
|
||||
|
||||
@@ -778,26 +749,24 @@ class ModuleDocumenter(Documenter):
|
||||
'imported-members': bool_option, 'ignore-module-all': bool_option
|
||||
} # type: Dict[str, Callable]
|
||||
|
||||
def __init__(self, *args):
|
||||
# type: (Any) -> None
|
||||
def __init__(self, *args) -> None:
|
||||
super().__init__(*args)
|
||||
merge_special_members_option(self.options)
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
# don't document submodules automatically
|
||||
return False
|
||||
|
||||
def resolve_name(self, modname, parents, path, base):
|
||||
# type: (str, Any, str, Any) -> Tuple[str, List[str]]
|
||||
def resolve_name(self, modname: str, parents: Any, path: str, base: Any
|
||||
) -> Tuple[str, List[str]]:
|
||||
if modname is not None:
|
||||
logger.warning(__('"::" in automodule name doesn\'t make sense'),
|
||||
type='autodoc')
|
||||
return (path or '') + base, []
|
||||
|
||||
def parse_name(self):
|
||||
# type: () -> bool
|
||||
def parse_name(self) -> bool:
|
||||
ret = super().parse_name()
|
||||
if self.args or self.retann:
|
||||
logger.warning(__('signature arguments or return annotation '
|
||||
@@ -805,8 +774,7 @@ class ModuleDocumenter(Documenter):
|
||||
type='autodoc')
|
||||
return ret
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
Documenter.add_directive_header(self, sig)
|
||||
|
||||
sourcename = self.get_sourcename()
|
||||
@@ -819,8 +787,7 @@ class ModuleDocumenter(Documenter):
|
||||
if self.options.deprecated:
|
||||
self.add_line(' :deprecated:', sourcename)
|
||||
|
||||
def get_object_members(self, want_all):
|
||||
# type: (bool) -> Tuple[bool, List[Tuple[str, object]]]
|
||||
def get_object_members(self, want_all: bool) -> Tuple[bool, List[Tuple[str, object]]]:
|
||||
if want_all:
|
||||
if (self.options.ignore_module_all or not
|
||||
hasattr(self.object, '__all__')):
|
||||
@@ -861,8 +828,8 @@ class ModuleLevelDocumenter(Documenter):
|
||||
Specialized Documenter subclass for objects on module level (functions,
|
||||
classes, data/constants).
|
||||
"""
|
||||
def resolve_name(self, modname, parents, path, base):
|
||||
# type: (str, Any, str, Any) -> Tuple[str, List[str]]
|
||||
def resolve_name(self, modname: str, parents: Any, path: str, base: Any
|
||||
) -> Tuple[str, List[str]]:
|
||||
if modname is None:
|
||||
if path:
|
||||
modname = path.rstrip('.')
|
||||
@@ -882,8 +849,8 @@ class ClassLevelDocumenter(Documenter):
|
||||
Specialized Documenter subclass for objects on class level (methods,
|
||||
attributes).
|
||||
"""
|
||||
def resolve_name(self, modname, parents, path, base):
|
||||
# type: (str, Any, str, Any) -> Tuple[str, List[str]]
|
||||
def resolve_name(self, modname: str, parents: Any, path: str, base: Any
|
||||
) -> Tuple[str, List[str]]:
|
||||
if modname is None:
|
||||
if path:
|
||||
mod_cls = path.rstrip('.')
|
||||
@@ -916,8 +883,7 @@ class DocstringSignatureMixin:
|
||||
feature of reading the signature from the docstring.
|
||||
"""
|
||||
|
||||
def _find_signature(self, encoding=None):
|
||||
# type: (str) -> Tuple[str, str]
|
||||
def _find_signature(self, encoding: str = None) -> Tuple[str, str]:
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s._find_signature() is "
|
||||
"deprecated." % self.__class__.__name__,
|
||||
@@ -951,8 +917,7 @@ class DocstringSignatureMixin:
|
||||
break
|
||||
return result
|
||||
|
||||
def get_doc(self, encoding=None, ignore=1):
|
||||
# type: (str, int) -> List[List[str]]
|
||||
def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]:
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."
|
||||
% self.__class__.__name__,
|
||||
@@ -962,8 +927,7 @@ class DocstringSignatureMixin:
|
||||
return lines
|
||||
return super().get_doc(None, ignore) # type: ignore
|
||||
|
||||
def format_signature(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_signature(self, **kwargs) -> str:
|
||||
if self.args is None and self.env.config.autodoc_docstring_signature: # type: ignore
|
||||
# only act if a signature is not explicitly given already, and if
|
||||
# the feature is enabled
|
||||
@@ -978,8 +942,7 @@ class DocstringStripSignatureMixin(DocstringSignatureMixin):
|
||||
Mixin for AttributeDocumenter to provide the
|
||||
feature of stripping any function signature from the docstring.
|
||||
"""
|
||||
def format_signature(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_signature(self, **kwargs) -> str:
|
||||
if self.args is None and self.env.config.autodoc_docstring_signature: # type: ignore
|
||||
# only act if a signature is not explicitly given already, and if
|
||||
# the feature is enabled
|
||||
@@ -1000,14 +963,13 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
|
||||
member_order = 30
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
# supports functions, builtins and bound methods exported at the module level
|
||||
return (inspect.isfunction(member) or inspect.isbuiltin(member) or
|
||||
(inspect.isroutine(member) and isinstance(parent, ModuleDocumenter)))
|
||||
|
||||
def format_args(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_args(self, **kwargs) -> str:
|
||||
if self.env.config.autodoc_typehints == 'none':
|
||||
kwargs.setdefault('show_annotation', False)
|
||||
|
||||
@@ -1042,12 +1004,10 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
|
||||
args = args.replace('\\', '\\\\')
|
||||
return args
|
||||
|
||||
def document_members(self, all_members=False):
|
||||
# type: (bool) -> None
|
||||
def document_members(self, all_members: bool = False) -> None:
|
||||
pass
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
sourcename = self.get_sourcename()
|
||||
super().add_directive_header(sig)
|
||||
|
||||
@@ -1086,18 +1046,16 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
'private-members': bool_option, 'special-members': members_option,
|
||||
} # type: Dict[str, Callable]
|
||||
|
||||
def __init__(self, *args):
|
||||
# type: (Any) -> None
|
||||
def __init__(self, *args) -> None:
|
||||
super().__init__(*args)
|
||||
merge_special_members_option(self.options)
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
return isinstance(member, type)
|
||||
|
||||
def import_object(self):
|
||||
# type: () -> Any
|
||||
def import_object(self) -> Any:
|
||||
ret = super().import_object()
|
||||
# if the class is documented under another name, document it
|
||||
# as data/attribute
|
||||
@@ -1108,8 +1066,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
self.doc_as_attr = True
|
||||
return ret
|
||||
|
||||
def format_args(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_args(self, **kwargs) -> str:
|
||||
if self.env.config.autodoc_typehints == 'none':
|
||||
kwargs.setdefault('show_annotation', False)
|
||||
|
||||
@@ -1129,15 +1086,13 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
# with __init__ in C
|
||||
return None
|
||||
|
||||
def format_signature(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_signature(self, **kwargs) -> str:
|
||||
if self.doc_as_attr:
|
||||
return ''
|
||||
|
||||
return super().format_signature(**kwargs)
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
if self.doc_as_attr:
|
||||
self.directivetype = 'attribute'
|
||||
super().add_directive_header(sig)
|
||||
@@ -1154,8 +1109,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
self.add_line(' ' + _('Bases: %s') % ', '.join(bases),
|
||||
sourcename)
|
||||
|
||||
def get_doc(self, encoding=None, ignore=1):
|
||||
# type: (str, int) -> List[List[str]]
|
||||
def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]:
|
||||
if encoding is not None:
|
||||
warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated."
|
||||
% self.__class__.__name__,
|
||||
@@ -1199,8 +1153,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
tab_width = self.directive.state.document.settings.tab_width
|
||||
return [prepare_docstring(docstring, ignore, tab_width) for docstring in docstrings]
|
||||
|
||||
def add_content(self, more_content, no_docstring=False):
|
||||
# type: (Any, bool) -> None
|
||||
def add_content(self, more_content: Any, no_docstring: bool = False) -> None:
|
||||
if self.doc_as_attr:
|
||||
classname = safe_getattr(self.object, '__qualname__', None)
|
||||
if not classname:
|
||||
@@ -1215,15 +1168,13 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
||||
else:
|
||||
super().add_content(more_content)
|
||||
|
||||
def document_members(self, all_members=False):
|
||||
# type: (bool) -> None
|
||||
def document_members(self, all_members: bool = False) -> None:
|
||||
if self.doc_as_attr:
|
||||
return
|
||||
super().document_members(all_members)
|
||||
|
||||
def generate(self, more_content=None, real_modname=None,
|
||||
check_module=False, all_members=False):
|
||||
# type: (Any, str, bool, bool) -> None
|
||||
def generate(self, more_content: Any = None, real_modname: str = None,
|
||||
check_module: bool = False, all_members: bool = False) -> None:
|
||||
# Do not pass real_modname and use the name from the __module__
|
||||
# attribute of the class.
|
||||
# If a class gets imported into the module real_modname
|
||||
@@ -1245,8 +1196,8 @@ class ExceptionDocumenter(ClassDocumenter):
|
||||
priority = 10
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
return isinstance(member, type) and issubclass(member, BaseException)
|
||||
|
||||
|
||||
@@ -1261,12 +1212,11 @@ class DataDocumenter(ModuleLevelDocumenter):
|
||||
option_spec["annotation"] = annotation_option
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
return isinstance(parent, ModuleDocumenter) and isattr
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
super().add_directive_header(sig)
|
||||
sourcename = self.get_sourcename()
|
||||
if not self.options.annotation:
|
||||
@@ -1282,12 +1232,10 @@ class DataDocumenter(ModuleLevelDocumenter):
|
||||
self.add_line(' :annotation: %s' % self.options.annotation,
|
||||
sourcename)
|
||||
|
||||
def document_members(self, all_members=False):
|
||||
# type: (bool) -> None
|
||||
def document_members(self, all_members: bool = False) -> None:
|
||||
pass
|
||||
|
||||
def get_real_modname(self):
|
||||
# type: () -> str
|
||||
def get_real_modname(self) -> str:
|
||||
return self.get_attr(self.parent or self.object, '__module__', None) \
|
||||
or self.modname
|
||||
|
||||
@@ -1302,13 +1250,12 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
||||
priority = 1 # must be more than FunctionDocumenter
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
return inspect.isroutine(member) and \
|
||||
not isinstance(parent, ModuleDocumenter)
|
||||
|
||||
def import_object(self):
|
||||
# type: () -> Any
|
||||
def import_object(self) -> Any:
|
||||
ret = super().import_object()
|
||||
if not ret:
|
||||
return ret
|
||||
@@ -1325,8 +1272,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
||||
|
||||
return ret
|
||||
|
||||
def format_args(self, **kwargs):
|
||||
# type: (Any) -> str
|
||||
def format_args(self, **kwargs) -> str:
|
||||
if self.env.config.autodoc_typehints == 'none':
|
||||
kwargs.setdefault('show_annotation', False)
|
||||
|
||||
@@ -1341,8 +1287,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
||||
args = args.replace('\\', '\\\\')
|
||||
return args
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig) -> None:
|
||||
super().add_directive_header(sig)
|
||||
|
||||
sourcename = self.get_sourcename()
|
||||
@@ -1356,8 +1301,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
|
||||
if inspect.isstaticmethod(obj, cls=self.parent, name=self.object_name):
|
||||
self.add_line(' :staticmethod:', sourcename)
|
||||
|
||||
def document_members(self, all_members=False):
|
||||
# type: (bool) -> None
|
||||
def document_members(self, all_members: bool = False) -> None:
|
||||
pass
|
||||
|
||||
|
||||
@@ -1375,13 +1319,12 @@ class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
|
||||
priority = 10
|
||||
|
||||
@staticmethod
|
||||
def is_function_or_method(obj):
|
||||
# type: (Any) -> bool
|
||||
def is_function_or_method(obj: Any) -> bool:
|
||||
return inspect.isfunction(obj) or inspect.isbuiltin(obj) or inspect.ismethod(obj)
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
if inspect.isattributedescriptor(member):
|
||||
return True
|
||||
elif (not isinstance(parent, ModuleDocumenter) and
|
||||
@@ -1391,12 +1334,10 @@ class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
|
||||
else:
|
||||
return False
|
||||
|
||||
def document_members(self, all_members=False):
|
||||
# type: (bool) -> None
|
||||
def document_members(self, all_members: bool = False) -> None:
|
||||
pass
|
||||
|
||||
def import_object(self):
|
||||
# type: () -> Any
|
||||
def import_object(self) -> Any:
|
||||
ret = super().import_object()
|
||||
if inspect.isenumattribute(self.object):
|
||||
self.object = self.object.value
|
||||
@@ -1407,13 +1348,11 @@ class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
|
||||
self._datadescriptor = False
|
||||
return ret
|
||||
|
||||
def get_real_modname(self):
|
||||
# type: () -> str
|
||||
def get_real_modname(self) -> str:
|
||||
return self.get_attr(self.parent or self.object, '__module__', None) \
|
||||
or self.modname
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
super().add_directive_header(sig)
|
||||
sourcename = self.get_sourcename()
|
||||
if not self.options.annotation:
|
||||
@@ -1429,8 +1368,7 @@ class AttributeDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter):
|
||||
else:
|
||||
self.add_line(' :annotation: %s' % self.options.annotation, sourcename)
|
||||
|
||||
def add_content(self, more_content, no_docstring=False):
|
||||
# type: (Any, bool) -> None
|
||||
def add_content(self, more_content: Any, no_docstring: bool = False) -> None:
|
||||
if not self._datadescriptor:
|
||||
# if it's not a data descriptor, its docstring is very probably the
|
||||
# wrong thing to display
|
||||
@@ -1450,21 +1388,18 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): #
|
||||
priority = AttributeDocumenter.priority + 1
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
return inspect.isproperty(member) and isinstance(parent, ClassDocumenter)
|
||||
|
||||
def document_members(self, all_members=False):
|
||||
# type: (bool) -> None
|
||||
def document_members(self, all_members: bool = False) -> None:
|
||||
pass
|
||||
|
||||
def get_real_modname(self):
|
||||
# type: () -> str
|
||||
def get_real_modname(self) -> str:
|
||||
return self.get_attr(self.parent or self.object, '__module__', None) \
|
||||
or self.modname
|
||||
|
||||
def add_directive_header(self, sig):
|
||||
# type: (str) -> None
|
||||
def add_directive_header(self, sig: str) -> None:
|
||||
super().add_directive_header(sig)
|
||||
sourcename = self.get_sourcename()
|
||||
if inspect.isabstractmethod(self.object):
|
||||
@@ -1485,21 +1420,19 @@ class InstanceAttributeDocumenter(AttributeDocumenter):
|
||||
priority = 11
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
"""This documents only INSTANCEATTR members."""
|
||||
return isattr and (member is INSTANCEATTR)
|
||||
|
||||
def import_object(self):
|
||||
# type: () -> bool
|
||||
def import_object(self) -> bool:
|
||||
"""Never import anything."""
|
||||
# disguise as an attribute
|
||||
self.objtype = 'attribute'
|
||||
self._datadescriptor = False
|
||||
return True
|
||||
|
||||
def add_content(self, more_content, no_docstring=False):
|
||||
# type: (Any, bool) -> None
|
||||
def add_content(self, more_content: Any, no_docstring: bool = False) -> None:
|
||||
"""Never try to get a docstring from the object."""
|
||||
super().add_content(more_content, no_docstring=True)
|
||||
|
||||
@@ -1517,13 +1450,12 @@ class SlotsAttributeDocumenter(AttributeDocumenter):
|
||||
priority = 11
|
||||
|
||||
@classmethod
|
||||
def can_document_member(cls, member, membername, isattr, parent):
|
||||
# type: (Any, str, bool, Any) -> bool
|
||||
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
|
||||
) -> bool:
|
||||
"""This documents only SLOTSATTR members."""
|
||||
return member is SLOTSATTR
|
||||
|
||||
def import_object(self):
|
||||
# type: () -> bool
|
||||
def import_object(self) -> Any:
|
||||
"""Never import anything."""
|
||||
# disguise as an attribute
|
||||
self.objtype = 'attribute'
|
||||
@@ -1541,8 +1473,7 @@ class SlotsAttributeDocumenter(AttributeDocumenter):
|
||||
self.env.note_reread()
|
||||
return False
|
||||
|
||||
def get_doc(self, encoding=None, ignore=1):
|
||||
# type: (str, int) -> List[List[str]]
|
||||
def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]:
|
||||
"""Decode and return lines of the docstring(s) for the object."""
|
||||
name = self.objpath[-1]
|
||||
__slots__ = safe_getattr(self.parent, '__slots__', [])
|
||||
@@ -1553,14 +1484,12 @@ class SlotsAttributeDocumenter(AttributeDocumenter):
|
||||
return []
|
||||
|
||||
|
||||
def get_documenters(app):
|
||||
# type: (Sphinx) -> Dict[str, Type[Documenter]]
|
||||
def get_documenters(app: Sphinx) -> Dict[str, Type[Documenter]]:
|
||||
"""Returns registered Documenter classes"""
|
||||
return app.registry.documenters
|
||||
|
||||
|
||||
def autodoc_attrgetter(app, obj, name, *defargs):
|
||||
# type: (Sphinx, Any, str, Any) -> Any
|
||||
def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs) -> Any:
|
||||
"""Alternative getattr() for types"""
|
||||
for typ, func in app.registry.autodoc_attrgettrs.items():
|
||||
if isinstance(obj, typ):
|
||||
@@ -1569,8 +1498,7 @@ def autodoc_attrgetter(app, obj, name, *defargs):
|
||||
return safe_getattr(obj, name, *defargs)
|
||||
|
||||
|
||||
def merge_autodoc_default_flags(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
def merge_autodoc_default_flags(app: Sphinx, config: Config) -> None:
|
||||
"""This merges the autodoc_default_flags to autodoc_default_options."""
|
||||
if not config.autodoc_default_flags:
|
||||
return
|
||||
@@ -1602,8 +1530,7 @@ deprecated_alias('sphinx.ext.autodoc',
|
||||
RemovedInSphinx40Warning)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_autodocumenter(ModuleDocumenter)
|
||||
app.add_autodocumenter(ClassDocumenter)
|
||||
app.add_autodocumenter(ExceptionDocumenter)
|
||||
|
||||
@@ -7,27 +7,22 @@
|
||||
"""
|
||||
|
||||
import warnings
|
||||
from typing import Any, Callable, Dict, List, Set, Type
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst.states import Struct
|
||||
from docutils.nodes import Element, Node
|
||||
from docutils.parsers.rst.states import RSTState, Struct
|
||||
from docutils.statemachine import StringList
|
||||
from docutils.utils import assemble_option_dict
|
||||
from docutils.utils import Reporter, assemble_option_dict
|
||||
|
||||
from sphinx.config import Config
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning
|
||||
from sphinx.ext.autodoc import Options, get_documenters
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.ext.autodoc import Documenter, Options, get_documenters
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docutils import SphinxDirective, switch_source_input
|
||||
from sphinx.util.nodes import nested_parse_with_titles
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Dict, List, Set, Type # NOQA
|
||||
from docutils.parsers.rst.state import RSTState # NOQA
|
||||
from docutils.utils import Reporter # NOQA
|
||||
from sphinx.config import Config # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.ext.autodoc import Documenter # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -41,21 +36,19 @@ AUTODOC_DEFAULT_OPTIONS = ['members', 'undoc-members', 'inherited-members',
|
||||
class DummyOptionSpec(dict):
|
||||
"""An option_spec allows any options."""
|
||||
|
||||
def __bool__(self):
|
||||
# type: () -> bool
|
||||
def __bool__(self) -> bool:
|
||||
"""Behaves like some options are defined."""
|
||||
return True
|
||||
|
||||
def __getitem__(self, key):
|
||||
# type: (str) -> Callable[[str], str]
|
||||
def __getitem__(self, key: str) -> Callable[[str], str]:
|
||||
return lambda x: x
|
||||
|
||||
|
||||
class DocumenterBridge:
|
||||
"""A parameters container for Documenters."""
|
||||
|
||||
def __init__(self, env, reporter, options, lineno, state=None):
|
||||
# type: (BuildEnvironment, Reporter, Options, int, Any) -> None
|
||||
def __init__(self, env: BuildEnvironment, reporter: Reporter, options: Options,
|
||||
lineno: int, state: Any = None) -> None:
|
||||
self.env = env
|
||||
self.reporter = reporter
|
||||
self.genopt = options
|
||||
@@ -73,13 +66,12 @@ class DocumenterBridge:
|
||||
document = Struct(settings=settings)
|
||||
self.state = Struct(document=document)
|
||||
|
||||
def warn(self, msg):
|
||||
# type: (str) -> None
|
||||
def warn(self, msg: str) -> None:
|
||||
logger.warning(msg, location=(self.env.docname, self.lineno))
|
||||
|
||||
|
||||
def process_documenter_options(documenter, config, options):
|
||||
# type: (Type[Documenter], Config, Dict) -> Options
|
||||
def process_documenter_options(documenter: Type[Documenter], config: Config, options: Dict
|
||||
) -> Options:
|
||||
"""Recognize options of Documenter from user input."""
|
||||
for name in AUTODOC_DEFAULT_OPTIONS:
|
||||
if name not in documenter.option_spec:
|
||||
@@ -92,12 +84,12 @@ def process_documenter_options(documenter, config, options):
|
||||
return Options(assemble_option_dict(options.items(), documenter.option_spec))
|
||||
|
||||
|
||||
def parse_generated_content(state, content, documenter):
|
||||
# type: (RSTState, StringList, Documenter) -> List[nodes.Node]
|
||||
def parse_generated_content(state: RSTState, content: StringList, documenter: Documenter
|
||||
) -> List[Node]:
|
||||
"""Parse a generated content by Documenter."""
|
||||
with switch_source_input(state, content):
|
||||
if documenter.titles_allowed:
|
||||
node = nodes.section() # type: nodes.Element
|
||||
node = nodes.section() # type: Element
|
||||
# necessary so that the child nodes get the right source/line set
|
||||
node.document = state.document
|
||||
nested_parse_with_titles(state, content, node)
|
||||
@@ -121,8 +113,7 @@ class AutodocDirective(SphinxDirective):
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
reporter = self.state.document.reporter
|
||||
|
||||
try:
|
||||
|
||||
@@ -12,20 +12,16 @@ import sys
|
||||
import traceback
|
||||
import warnings
|
||||
from collections import namedtuple
|
||||
from typing import Any, Callable, Dict, List
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.inspect import isclass, isenumclass, safe_getattr
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Callable, Dict, List # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def import_module(modname, warningiserror=False):
|
||||
# type: (str, bool) -> Any
|
||||
def import_module(modname: str, warningiserror: bool = False) -> Any:
|
||||
"""
|
||||
Call __import__(modname), convert exceptions to ImportError
|
||||
"""
|
||||
@@ -41,8 +37,9 @@ def import_module(modname, warningiserror=False):
|
||||
raise ImportError(exc, traceback.format_exc())
|
||||
|
||||
|
||||
def import_object(modname, objpath, objtype='', attrgetter=safe_getattr, warningiserror=False):
|
||||
# type: (str, List[str], str, Callable[[Any, str], Any], bool) -> Any
|
||||
def import_object(modname: str, objpath: List[str], objtype: str = '',
|
||||
attrgetter: Callable[[Any, str], Any] = safe_getattr,
|
||||
warningiserror: bool = False) -> Any:
|
||||
if objpath:
|
||||
logger.debug('[autodoc] from %s import %s', modname, '.'.join(objpath))
|
||||
else:
|
||||
@@ -108,8 +105,8 @@ def import_object(modname, objpath, objtype='', attrgetter=safe_getattr, warning
|
||||
Attribute = namedtuple('Attribute', ['name', 'directly_defined', 'value'])
|
||||
|
||||
|
||||
def get_object_members(subject, objpath, attrgetter, analyzer=None):
|
||||
# type: (Any, List[str], Callable, Any) -> Dict[str, Attribute] # NOQA
|
||||
def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
|
||||
analyzer: Any = None) -> Dict[str, Attribute]:
|
||||
"""Get members and attributes of target object."""
|
||||
# the members directly defined in the class
|
||||
obj_dict = attrgetter(subject, '__dict__', {})
|
||||
|
||||
+28
-54
@@ -15,14 +15,11 @@ import warnings
|
||||
from importlib.abc import Loader, MetaPathFinder
|
||||
from importlib.machinery import ModuleSpec
|
||||
from types import FunctionType, MethodType, ModuleType
|
||||
from typing import Any, Generator, Iterator, List, Sequence, Tuple, Union
|
||||
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||
from sphinx.util import logging
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Generator, Iterator, List, Sequence, Tuple, Union # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -31,8 +28,7 @@ class _MockObject:
|
||||
|
||||
__display_name__ = '_MockObject'
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
# type: (Any, Any) -> Any
|
||||
def __new__(cls, *args, **kwargs) -> Any:
|
||||
if len(args) == 3 and isinstance(args[1], tuple):
|
||||
superclass = args[1][-1].__class__
|
||||
if superclass is cls:
|
||||
@@ -42,48 +38,39 @@ class _MockObject:
|
||||
|
||||
return super().__new__(cls)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
# type: (Any, Any) -> None
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
self.__qualname__ = ''
|
||||
|
||||
def __len__(self):
|
||||
# type: () -> int
|
||||
def __len__(self) -> int:
|
||||
return 0
|
||||
|
||||
def __contains__(self, key):
|
||||
# type: (str) -> bool
|
||||
def __contains__(self, key: str) -> bool:
|
||||
return False
|
||||
|
||||
def __iter__(self):
|
||||
# type: () -> Iterator
|
||||
def __iter__(self) -> Iterator:
|
||||
return iter([])
|
||||
|
||||
def __mro_entries__(self, bases):
|
||||
# type: (Tuple) -> Tuple
|
||||
def __mro_entries__(self, bases: Tuple) -> Tuple:
|
||||
return (self.__class__,)
|
||||
|
||||
def __getitem__(self, key):
|
||||
# type: (str) -> _MockObject
|
||||
def __getitem__(self, key: str) -> "_MockObject":
|
||||
return _make_subclass(key, self.__display_name__, self.__class__)()
|
||||
|
||||
def __getattr__(self, key):
|
||||
# type: (str) -> _MockObject
|
||||
def __getattr__(self, key: str) -> "_MockObject":
|
||||
return _make_subclass(key, self.__display_name__, self.__class__)()
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
# type: (Any, Any) -> Any
|
||||
def __call__(self, *args, **kw) -> Any:
|
||||
if args and type(args[0]) in [FunctionType, MethodType]:
|
||||
# Appears to be a decorator, pass through unchanged
|
||||
return args[0]
|
||||
return self
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
def __repr__(self) -> str:
|
||||
return self.__display_name__
|
||||
|
||||
|
||||
def _make_subclass(name, module, superclass=_MockObject, attributes=None):
|
||||
# type: (str, str, Any, dict) -> Any
|
||||
def _make_subclass(name: str, module: str, superclass: Any = _MockObject,
|
||||
attributes: Any = None) -> Any:
|
||||
attrs = {'__module__': module, '__display_name__': module + '.' + name}
|
||||
attrs.update(attributes or {})
|
||||
|
||||
@@ -94,8 +81,7 @@ class _MockModule(ModuleType):
|
||||
"""Used by autodoc_mock_imports."""
|
||||
__file__ = os.devnull
|
||||
|
||||
def __init__(self, name, loader=None):
|
||||
# type: (str, _MockImporter) -> None
|
||||
def __init__(self, name: str, loader: "_MockImporter" = None) -> None:
|
||||
super().__init__(name)
|
||||
self.__all__ = [] # type: List[str]
|
||||
self.__path__ = [] # type: List[str]
|
||||
@@ -104,18 +90,15 @@ class _MockModule(ModuleType):
|
||||
warnings.warn('The loader argument for _MockModule is deprecated.',
|
||||
RemovedInSphinx30Warning)
|
||||
|
||||
def __getattr__(self, name):
|
||||
# type: (str) -> _MockObject
|
||||
def __getattr__(self, name: str) -> _MockObject:
|
||||
return _make_subclass(name, self.__name__)()
|
||||
|
||||
def __repr__(self):
|
||||
# type: () -> str
|
||||
def __repr__(self) -> str:
|
||||
return self.__name__
|
||||
|
||||
|
||||
class _MockImporter(MetaPathFinder):
|
||||
def __init__(self, names):
|
||||
# type: (List[str]) -> None
|
||||
def __init__(self, names: List[str]) -> None:
|
||||
self.names = names
|
||||
self.mocked_modules = [] # type: List[str]
|
||||
# enable hook by adding itself to meta_path
|
||||
@@ -124,8 +107,7 @@ class _MockImporter(MetaPathFinder):
|
||||
warnings.warn('_MockImporter is now deprecated.',
|
||||
RemovedInSphinx30Warning)
|
||||
|
||||
def disable(self):
|
||||
# type: () -> None
|
||||
def disable(self) -> None:
|
||||
# remove `self` from `sys.meta_path` to disable import hook
|
||||
sys.meta_path = [i for i in sys.meta_path if i is not self]
|
||||
# remove mocked modules from sys.modules to avoid side effects after
|
||||
@@ -134,16 +116,14 @@ class _MockImporter(MetaPathFinder):
|
||||
if m in sys.modules:
|
||||
del sys.modules[m]
|
||||
|
||||
def find_module(self, name, path=None):
|
||||
# type: (str, Sequence[Union[bytes, str]]) -> Any
|
||||
def find_module(self, name: str, path: Sequence[Union[bytes, str]] = None) -> Any:
|
||||
# check if name is (or is a descendant of) one of our base_packages
|
||||
for n in self.names:
|
||||
if n == name or name.startswith(n + '.'):
|
||||
return self
|
||||
return None
|
||||
|
||||
def load_module(self, name):
|
||||
# type: (str) -> ModuleType
|
||||
def load_module(self, name: str) -> ModuleType:
|
||||
if name in sys.modules:
|
||||
# module has already been imported, return it
|
||||
return sys.modules[name]
|
||||
@@ -157,34 +137,30 @@ class _MockImporter(MetaPathFinder):
|
||||
|
||||
class MockLoader(Loader):
|
||||
"""A loader for mocking."""
|
||||
def __init__(self, finder):
|
||||
# type: (MockFinder) -> None
|
||||
def __init__(self, finder: "MockFinder") -> None:
|
||||
super().__init__()
|
||||
self.finder = finder
|
||||
|
||||
def create_module(self, spec):
|
||||
# type: (ModuleSpec) -> ModuleType
|
||||
def create_module(self, spec: ModuleSpec) -> ModuleType:
|
||||
logger.debug('[autodoc] adding a mock module as %s!', spec.name)
|
||||
self.finder.mocked_modules.append(spec.name)
|
||||
return _MockModule(spec.name)
|
||||
|
||||
def exec_module(self, module):
|
||||
# type: (ModuleType) -> None
|
||||
def exec_module(self, module: ModuleType) -> None:
|
||||
pass # nothing to do
|
||||
|
||||
|
||||
class MockFinder(MetaPathFinder):
|
||||
"""A finder for mocking."""
|
||||
|
||||
def __init__(self, modnames):
|
||||
# type: (List[str]) -> None
|
||||
def __init__(self, modnames: List[str]) -> None:
|
||||
super().__init__()
|
||||
self.modnames = modnames
|
||||
self.loader = MockLoader(self)
|
||||
self.mocked_modules = [] # type: List[str]
|
||||
|
||||
def find_spec(self, fullname, path, target=None):
|
||||
# type: (str, Sequence[Union[bytes, str]], ModuleType) -> ModuleSpec
|
||||
def find_spec(self, fullname: str, path: Sequence[Union[bytes, str]],
|
||||
target: ModuleType = None) -> ModuleSpec:
|
||||
for modname in self.modnames:
|
||||
# check if fullname is (or is a descendant of) one of our targets
|
||||
if modname == fullname or fullname.startswith(modname + '.'):
|
||||
@@ -192,16 +168,14 @@ class MockFinder(MetaPathFinder):
|
||||
|
||||
return None
|
||||
|
||||
def invalidate_caches(self):
|
||||
# type: () -> None
|
||||
def invalidate_caches(self) -> None:
|
||||
"""Invalidate mocked modules on sys.modules."""
|
||||
for modname in self.mocked_modules:
|
||||
sys.modules.pop(modname, None)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def mock(modnames):
|
||||
# type: (List[str]) -> Generator[None, None, None]
|
||||
def mock(modnames: List[str]) -> Generator[None, None, None]:
|
||||
"""Insert mock modules during context::
|
||||
|
||||
with mock(['target.module.name']):
|
||||
|
||||
+13
-27
@@ -14,30 +14,25 @@ import inspect
|
||||
import pickle
|
||||
import re
|
||||
from os import path
|
||||
from typing import Any, Dict, IO, List, Pattern, Set, Tuple
|
||||
|
||||
import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders import Builder
|
||||
from sphinx.locale import __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.inspect import safe_getattr
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, IO, List, Pattern, Set, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# utility
|
||||
def write_header(f, text, char='-'):
|
||||
# type:(IO, str, str) -> None
|
||||
def write_header(f: IO, text: str, char: str = '-') -> None:
|
||||
f.write(text + '\n')
|
||||
f.write(char * len(text) + '\n')
|
||||
|
||||
|
||||
def compile_regex_list(name, exps):
|
||||
# type: (str, str) -> List[Pattern]
|
||||
def compile_regex_list(name: str, exps: str) -> List[Pattern]:
|
||||
lst = []
|
||||
for exp in exps:
|
||||
try:
|
||||
@@ -55,8 +50,7 @@ class CoverageBuilder(Builder):
|
||||
epilog = __('Testing of coverage in the sources finished, look at the '
|
||||
'results in %(outdir)s' + path.sep + 'python.txt.')
|
||||
|
||||
def init(self):
|
||||
# type: () -> None
|
||||
def init(self) -> None:
|
||||
self.c_sourcefiles = [] # type: List[str]
|
||||
for pattern in self.config.coverage_c_path:
|
||||
pattern = path.join(self.srcdir, pattern)
|
||||
@@ -82,12 +76,10 @@ class CoverageBuilder(Builder):
|
||||
self.py_ignorexps = compile_regex_list('coverage_ignore_pyobjects',
|
||||
self.config.coverage_ignore_pyobjects)
|
||||
|
||||
def get_outdated_docs(self):
|
||||
# type: () -> str
|
||||
def get_outdated_docs(self) -> str:
|
||||
return 'coverage overview'
|
||||
|
||||
def write(self, *ignored):
|
||||
# type: (Any) -> None
|
||||
def write(self, *ignored) -> None:
|
||||
self.py_undoc = {} # type: Dict[str, Dict[str, Any]]
|
||||
self.build_py_coverage()
|
||||
self.write_py_coverage()
|
||||
@@ -96,8 +88,7 @@ class CoverageBuilder(Builder):
|
||||
self.build_c_coverage()
|
||||
self.write_c_coverage()
|
||||
|
||||
def build_c_coverage(self):
|
||||
# type: () -> None
|
||||
def build_c_coverage(self) -> None:
|
||||
# Fetch all the info from the header files
|
||||
c_objects = self.env.domaindata['c']['objects']
|
||||
for filename in self.c_sourcefiles:
|
||||
@@ -118,8 +109,7 @@ class CoverageBuilder(Builder):
|
||||
if undoc:
|
||||
self.c_undoc[filename] = undoc
|
||||
|
||||
def write_c_coverage(self):
|
||||
# type: () -> None
|
||||
def write_c_coverage(self) -> None:
|
||||
output_file = path.join(self.outdir, 'c.txt')
|
||||
with open(output_file, 'w') as op:
|
||||
if self.config.coverage_write_headline:
|
||||
@@ -138,8 +128,7 @@ class CoverageBuilder(Builder):
|
||||
return True
|
||||
return False
|
||||
|
||||
def build_py_coverage(self):
|
||||
# type: () -> None
|
||||
def build_py_coverage(self) -> None:
|
||||
objects = self.env.domaindata['py']['objects']
|
||||
modules = self.env.domaindata['py']['modules']
|
||||
|
||||
@@ -230,8 +219,7 @@ class CoverageBuilder(Builder):
|
||||
|
||||
self.py_undoc[mod_name] = {'funcs': funcs, 'classes': classes}
|
||||
|
||||
def write_py_coverage(self):
|
||||
# type: () -> None
|
||||
def write_py_coverage(self) -> None:
|
||||
output_file = path.join(self.outdir, 'python.txt')
|
||||
failed = []
|
||||
with open(output_file, 'w') as op:
|
||||
@@ -266,16 +254,14 @@ class CoverageBuilder(Builder):
|
||||
write_header(op, 'Modules that failed to import')
|
||||
op.writelines(' * %s -- %s\n' % x for x in failed)
|
||||
|
||||
def finish(self):
|
||||
# type: () -> None
|
||||
def finish(self) -> None:
|
||||
# dump the coverage data to a pickle file too
|
||||
picklepath = path.join(self.outdir, 'undoc.pickle')
|
||||
with open(picklepath, 'wb') as dumpfile:
|
||||
pickle.dump((self.py_undoc, self.c_undoc), dumpfile)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_builder(CoverageBuilder)
|
||||
app.add_config_value('coverage_ignore_modules', [], False)
|
||||
app.add_config_value('coverage_ignore_functions', [], False)
|
||||
|
||||
+12
-15
@@ -23,23 +23,22 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
from docutils import nodes, utils
|
||||
from docutils.nodes import Node, system_message
|
||||
from docutils.parsers.rst.states import Inliner
|
||||
|
||||
import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.util.nodes import split_explicit_title
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, List, Tuple # NOQA
|
||||
from docutils.parsers.rst.states import Inliner # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.util.typing import RoleFunction # NOQA
|
||||
from sphinx.util.typing import RoleFunction
|
||||
|
||||
|
||||
def make_link_role(base_url, prefix):
|
||||
# type: (str, str) -> RoleFunction
|
||||
def role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
# type: (str, str, str, int, Inliner, Dict, List[str]) -> Tuple[List[nodes.Node], List[nodes.system_message]] # NOQA
|
||||
def make_link_role(base_url: str, prefix: str) -> RoleFunction:
|
||||
def role(typ: str, rawtext: str, text: str, lineno: int,
|
||||
inliner: Inliner, options: Dict = {}, content: List[str] = []
|
||||
) -> Tuple[List[Node], List[system_message]]:
|
||||
text = utils.unescape(text)
|
||||
has_explicit_title, title, part = split_explicit_title(text)
|
||||
try:
|
||||
@@ -60,14 +59,12 @@ def make_link_role(base_url, prefix):
|
||||
return role
|
||||
|
||||
|
||||
def setup_link_roles(app):
|
||||
# type: (Sphinx) -> None
|
||||
def setup_link_roles(app: Sphinx) -> None:
|
||||
for name, (base_url, prefix) in app.config.extlinks.items():
|
||||
app.add_role(name, make_link_role(base_url, prefix))
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_config_value('extlinks', {}, 'env')
|
||||
app.connect('builder-inited', setup_link_roles)
|
||||
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
|
||||
@@ -10,18 +10,14 @@
|
||||
|
||||
import os
|
||||
import urllib
|
||||
from typing import Any, Dict
|
||||
|
||||
import sphinx
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.environment import BuildEnvironment
|
||||
|
||||
|
||||
def create_nojekyll_and_cname(app, env):
|
||||
# type: (Sphinx, BuildEnvironment) -> None
|
||||
def create_nojekyll_and_cname(app: Sphinx, env: BuildEnvironment) -> None:
|
||||
if app.builder.format == 'html':
|
||||
open(os.path.join(app.builder.outdir, '.nojekyll'), 'wt').close()
|
||||
|
||||
@@ -35,7 +31,6 @@ def create_nojekyll_and_cname(app, env):
|
||||
f.write(domain)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.connect('env-updated', create_nojekyll_and_cname)
|
||||
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
|
||||
+33
-51
@@ -15,31 +15,27 @@ import subprocess
|
||||
from hashlib import sha1
|
||||
from os import path
|
||||
from subprocess import CalledProcessError, PIPE
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst import directives
|
||||
from docutils.nodes import Node
|
||||
from docutils.parsers.rst import Directive, directives
|
||||
|
||||
import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import logging
|
||||
from sphinx.util.docutils import SphinxDirective
|
||||
from sphinx.util.docutils import SphinxDirective, SphinxTranslator
|
||||
from sphinx.util.fileutil import copy_asset
|
||||
from sphinx.util.i18n import search_image_for_language
|
||||
from sphinx.util.nodes import set_source_info
|
||||
from sphinx.util.osutil import ensuredir
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from docutils.parsers.rst import Directive # NOQA
|
||||
from typing import Any, Dict, List, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.util.docutils import SphinxTranslator # NOQA
|
||||
from sphinx.writers.html import HTMLTranslator # NOQA
|
||||
from sphinx.writers.latex import LaTeXTranslator # NOQA
|
||||
from sphinx.writers.manpage import ManualPageTranslator # NOQA
|
||||
from sphinx.writers.texinfo import TexinfoTranslator # NOQA
|
||||
from sphinx.writers.text import TextTranslator # NOQA
|
||||
from sphinx.writers.html import HTMLTranslator
|
||||
from sphinx.writers.latex import LaTeXTranslator
|
||||
from sphinx.writers.manpage import ManualPageTranslator
|
||||
from sphinx.writers.texinfo import TexinfoTranslator
|
||||
from sphinx.writers.text import TextTranslator
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -53,8 +49,7 @@ class ClickableMapDefinition:
|
||||
maptag_re = re.compile('<map id="(.*?)"')
|
||||
href_re = re.compile('href=".*?"')
|
||||
|
||||
def __init__(self, filename, content, dot=''):
|
||||
# type: (str, str, str) -> None
|
||||
def __init__(self, filename: str, content: str, dot: str = '') -> None:
|
||||
self.id = None # type: str
|
||||
self.filename = filename
|
||||
self.content = content.splitlines()
|
||||
@@ -62,8 +57,7 @@ class ClickableMapDefinition:
|
||||
|
||||
self.parse(dot=dot)
|
||||
|
||||
def parse(self, dot=None):
|
||||
# type: (str) -> None
|
||||
def parse(self, dot: str = None) -> None:
|
||||
matched = self.maptag_re.match(self.content[0])
|
||||
if not matched:
|
||||
raise GraphvizError('Invalid clickable map file found: %s' % self.filename)
|
||||
@@ -80,8 +74,7 @@ class ClickableMapDefinition:
|
||||
if self.href_re.search(line):
|
||||
self.clickable.append(line)
|
||||
|
||||
def generate_clickable_map(self):
|
||||
# type: () -> str
|
||||
def generate_clickable_map(self) -> str:
|
||||
"""Generate clickable map tags if clickable item exists.
|
||||
|
||||
If not exists, this only returns empty string.
|
||||
@@ -96,8 +89,7 @@ class graphviz(nodes.General, nodes.Inline, nodes.Element):
|
||||
pass
|
||||
|
||||
|
||||
def figure_wrapper(directive, node, caption):
|
||||
# type: (Directive, graphviz, str) -> nodes.figure
|
||||
def figure_wrapper(directive: Directive, node: graphviz, caption: str) -> nodes.figure:
|
||||
figure_node = nodes.figure('', node)
|
||||
if 'align' in node:
|
||||
figure_node['align'] = node.attributes.pop('align')
|
||||
@@ -110,8 +102,7 @@ def figure_wrapper(directive, node, caption):
|
||||
return figure_node
|
||||
|
||||
|
||||
def align_spec(argument):
|
||||
# type: (Any) -> str
|
||||
def align_spec(argument: Any) -> str:
|
||||
return directives.choice(argument, ('left', 'center', 'right'))
|
||||
|
||||
|
||||
@@ -132,8 +123,7 @@ class Graphviz(SphinxDirective):
|
||||
'name': directives.unchanged,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
if self.arguments:
|
||||
document = self.state.document
|
||||
if self.content:
|
||||
@@ -194,8 +184,7 @@ class GraphvizSimple(SphinxDirective):
|
||||
'name': directives.unchanged,
|
||||
}
|
||||
|
||||
def run(self):
|
||||
# type: () -> List[nodes.Node]
|
||||
def run(self) -> List[Node]:
|
||||
node = graphviz()
|
||||
node['code'] = '%s %s {\n%s\n}\n' % \
|
||||
(self.name, self.arguments[0], '\n'.join(self.content))
|
||||
@@ -216,8 +205,8 @@ class GraphvizSimple(SphinxDirective):
|
||||
return [figure]
|
||||
|
||||
|
||||
def render_dot(self, code, options, format, prefix='graphviz'):
|
||||
# type: (SphinxTranslator, str, Dict, str, str) -> Tuple[str, str]
|
||||
def render_dot(self: SphinxTranslator, code: str, options: Dict,
|
||||
format: str, prefix: str = 'graphviz') -> Tuple[str, str]:
|
||||
"""Render graphviz code into a PNG or PDF output file."""
|
||||
graphviz_dot = options.get('graphviz_dot', self.builder.config.graphviz_dot)
|
||||
hashkey = (code + str(options) + str(graphviz_dot) +
|
||||
@@ -265,9 +254,9 @@ def render_dot(self, code, options, format, prefix='graphviz'):
|
||||
'[stdout]\n%r') % (exc.stderr, exc.stdout))
|
||||
|
||||
|
||||
def render_dot_html(self, node, code, options, prefix='graphviz',
|
||||
imgcls=None, alt=None):
|
||||
# type: (HTMLTranslator, graphviz, str, Dict, str, str, str) -> Tuple[str, str]
|
||||
def render_dot_html(self: HTMLTranslator, node: graphviz, code: str, options: Dict,
|
||||
prefix: str = 'graphviz', imgcls: str = None, alt: str = None
|
||||
) -> Tuple[str, str]:
|
||||
format = self.builder.config.graphviz_output_format
|
||||
try:
|
||||
if format not in ('png', 'svg'):
|
||||
@@ -319,13 +308,12 @@ def render_dot_html(self, node, code, options, prefix='graphviz',
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
||||
def html_visit_graphviz(self, node):
|
||||
# type: (HTMLTranslator, graphviz) -> None
|
||||
def html_visit_graphviz(self: HTMLTranslator, node: graphviz) -> None:
|
||||
render_dot_html(self, node, node['code'], node['options'])
|
||||
|
||||
|
||||
def render_dot_latex(self, node, code, options, prefix='graphviz'):
|
||||
# type: (LaTeXTranslator, graphviz, str, Dict, str) -> None
|
||||
def render_dot_latex(self: LaTeXTranslator, node: graphviz, code: str,
|
||||
options: Dict, prefix: str = 'graphviz') -> None:
|
||||
try:
|
||||
fname, outfn = render_dot(self, code, options, 'pdf', prefix)
|
||||
except GraphvizError as exc:
|
||||
@@ -357,13 +345,12 @@ def render_dot_latex(self, node, code, options, prefix='graphviz'):
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
||||
def latex_visit_graphviz(self, node):
|
||||
# type: (LaTeXTranslator, graphviz) -> None
|
||||
def latex_visit_graphviz(self: LaTeXTranslator, node: graphviz) -> None:
|
||||
render_dot_latex(self, node, node['code'], node['options'])
|
||||
|
||||
|
||||
def render_dot_texinfo(self, node, code, options, prefix='graphviz'):
|
||||
# type: (TexinfoTranslator, graphviz, str, Dict, str) -> None
|
||||
def render_dot_texinfo(self: TexinfoTranslator, node: graphviz, code: str,
|
||||
options: Dict, prefix: str = 'graphviz') -> None:
|
||||
try:
|
||||
fname, outfn = render_dot(self, code, options, 'png', prefix)
|
||||
except GraphvizError as exc:
|
||||
@@ -374,13 +361,11 @@ def render_dot_texinfo(self, node, code, options, prefix='graphviz'):
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
||||
def texinfo_visit_graphviz(self, node):
|
||||
# type: (TexinfoTranslator, graphviz) -> None
|
||||
def texinfo_visit_graphviz(self: TexinfoTranslator, node: graphviz) -> None:
|
||||
render_dot_texinfo(self, node, node['code'], node['options'])
|
||||
|
||||
|
||||
def text_visit_graphviz(self, node):
|
||||
# type: (TextTranslator, graphviz) -> None
|
||||
def text_visit_graphviz(self: TextTranslator, node: graphviz) -> None:
|
||||
if 'alt' in node.attributes:
|
||||
self.add_text(_('[graph: %s]') % node['alt'])
|
||||
else:
|
||||
@@ -388,8 +373,7 @@ def text_visit_graphviz(self, node):
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
||||
def man_visit_graphviz(self, node):
|
||||
# type: (ManualPageTranslator, graphviz) -> None
|
||||
def man_visit_graphviz(self: ManualPageTranslator, node: graphviz) -> None:
|
||||
if 'alt' in node.attributes:
|
||||
self.body.append(_('[graph: %s]') % node['alt'])
|
||||
else:
|
||||
@@ -397,16 +381,14 @@ def man_visit_graphviz(self, node):
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
||||
def on_build_finished(app, exc):
|
||||
# type: (Sphinx, Exception) -> None
|
||||
def on_build_finished(app: Sphinx, exc: Exception) -> None:
|
||||
if exc is None:
|
||||
src = path.join(sphinx.package_dir, 'templates', 'graphviz', 'graphviz.css')
|
||||
dst = path.join(app.outdir, '_static')
|
||||
copy_asset(src, dst)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_node(graphviz,
|
||||
html=(html_visit_graphviz, None),
|
||||
latex=(latex_visit_graphviz, None),
|
||||
|
||||
@@ -7,19 +7,17 @@
|
||||
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
from subprocess import CalledProcessError, PIPE
|
||||
from typing import Any, Dict
|
||||
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.errors import ExtensionError
|
||||
from sphinx.locale import __
|
||||
from sphinx.transforms.post_transforms.images import ImageConverter
|
||||
from sphinx.util import logging
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -31,8 +29,7 @@ class ImagemagickConverter(ImageConverter):
|
||||
('application/pdf', 'image/png'),
|
||||
]
|
||||
|
||||
def is_available(self):
|
||||
# type: () -> bool
|
||||
def is_available(self) -> bool:
|
||||
"""Confirms the converter is available or not."""
|
||||
try:
|
||||
args = [self.config.image_converter, '-version']
|
||||
@@ -50,8 +47,7 @@ class ImagemagickConverter(ImageConverter):
|
||||
exc.stderr, exc.stdout)
|
||||
return False
|
||||
|
||||
def convert(self, _from, _to):
|
||||
# type: (str, str) -> bool
|
||||
def convert(self, _from: str, _to: str) -> bool:
|
||||
"""Converts the image to expected one."""
|
||||
try:
|
||||
# append an index 0 to source filename to pick up the first frame
|
||||
@@ -75,8 +71,7 @@ class ImagemagickConverter(ImageConverter):
|
||||
(exc.stderr, exc.stdout))
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_post_transform(ImagemagickConverter)
|
||||
app.add_config_value('image_converter', 'convert', 'env')
|
||||
app.add_config_value('image_converter_args', [], 'env')
|
||||
|
||||
+22
-37
@@ -28,24 +28,23 @@ import posixpath
|
||||
import sys
|
||||
import time
|
||||
from os import path
|
||||
from typing import Any, Dict, IO, List, Tuple
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, TextElement
|
||||
from docutils.utils import relative_path
|
||||
|
||||
import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders.html import INVENTORY_FILENAME
|
||||
from sphinx.config import Config
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.locale import _, __
|
||||
from sphinx.util import requests, logging
|
||||
from sphinx.util.inventory import InventoryFile
|
||||
from sphinx.util.typing import Inventory
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, IO, List, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.config import Config # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.util.typing import Inventory # NOQA
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -53,8 +52,7 @@ logger = logging.getLogger(__name__)
|
||||
class InventoryAdapter:
|
||||
"""Inventory adapter for environment"""
|
||||
|
||||
def __init__(self, env):
|
||||
# type: (BuildEnvironment) -> None
|
||||
def __init__(self, env: BuildEnvironment) -> None:
|
||||
self.env = env
|
||||
|
||||
if not hasattr(env, 'intersphinx_cache'):
|
||||
@@ -63,28 +61,23 @@ class InventoryAdapter:
|
||||
self.env.intersphinx_named_inventory = {} # type: ignore
|
||||
|
||||
@property
|
||||
def cache(self):
|
||||
# type: () -> Dict[str, Tuple[str, int, Inventory]]
|
||||
def cache(self) -> Dict[str, Tuple[str, int, Inventory]]:
|
||||
return self.env.intersphinx_cache # type: ignore
|
||||
|
||||
@property
|
||||
def main_inventory(self):
|
||||
# type: () -> Inventory
|
||||
def main_inventory(self) -> Inventory:
|
||||
return self.env.intersphinx_inventory # type: ignore
|
||||
|
||||
@property
|
||||
def named_inventory(self):
|
||||
# type: () -> Dict[str, Inventory]
|
||||
def named_inventory(self) -> Dict[str, Inventory]:
|
||||
return self.env.intersphinx_named_inventory # type: ignore
|
||||
|
||||
def clear(self):
|
||||
# type: () -> None
|
||||
def clear(self) -> None:
|
||||
self.env.intersphinx_inventory.clear() # type: ignore
|
||||
self.env.intersphinx_named_inventory.clear() # type: ignore
|
||||
|
||||
|
||||
def _strip_basic_auth(url):
|
||||
# type: (str) -> str
|
||||
def _strip_basic_auth(url: str) -> str:
|
||||
"""Returns *url* with basic auth credentials removed. Also returns the
|
||||
basic auth username and password if they're present in *url*.
|
||||
|
||||
@@ -105,8 +98,7 @@ def _strip_basic_auth(url):
|
||||
return urlunsplit(frags)
|
||||
|
||||
|
||||
def _read_from_url(url, config=None):
|
||||
# type: (str, Config) -> IO
|
||||
def _read_from_url(url: str, config: Config = None) -> IO:
|
||||
"""Reads data from *url* with an HTTP *GET*.
|
||||
|
||||
This function supports fetching from resources which use basic HTTP auth as
|
||||
@@ -131,8 +123,7 @@ def _read_from_url(url, config=None):
|
||||
return r.raw
|
||||
|
||||
|
||||
def _get_safe_url(url):
|
||||
# type: (str) -> str
|
||||
def _get_safe_url(url: str) -> str:
|
||||
"""Gets version of *url* with basic auth passwords obscured. This function
|
||||
returns results suitable for printing and logging.
|
||||
|
||||
@@ -157,8 +148,7 @@ def _get_safe_url(url):
|
||||
return urlunsplit(frags)
|
||||
|
||||
|
||||
def fetch_inventory(app, uri, inv):
|
||||
# type: (Sphinx, str, Any) -> Any
|
||||
def fetch_inventory(app: Sphinx, uri: str, inv: Any) -> Any:
|
||||
"""Fetch, parse and return an intersphinx inventory file."""
|
||||
# both *uri* (base URI of the links to generate) and *inv* (actual
|
||||
# location of the inventory file) can be local or remote URIs
|
||||
@@ -197,8 +187,7 @@ def fetch_inventory(app, uri, inv):
|
||||
return invdata
|
||||
|
||||
|
||||
def load_mappings(app):
|
||||
# type: (Sphinx) -> None
|
||||
def load_mappings(app: Sphinx) -> None:
|
||||
"""Load all intersphinx mappings into the environment."""
|
||||
now = int(time.time())
|
||||
cache_time = now - app.config.intersphinx_cache_limit * 86400
|
||||
@@ -258,8 +247,8 @@ def load_mappings(app):
|
||||
inventories.main_inventory.setdefault(type, {}).update(objects)
|
||||
|
||||
|
||||
def missing_reference(app, env, node, contnode):
|
||||
# type: (Sphinx, BuildEnvironment, nodes.Element, nodes.TextElement) -> nodes.reference
|
||||
def missing_reference(app: Sphinx, env: BuildEnvironment, node: Element, contnode: TextElement
|
||||
) -> nodes.reference:
|
||||
"""Attempt to resolve a missing reference via intersphinx references."""
|
||||
target = node['reftarget']
|
||||
inventories = InventoryAdapter(env)
|
||||
@@ -336,8 +325,7 @@ def missing_reference(app, env, node, contnode):
|
||||
return None
|
||||
|
||||
|
||||
def normalize_intersphinx_mapping(app, config):
|
||||
# type: (Sphinx, Config) -> None
|
||||
def normalize_intersphinx_mapping(app: Sphinx, config: Config) -> None:
|
||||
for key, value in config.intersphinx_mapping.copy().items():
|
||||
try:
|
||||
if isinstance(value, (list, tuple)):
|
||||
@@ -361,8 +349,7 @@ def normalize_intersphinx_mapping(app, config):
|
||||
config.intersphinx_mapping.pop(key)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_config_value('intersphinx_mapping', {}, True)
|
||||
app.add_config_value('intersphinx_cache_limit', 5, False)
|
||||
app.add_config_value('intersphinx_timeout', None, False)
|
||||
@@ -376,8 +363,7 @@ def setup(app):
|
||||
}
|
||||
|
||||
|
||||
def inspect_main(argv):
|
||||
# type: (List[str]) -> None
|
||||
def inspect_main(argv: List[str]) -> None:
|
||||
"""Debug functionality to print out an inventory"""
|
||||
if len(argv) < 1:
|
||||
print("Print out an inventory file.\n"
|
||||
@@ -393,8 +379,7 @@ def inspect_main(argv):
|
||||
srcdir = ''
|
||||
config = MockConfig()
|
||||
|
||||
def warn(self, msg):
|
||||
# type: (str) -> None
|
||||
def warn(self, msg: str) -> None:
|
||||
print(msg, file=sys.stderr)
|
||||
|
||||
try:
|
||||
|
||||
@@ -8,25 +8,23 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from typing import Any, Dict, Set
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Node
|
||||
|
||||
import sphinx
|
||||
from sphinx import addnodes
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.errors import SphinxError
|
||||
from sphinx.locale import _
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict, Set # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
|
||||
|
||||
class LinkcodeError(SphinxError):
|
||||
category = "linkcode error"
|
||||
|
||||
|
||||
def doctree_read(app, doctree):
|
||||
# type: (Sphinx, nodes.Node) -> None
|
||||
def doctree_read(app: Sphinx, doctree: Node) -> None:
|
||||
env = app.builder.env
|
||||
|
||||
resolve_target = getattr(env.config, 'linkcode_resolve', None)
|
||||
@@ -75,8 +73,7 @@ def doctree_read(app, doctree):
|
||||
signode += onlynode
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.connect('doctree-read', doctree_read)
|
||||
app.add_config_value('linkcode_resolve', None, '')
|
||||
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
|
||||
+11
-15
@@ -9,26 +9,24 @@
|
||||
"""
|
||||
|
||||
import warnings
|
||||
from typing import Callable, List, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.nodes import Element, Node
|
||||
from docutils.parsers.rst.roles import math_role as math_role_base
|
||||
|
||||
from sphinx.addnodes import math, math_block as displaymath # NOQA # to keep compatibility
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders.latex.nodes import math_reference as eqref # NOQA # to keep compatibility
|
||||
from sphinx.deprecation import RemovedInSphinx30Warning
|
||||
from sphinx.directives.patches import MathDirective as MathDirectiveBase
|
||||
from sphinx.domains.math import MathDomain # NOQA # to keep compatibility
|
||||
from sphinx.domains.math import MathReferenceRole as EqXRefRole # NOQA # to keep compatibility
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Callable, Tuple # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.writers.html import HTMLTranslator # NOQA
|
||||
from sphinx.writers.html import HTMLTranslator
|
||||
|
||||
|
||||
class MathDirective(MathDirectiveBase):
|
||||
def run(self):
|
||||
def run(self) -> List[Node]:
|
||||
warnings.warn('sphinx.ext.mathbase.MathDirective is moved to '
|
||||
'sphinx.directives.patches package.',
|
||||
RemovedInSphinx30Warning, stacklevel=2)
|
||||
@@ -42,8 +40,7 @@ def math_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
|
||||
return math_role_base(role, rawtext, text, lineno, inliner, options, content)
|
||||
|
||||
|
||||
def get_node_equation_number(writer, node):
|
||||
# type: (HTMLTranslator, nodes.math_block) -> str
|
||||
def get_node_equation_number(writer: HTMLTranslator, node: nodes.math_block) -> str:
|
||||
warnings.warn('sphinx.ext.mathbase.get_node_equation_number() is moved to '
|
||||
'sphinx.util.math package.',
|
||||
RemovedInSphinx30Warning, stacklevel=2)
|
||||
@@ -51,8 +48,7 @@ def get_node_equation_number(writer, node):
|
||||
return get_node_equation_number(writer, node)
|
||||
|
||||
|
||||
def wrap_displaymath(text, label, numbering):
|
||||
# type: (str, str, bool) -> str
|
||||
def wrap_displaymath(text: str, label: str, numbering: bool) -> str:
|
||||
warnings.warn('sphinx.ext.mathbase.wrap_displaymath() is moved to '
|
||||
'sphinx.util.math package.',
|
||||
RemovedInSphinx30Warning, stacklevel=2)
|
||||
@@ -60,8 +56,7 @@ def wrap_displaymath(text, label, numbering):
|
||||
return wrap_displaymath(text, label, numbering)
|
||||
|
||||
|
||||
def is_in_section_title(node):
|
||||
# type: (nodes.Element) -> bool
|
||||
def is_in_section_title(node: Element) -> bool:
|
||||
"""Determine whether the node is in a section title"""
|
||||
from sphinx.util.nodes import traverse_parent
|
||||
|
||||
@@ -75,8 +70,9 @@ def is_in_section_title(node):
|
||||
return False
|
||||
|
||||
|
||||
def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
|
||||
# type: (Sphinx, Tuple[Callable, Callable], Tuple[Callable, Callable]) -> None
|
||||
def setup_math(app: Sphinx,
|
||||
htmlinlinevisitors: Tuple[Callable, Callable],
|
||||
htmldisplayvisitors: Tuple[Callable, Callable]) -> None:
|
||||
warnings.warn('setup_math() is deprecated. '
|
||||
'Please use app.add_html_math_renderer() instead.',
|
||||
RemovedInSphinx30Warning, stacklevel=2)
|
||||
|
||||
+8
-15
@@ -11,27 +11,23 @@
|
||||
"""
|
||||
|
||||
import json
|
||||
from typing import Any, Dict
|
||||
from typing import cast
|
||||
|
||||
from docutils import nodes
|
||||
|
||||
import sphinx
|
||||
from sphinx.application import Sphinx
|
||||
from sphinx.builders.html import StandaloneHTMLBuilder
|
||||
from sphinx.domains.math import MathDomain
|
||||
from sphinx.environment import BuildEnvironment
|
||||
from sphinx.errors import ExtensionError
|
||||
from sphinx.locale import _
|
||||
from sphinx.util.math import get_node_equation_number
|
||||
|
||||
if False:
|
||||
# For type annotation
|
||||
from typing import Any, Dict # NOQA
|
||||
from sphinx.application import Sphinx # NOQA
|
||||
from sphinx.environment import BuildEnvironment # NOQA
|
||||
from sphinx.writers.html import HTMLTranslator # NOQA
|
||||
from sphinx.writers.html import HTMLTranslator
|
||||
|
||||
|
||||
def html_visit_math(self, node):
|
||||
# type: (HTMLTranslator, nodes.math) -> None
|
||||
def html_visit_math(self: HTMLTranslator, node: nodes.math) -> None:
|
||||
self.body.append(self.starttag(node, 'span', '', CLASS='math notranslate nohighlight'))
|
||||
self.body.append(self.builder.config.mathjax_inline[0] +
|
||||
self.encode(node.astext()) +
|
||||
@@ -39,8 +35,7 @@ def html_visit_math(self, node):
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
||||
def html_visit_displaymath(self, node):
|
||||
# type: (HTMLTranslator, nodes.math_block) -> None
|
||||
def html_visit_displaymath(self: HTMLTranslator, node: nodes.math_block) -> None:
|
||||
self.body.append(self.starttag(node, 'div', CLASS='math notranslate nohighlight'))
|
||||
if node['nowrap']:
|
||||
self.body.append(self.encode(node.astext()))
|
||||
@@ -72,8 +67,7 @@ def html_visit_displaymath(self, node):
|
||||
raise nodes.SkipNode
|
||||
|
||||
|
||||
def install_mathjax(app, env):
|
||||
# type: (Sphinx, BuildEnvironment) -> None
|
||||
def install_mathjax(app: Sphinx, env: BuildEnvironment) -> None:
|
||||
if app.builder.format != 'html' or app.builder.math_renderer_name != 'mathjax': # type: ignore # NOQA
|
||||
return
|
||||
if not app.config.mathjax_path:
|
||||
@@ -94,8 +88,7 @@ def install_mathjax(app, env):
|
||||
builder.add_js_file(None, type="text/x-mathjax-config", body=body)
|
||||
|
||||
|
||||
def setup(app):
|
||||
# type: (Sphinx) -> Dict[str, Any]
|
||||
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||
app.add_html_math_renderer('mathjax',
|
||||
(html_visit_math, None),
|
||||
(html_visit_displaymath, None))
|
||||
|
||||
Reference in new issue
Block a user