Merge branch '2.0' into refactor_latex

This commit is contained in:
Takeshi KOMIYA 2020-01-31 01:18:57 +09:00
commit 52afc79e1f
305 changed files with 2060 additions and 877 deletions

31
CHANGES
View File

@ -11,13 +11,18 @@ Deprecated
----------
* The ``decode`` argument of ``sphinx.pycode.ModuleAnalyzer()``
* ``sphinx.directives.other.Index``
* ``sphinx.environment.temp_data['gloss_entries']``
* ``sphinx.environment.BuildEnvironment.indexentries``
* ``sphinx.environment.collectors.indexentries.IndexEntriesCollector``
* ``sphinx.io.FiletypeNotFoundError``
* ``sphinx.io.get_filetype()``
* ``sphinx.pycode.ModuleAnalyzer.encoding``
* ``sphinx.roles.Index``
* ``sphinx.util.detect_encoding()``
* ``sphinx.util.get_module_source()``
* ``sphinx.util.inspect.Signature``
* ``sphinx.util.inspect.safe_getmembers()``
* ``sphinx.writers.latex.LaTeXTranslator.settings.author``
* ``sphinx.writers.latex.LaTeXTranslator.settings.contentsname``
* ``sphinx.writers.latex.LaTeXTranslator.settings.docclass``
@ -31,6 +36,23 @@ Features added
* #6446: duration: Add ``sphinx.ext.durations`` to inspect which documents slow
down the build
* #6837: LaTeX: Support a nested table
* #6966: graphviz: Support ``:class:`` option
* #6696: html: ``:scale:`` option of image/figure directive not working for SVG
images (imagesize-1.2.0 or above is required)
* #6994: imgconverter: Support illustrator file (.ai) to .png conversion
* autodoc: Support Positional-Only Argument separator (PEP-570 compliant)
* #2755: autodoc: Add new event: :event:`autodoc-before-process-signature`
* #2755: autodoc: Support type_comment style (ex. ``# type: (str) -> str``)
annotation (python3.8+ or `typed_ast <https://github.com/python/typed_ast>`_
is required)
* #7051: autodoc: Support instance variables without defaults (PEP-526)
* #6418: autodoc: Add a new extension ``sphinx.ext.autodoc.typehints``. It shows
typehints as object description if ``autodoc_typehints = "description"`` set.
This is an experimental extension and it will be integrated into autodoc core
in Sphinx-3.0
* SphinxTranslator now calls visitor/departure method for super node class if
visitor/departure method for original node class not found
* #6418: Add new event: :event:`object-description-transform`
Bugs fixed
----------
@ -38,6 +60,13 @@ Bugs fixed
* #6925: html: Remove redundant type="text/javascript" from <script> elements
* #6906, #6907: autodoc: failed to read the source codes encoeded in cp1251
* #6961: latex: warning for babel shown twice
* #6559: Wrong node-ids are generated in glossary directive
* #6986: apidoc: misdetects module name for .so file inside module
* #6999: napoleon: fails to parse tilde in :exc: role
* #7019: gettext: Absolute path used in message catalogs
* #7023: autodoc: nested partial functions are not listed
* #7023: autodoc: partial functions imported from other modules are listed as
module members without :impoprted-members: option
Testing
--------
@ -1126,6 +1155,8 @@ Features added
* #5029: autosummary: expose ``inherited_members`` to template
* #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
for mathjax
* #726, #969: mathjax: Add :confval:`mathjax_config` to give in-line
configurations for mathjax
* #4362: latex: Don't overwrite .tex file if document not changed
* #1431: latex: Add alphanumeric enumerated list support
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True``

View File

@ -218,6 +218,14 @@ connect handlers to the events. Example:
.. versionadded:: 0.5
.. event:: object-description-transform (app, domain, objtype, contentnode)
Emitted when an object description directive has run. The *domain* and
*objtype* arguments are strings indicating object description of the object.
And *contentnode* is a content for the object. It can be modified in-place.
.. versionadded:: 2.4
.. event:: doctree-read (app, doctree)
Emitted when a doctree has been parsed and read by the environment, and is

View File

@ -31,6 +31,16 @@ The following is a list of deprecated interfaces.
- 4.0
- N/A
* - ``sphinx.directives.other.Index``
- 2.4
- 4.0
- ``sphinx.domains.index.IndexDirective``
* - ``sphinx.environment.temp_data['gloss_entries']``
- 2.4
- 4.0
- ``documents.nameids``
* - ``sphinx.environment.BuildEnvironment.indexentries``
- 2.4
- 4.0
@ -51,21 +61,37 @@ The following is a list of deprecated interfaces.
- 4.0
- ``sphinx.util.get_filetype()``
* - ``sphinx.util.get_module_source()``
- 2.4
- 4.0
- N/A
* - ``sphinx.pycode.ModuleAnalyzer.encoding``
- 2.4
- 4.0
- N/A
* - ``sphinx.roles.Index``
- 2.4
- 4.0
- ``sphinx.domains.index.IndexRole``
* - ``sphinx.util.detect_encoding()``
- 2.4
- 4.0
- ``tokenize.detect_encoding()``
* - ``sphinx.util.get_module_source()``
- 2.4
- 4.0
- N/A
* - ``sphinx.util.inspect.Signature``
- 2.4
- 4.0
- ``sphinx.util.inspect.signature`` and
``sphinx.util.inspect.stringify_signature()``
* - ``sphinx.util.inspect.safe_getmembers()``
- 2.4
- 4.0
- ``inspect.getmembers()``
* - ``sphinx.writers.latex.LaTeXTranslator.settings.author``
- 2.4
- 4.0

View File

@ -494,6 +494,17 @@ autodoc provides the following additional events:
auto directive
:param lines: the lines of the docstring, see above
.. event:: autodoc-before-process-signature (app, obj, bound_method)
.. versionadded:: 2.4
Emitted before autodoc formats a signature for an object. The event handler
can modify an object to change its signature.
:param app: the Sphinx application object
:param obj: the object itself
:param bound_method: a boolean indicates an object is bound method or not
.. event:: autodoc-process-signature (app, what, name, obj, options, signature, return_annotation)
.. versionadded:: 0.5
@ -556,3 +567,24 @@ member should be included in the documentation by using the following event:
``inherited_members``, ``undoc_members``, ``show_inheritance`` and
``noindex`` that are true if the flag option of same name was given to the
auto directive
Generating documents from type annotations
------------------------------------------
As an experimental feature, autodoc provides ``sphinx.ext.autodoc.typehints`` as
an additional extension. It extends autodoc itself to generate function document
from its type annotations.
To enable the feature, please add ``sphinx.ext.autodoc.typehints`` to list of
extensions and set `'description'` to :confval:`autodoc_typehints`:
.. code-block:: python
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autodoc.typehints']
autodoc_typehints = 'description'
.. versionadded:: 2.4
Added as an experimental feature. This will be integrated into autodoc core
in Sphinx-3.0.

View File

@ -82,6 +82,13 @@ It adds these directives:
.. versionadded:: 1.6
.. rst:directive:option:: class: class names
:type: a list of class names separeted by spaces
The class name of the graph.
.. versionadded:: 2.4
.. rst:directive:: graph
@ -131,6 +138,13 @@ It adds these directives:
.. versionadded:: 1.6
.. rst:directive:option:: class: class names
:type: a list of class names separeted by spaces
The class name of the graph.
.. versionadded:: 2.4
.. rst:directive:: digraph
@ -176,6 +190,13 @@ It adds these directives:
.. versionadded:: 1.6
.. rst:directive:option:: class: class names
:type: a list of class names separeted by spaces
The class name of the graph.
.. versionadded:: 2.4
There are also these config values:

View File

@ -191,6 +191,8 @@ Sphinx but is set to automatically include it from a third-party site.
The default is empty (``{}``).
.. versionadded:: 1.8
.. confval:: mathjax_config
The inline configuration options for mathjax. The value is used as a
@ -206,6 +208,8 @@ Sphinx but is set to automatically include it from a third-party site.
The default is empty (not configured).
.. versionadded:: 1.8
.. _Using in-line configuration options: https://docs.mathjax.org/en/latest/configuration.html#using-in-line-configuration-options
:mod:`sphinx.ext.jsmath` -- Render math via JavaScript

View File

@ -189,8 +189,8 @@ Referencing downloadable files
When you use this role, the referenced file is automatically marked for
inclusion in the output when building (obviously, for HTML output only).
All downloadable files are put into the ``_downloads`` subdirectory of the
output directory; duplicate filenames are handled.
All downloadable files are put into a ``_downloads/<unique hash>/``
subdirectory of the output directory; duplicate filenames are handled.
An example::

View File

@ -40,6 +40,7 @@ paths =
.
[mypy]
disallow_incomplete_defs = True
show_column_numbers = True
show_error_context = True
ignore_missing_imports = True

View File

@ -42,7 +42,7 @@ extras_require = {
'sphinxcontrib-websupport',
],
'test': [
'pytest',
'pytest < 5.3.3',
'pytest-cov',
'html5lib',
'flake8>=3.5.0',

View File

@ -4,7 +4,7 @@
The Sphinx documentation toolchain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The Sphinx documentation toolchain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Additional docutils nodes.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -12,6 +12,7 @@ import warnings
from typing import Any, Dict, List, Sequence
from docutils import nodes
from docutils.nodes import Node
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
@ -358,7 +359,8 @@ class abbreviation(nodes.abbreviation):
.. deprecated:: 2.0
"""
def __init__(self, rawsource: str = '', text: str = '', *children, **attributes) -> None:
def __init__(self, rawsource: str = '', text: str = '',
*children: Node, **attributes: Any) -> None:
warnings.warn("abbrevition node for Sphinx was replaced by docutils'.",
RemovedInSphinx40Warning, stacklevel=2)

View File

@ -6,7 +6,7 @@
Gracefully adapted from the TextPress system by Armin.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -438,7 +438,7 @@ class Sphinx:
logger.debug('[app] disconnecting event: [id=%s]', listener_id)
self.events.disconnect(listener_id)
def emit(self, event: str, *args) -> List:
def emit(self, event: str, *args: Any) -> List:
"""Emit *event* and pass *arguments* to the callback functions.
Return the return values of all callbacks as a list. Do not emit core
@ -446,7 +446,7 @@ class Sphinx:
"""
return self.events.emit(event, *args)
def emit_firstresult(self, event: str, *args) -> Any:
def emit_firstresult(self, event: str, *args: Any) -> Any:
"""Emit *event* and pass *arguments* to the callback functions.
Return the result of the first callback that doesn't return ``None``.
@ -524,7 +524,8 @@ class Sphinx:
"""
self.registry.add_translator(name, translator_class, override=override)
def add_node(self, node: "Type[Element]", override: bool = False, **kwds) -> None:
def add_node(self, node: "Type[Element]", override: bool = False,
**kwargs: Tuple[Callable, Callable]) -> None:
"""Register a Docutils node class.
This is necessary for Docutils internals. It may also be used in the
@ -554,17 +555,17 @@ class Sphinx:
.. versionchanged:: 0.5
Added the support for keyword arguments giving visit functions.
"""
logger.debug('[app] adding node: %r', (node, kwds))
logger.debug('[app] adding node: %r', (node, kwargs))
if not override and docutils.is_node_registered(node):
logger.warning(__('node class %r is already registered, '
'its visitors will be overridden'),
node.__name__, type='app', subtype='add_node')
docutils.register_node(node)
self.registry.add_translation_handlers(node, **kwds)
self.registry.add_translation_handlers(node, **kwargs)
def add_enumerable_node(self, node: "Type[Element]", figtype: str,
title_getter: TitleGetter = None, override: bool = False,
**kwds) -> None:
**kwargs: Tuple[Callable, Callable]) -> None:
"""Register a Docutils node class as a numfig target.
Sphinx numbers the node automatically. And then the users can refer it
@ -589,7 +590,7 @@ class Sphinx:
.. versionadded:: 1.4
"""
self.registry.add_enumerable_node(node, figtype, title_getter, override=override)
self.add_node(node, override=override, **kwds)
self.add_node(node, override=override, **kwargs)
@property
def enumerable_nodes(self) -> Dict["Type[Node]", Tuple[str, TitleGetter]]:
@ -600,7 +601,7 @@ class Sphinx:
def add_directive(self, name: str, obj: Any, content: bool = None,
arguments: Tuple[int, int, bool] = None, override: bool = False,
**options) -> None:
**options: Any) -> None:
"""Register a Docutils directive.
*name* must be the prospective directive name. There are two possible
@ -729,7 +730,7 @@ class Sphinx:
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:
override: bool = False, **option_spec: Any) -> None:
"""Register a Docutils directive in a domain.
Like :meth:`add_directive`, but the directive is added to the domain
@ -1099,7 +1100,7 @@ class Sphinx:
"""
self.registry.add_source_suffix(suffix, filetype, override=override)
def add_source_parser(self, *args, **kwargs) -> None:
def add_source_parser(self, *args: Any, **kwargs: Any) -> None:
"""Register a parser class.
.. versionadded:: 1.4

View File

@ -4,7 +4,7 @@
Builder superclass for all builders.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -118,11 +118,11 @@ class Builder:
self.env.set_versioning_method(self.versioning_method,
self.versioning_compare)
def get_translator_class(self, *args) -> "Type[nodes.NodeVisitor]":
def get_translator_class(self, *args: Any) -> "Type[nodes.NodeVisitor]":
"""Return a class of translator."""
return self.app.registry.get_translator_class(self)
def create_translator(self, *args) -> nodes.NodeVisitor:
def create_translator(self, *args: Any) -> nodes.NodeVisitor:
"""Return an instance of translator.
This method returns an instance of ``default_translator_class`` by default.

View File

@ -4,7 +4,7 @@
Base class of epub2/epub3 builders.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Build Apple help books.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Changelog builder.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -50,7 +50,7 @@ class ChangesBuilder(Builder):
'deprecated': 'deprecated',
}
def write(self, *ignored) -> None:
def write(self, *ignored: Any) -> None:
version = self.config.version
domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]

View File

@ -6,7 +6,7 @@
.. _Devhelp: https://wiki.gnome.org/Apps/Devhelp
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Directory HTML builders.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The MessageCatalogBuilder class.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -30,7 +30,7 @@ from sphinx.util import split_index_msg, logging, status_iterator
from sphinx.util.console import bold # type: ignore
from sphinx.util.i18n import CatalogInfo, docname_to_domain
from sphinx.util.nodes import extract_messages, traverse_translatable_index
from sphinx.util.osutil import ensuredir, canon_path
from sphinx.util.osutil import ensuredir, canon_path, relpath
from sphinx.util.tags import Tags
from sphinx.util.template import SphinxRenderer
@ -108,7 +108,8 @@ class MsgOrigin:
class GettextRenderer(SphinxRenderer):
def __init__(self, template_path: str = None) -> None:
def __init__(self, template_path: str = None, outdir: str = None) -> None:
self.outdir = outdir
if template_path is None:
template_path = path.join(package_dir, 'templates', 'gettext')
super().__init__(template_path)
@ -122,6 +123,13 @@ class GettextRenderer(SphinxRenderer):
self.env.filters['e'] = escape
self.env.filters['escape'] = escape
def render(self, filename: str, context: Dict) -> str:
def _relpath(s: str) -> str:
return canon_path(relpath(s, self.outdir))
context['relpath'] = _relpath
return super().render(filename, context)
class I18nTags(Tags):
"""Dummy tags module for I18nBuilder.
@ -198,8 +206,8 @@ if source_date_epoch is not None:
class LocalTimeZone(tzinfo):
def __init__(self, *args, **kw) -> None:
super().__init__(*args, **kw) # type: ignore
def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kwargs) # type: ignore
self.tzdelta = tzdelta
def utcoffset(self, dt: datetime) -> timedelta:
@ -212,7 +220,7 @@ class LocalTimeZone(tzinfo):
ltz = LocalTimeZone()
def should_write(filepath: str, new_content: str):
def should_write(filepath: str, new_content: str) -> bool:
if not path.exists(filepath):
return True
try:
@ -297,7 +305,7 @@ class MessageCatalogBuilder(I18nBuilder):
ensuredir(path.join(self.outdir, path.dirname(textdomain)))
context['messages'] = list(catalog)
content = GettextRenderer().render('message.pot_t', context)
content = GettextRenderer(outdir=self.outdir).render('message.pot_t', context)
pofn = path.join(self.outdir, textdomain + '.pot')
if should_write(pofn, content):

View File

@ -4,7 +4,7 @@
Several HTML builders.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -887,11 +887,11 @@ class StandaloneHTMLBuilder(Builder):
indexer_name, indexer_name),
RemovedInSphinx40Warning)
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
if 'includehidden' not in kwds:
kwds['includehidden'] = False
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
if 'includehidden' not in kwargs:
kwargs['includehidden'] = False
return self.render_partial(TocTree(self.env).get_toctree_for(
docname, self, collapse, **kwds))['fragment']
docname, self, collapse, **kwargs))['fragment']
def get_outfilename(self, pagename: str) -> str:
return path.join(self.outdir, os_path(pagename) + self.out_suffix)
@ -1000,7 +1000,7 @@ class StandaloneHTMLBuilder(Builder):
return False
ctx['hasdoc'] = hasdoc
def warn(*args, **kwargs) -> str:
def warn(*args: Any, **kwargs: Any) -> str:
"""Simple warn() wrapper for themes."""
warnings.warn('The template function warn() was deprecated. '
'Use warning() instead.',
@ -1009,7 +1009,7 @@ class StandaloneHTMLBuilder(Builder):
return '' # return empty string
ctx['warn'] = warn
ctx['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw)
ctx['toctree'] = lambda **kwargs: self._get_local_toctree(pagename, **kwargs)
self.add_sidebars(pagename, ctx)
ctx.update(addctx)

View File

@ -5,7 +5,7 @@
Build HTML help support files.
Parts adapted from Python's Doc/tools/prechm.py.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
LaTeX builder.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -137,7 +137,7 @@ class LaTeXBuilder(Builder):
def get_target_uri(self, docname: str, typ: str = None) -> str:
if docname not in self.docnames:
raise NoUri
raise NoUri(docname, typ)
else:
return '%' + docname
@ -215,7 +215,7 @@ class LaTeXBuilder(Builder):
'[2016/05/29 stylesheet for highlighting with pygments]\n\n')
f.write(highlighter.get_stylesheet())
def write(self, *ignored) -> None:
def write(self, *ignored: Any) -> None:
docwriter = LaTeXWriter(self)
docsettings = OptionParser(
defaults=self.env.settings,

View File

@ -4,7 +4,7 @@
Additional nodes for LaTeX writer.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Transforms for LaTeX builder.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -32,7 +32,7 @@ class FootnoteDocnameUpdater(SphinxTransform):
default_priority = 700
TARGET_NODES = (nodes.footnote, nodes.footnote_reference)
def apply(self, **kwargs) -> None:
def apply(self, **kwargs: Any) -> None:
matcher = NodeMatcher(*self.TARGET_NODES)
for node in self.document.traverse(matcher): # type: nodes.Element
node['docname'] = self.env.docname
@ -51,7 +51,7 @@ class ShowUrlsTransform(SphinxPostTransform):
# references are expanded to footnotes (or not)
expanded = False
def run(self, **kwargs) -> None:
def run(self, **kwargs: Any) -> None:
try:
# replace id_prefix temporarily
settings = self.document.settings # type: Any
@ -338,7 +338,7 @@ class LaTeXFootnoteTransform(SphinxPostTransform):
default_priority = 600
builders = ('latex',)
def run(self, **kwargs) -> None:
def run(self, **kwargs: Any) -> None:
footnotes = list(self.document.traverse(nodes.footnote))
for node in footnotes:
node.parent.remove(node)
@ -490,7 +490,7 @@ class BibliographyTransform(SphinxPostTransform):
default_priority = 750
builders = ('latex',)
def run(self, **kwargs) -> None:
def run(self, **kwargs: Any) -> None:
citations = thebibliography()
for node in self.document.traverse(nodes.citation):
node.parent.remove(node)
@ -509,7 +509,7 @@ class CitationReferenceTransform(SphinxPostTransform):
default_priority = 5 # before ReferencesResolver
builders = ('latex',)
def run(self, **kwargs) -> None:
def run(self, **kwargs: Any) -> None:
domain = cast(CitationDomain, self.env.get_domain('citation'))
matcher = NodeMatcher(addnodes.pending_xref, refdomain='citation', reftype='ref')
for node in self.document.traverse(matcher): # type: addnodes.pending_xref
@ -529,7 +529,7 @@ class MathReferenceTransform(SphinxPostTransform):
default_priority = 5 # before ReferencesResolver
builders = ('latex',)
def run(self, **kwargs) -> None:
def run(self, **kwargs: Any) -> None:
equations = self.env.get_domain('math').data['objects']
for node in self.document.traverse(addnodes.pending_xref):
if node['refdomain'] == 'math' and node['reftype'] in ('eq', 'numref'):
@ -544,7 +544,7 @@ class LiteralBlockTransform(SphinxPostTransform):
default_priority = 400
builders = ('latex',)
def run(self, **kwargs) -> None:
def run(self, **kwargs: Any) -> None:
matcher = NodeMatcher(nodes.container, literal_block=True)
for node in self.document.traverse(matcher): # type: nodes.container
newnode = captioned_literal_block('', *node.children, **node.attributes)
@ -556,7 +556,7 @@ class DocumentTargetTransform(SphinxPostTransform):
default_priority = 400
builders = ('latex',)
def run(self, **kwargs) -> None:
def run(self, **kwargs: Any) -> None:
for node in self.document.traverse(addnodes.start_of_file):
section = node.next_node(nodes.section)
if section:

View File

@ -4,7 +4,7 @@
The CheckExternalLinksBuilder class.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Manual pages builder.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -53,10 +53,10 @@ class ManualPageBuilder(Builder):
def get_target_uri(self, docname: str, typ: str = None) -> str:
if typ == 'token':
return ''
raise NoUri
raise NoUri(docname, typ)
@progress_message(__('writing'))
def write(self, *ignored) -> None:
def write(self, *ignored: Any) -> None:
docwriter = ManualPageWriter(self)
docsettings = OptionParser(
defaults=self.env.settings,

View File

@ -4,7 +4,7 @@
Build input files for the Qt collection generator.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Single HTML builders.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -67,10 +67,10 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
if hashindex >= 0:
refnode['refuri'] = fname + refuri[hashindex:]
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwds) -> str:
if 'includehidden' not in kwds:
kwds['includehidden'] = False
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwds)
def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str:
if 'includehidden' not in kwargs:
kwargs['includehidden'] = False
toctree = TocTree(self.env).get_toctree_for(docname, self, collapse, **kwargs)
if toctree is not None:
self.fix_refuris(toctree)
return self.render_partial(toctree)['fragment']
@ -149,7 +149,7 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
'display_toc': display_toc,
}
def write(self, *ignored) -> None:
def write(self, *ignored: Any) -> None:
docnames = self.env.all_docs
with progress_message(__('preparing documents')):

View File

@ -4,7 +4,7 @@
Texinfo builder.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -63,7 +63,7 @@ class TexinfoBuilder(Builder):
def get_target_uri(self, docname: str, typ: str = None) -> str:
if docname not in self.docnames:
raise NoUri
raise NoUri(docname, typ)
else:
return '%' + docname
@ -90,7 +90,7 @@ class TexinfoBuilder(Builder):
docname = docname[:-5]
self.titles.append((docname, entry[2]))
def write(self, *ignored) -> None:
def write(self, *ignored: Any) -> None:
self.init_document_data()
for entry in self.document_data:
docname, targetname, title, author = entry[:4]

View File

@ -4,7 +4,7 @@
Plain-text Sphinx builder.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Docutils-native XML and pseudo-XML builders.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,6 +4,6 @@
Modules for command line executables.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Build documentation from a provided source.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -10,7 +10,7 @@
This is in its own module so that importing it is fast. It should not
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Quickly setup documentation source to work with Sphinx.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
sphinx-build command-line handling.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Build configuration file handling.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -154,7 +154,7 @@ class Config:
'env', []),
} # type: Dict[str, Tuple]
def __init__(self, *args) -> None:
def __init__(self, *args: Any) -> None:
if len(args) == 4:
# old style arguments: (dirname, filename, overrides, tags)
warnings.warn('The argument of Config() class has been changed. '

View File

@ -4,7 +4,7 @@
Sphinx deprecation classes and utilities.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Handlers for additional ReST directives.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -193,6 +193,8 @@ class ObjectDescription(SphinxDirective):
self.env.temp_data['object'] = self.names[0]
self.before_content()
self.state.nested_parse(self.content, self.content_offset, contentnode)
self.env.app.emit('object-description-transform',
self.domain, self.objtype, contentnode)
DocFieldTransformer(self).transform_all(contentnode)
self.env.temp_data['object'] = None
self.after_content()
@ -253,12 +255,13 @@ from sphinx.directives.code import ( # noqa
Highlight, CodeBlock, LiteralInclude
)
from sphinx.directives.other import ( # noqa
TocTree, Author, Index, VersionChange, SeeAlso,
TocTree, Author, VersionChange, SeeAlso,
TabularColumns, Centered, Acks, HList, Only, Include, Class
)
from sphinx.directives.patches import ( # noqa
Figure, Meta
)
from sphinx.domains.index import IndexDirective # noqa
deprecated_alias('sphinx.directives',
{
@ -267,7 +270,7 @@ deprecated_alias('sphinx.directives',
'LiteralInclude': LiteralInclude,
'TocTree': TocTree,
'Author': Author,
'Index': Index,
'Index': IndexDirective,
'VersionChange': VersionChange,
'SeeAlso': SeeAlso,
'TabularColumns': TabularColumns,
@ -294,6 +297,8 @@ def setup(app: "Sphinx") -> Dict[str, Any]:
# new, more consistent, name
directives.register_directive('object', ObjectDescription)
app.add_event('object-description-transform')
return {
'version': 'builtin',
'parallel_read_safe': True,

View File

@ -2,7 +2,7 @@
sphinx.directives.code
~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -2,7 +2,7 @@
sphinx.directives.other
~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -18,12 +18,13 @@ from docutils.parsers.rst.directives.misc import Class
from docutils.parsers.rst.directives.misc import Include as BaseInclude
from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
from sphinx.locale import _
from sphinx.util import url_re, docname_join
from sphinx.util.docutils import SphinxDirective
from sphinx.util.matching import Matcher, patfilter
from sphinx.util.nodes import explicit_title_re, process_index_entry
from sphinx.util.nodes import explicit_title_re
if False:
# For type annotation
@ -182,30 +183,6 @@ class Author(SphinxDirective):
return ret
class Index(SphinxDirective):
"""
Directive to add entries to the index.
"""
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {} # type: Dict
def run(self) -> List[Node]:
arguments = self.arguments[0].split('\n')
targetid = 'index-%s' % self.env.new_serialno('index')
targetnode = nodes.target('', '', ids=[targetid])
self.state.document.note_explicit_target(targetnode)
indexnode = addnodes.index()
indexnode['entries'] = []
indexnode['inline'] = False
self.set_source_info(indexnode)
for entry in arguments:
indexnode['entries'].extend(process_index_entry(entry, targetid))
return [indexnode, targetnode]
class SeeAlso(BaseAdmonition):
"""
An admonition mentioning things to look at as reference.
@ -383,12 +360,21 @@ class Include(BaseInclude, SphinxDirective):
return super().run()
# Import old modules here for compatibility
from sphinx.domains.index import IndexDirective # NOQA
deprecated_alias('sphinx.directives.other',
{
'Index': IndexDirective,
},
RemovedInSphinx40Warning)
def setup(app: "Sphinx") -> Dict[str, Any]:
directives.register_directive('toctree', TocTree)
directives.register_directive('sectionauthor', Author)
directives.register_directive('moduleauthor', Author)
directives.register_directive('codeauthor', Author)
directives.register_directive('index', Index)
directives.register_directive('seealso', SeeAlso)
directives.register_directive('tabularcolumns', TabularColumns)
directives.register_directive('centered', Centered)

View File

@ -2,7 +2,7 @@
sphinx.directives.patches
~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Support for domains, which are groupings of description directives
and roles describing e.g. constructs of one programming language.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -48,7 +48,7 @@ class ObjType:
'searchprio': 1,
}
def __init__(self, lname: str, *roles, **attrs) -> None:
def __init__(self, lname: str, *roles: Any, **attrs: Any) -> None:
self.lname = lname
self.roles = roles # type: Tuple
self.attrs = self.known_attrs.copy() # type: Dict

View File

@ -4,7 +4,7 @@
The C language domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The changeset domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The citation domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -112,7 +112,7 @@ class CitationDefinitionTransform(SphinxTransform):
"""Mark citation definition labels as not smartquoted."""
default_priority = 619
def apply(self, **kwargs) -> None:
def apply(self, **kwargs: Any) -> None:
domain = cast(CitationDomain, self.env.get_domain('citation'))
for node in self.document.traverse(nodes.citation):
# register citation node to domain
@ -131,7 +131,7 @@ class CitationReferenceTransform(SphinxTransform):
"""
default_priority = 619
def apply(self, **kwargs) -> None:
def apply(self, **kwargs: Any) -> None:
domain = cast(CitationDomain, self.env.get_domain('citation'))
for node in self.document.traverse(nodes.citation_reference):
target = node.astext()

View File

@ -4,7 +4,7 @@
The C++ language domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -6496,7 +6496,7 @@ class AliasNode(nodes.Element):
class AliasTransform(SphinxTransform):
default_priority = ReferencesResolver.default_priority - 1
def apply(self, **kwargs) -> None:
def apply(self, **kwargs: Any) -> None:
for node in self.document.traverse(AliasNode):
class Warner:
def warn(self, msg):
@ -6857,7 +6857,7 @@ class CPPDomain(Domain):
if s is None or s.declaration is None:
txtName = str(name)
if txtName.startswith('std::') or txtName == 'std':
raise NoUri()
raise NoUri(txtName, typ)
return None, None
if typ.startswith('cpp:'):

View File

@ -4,20 +4,26 @@
The index domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from typing import Any, Dict, Iterable, List, Tuple
from docutils.nodes import Node
from docutils import nodes
from docutils.nodes import Node, system_message
from sphinx import addnodes
from sphinx.application import Sphinx
from sphinx.domains import Domain
from sphinx.environment import BuildEnvironment
from sphinx.util import logging
from sphinx.util import split_index_msg
from sphinx.util.docutils import ReferenceRole, SphinxDirective
from sphinx.util.nodes import process_index_entry
if False:
# For type annotation
from sphinx.application import Sphinx
logger = logging.getLogger(__name__)
@ -54,8 +60,57 @@ class IndexDomain(Domain):
entries.append(entry)
def setup(app: Sphinx) -> Dict[str, Any]:
class IndexDirective(SphinxDirective):
"""
Directive to add entries to the index.
"""
has_content = False
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
option_spec = {} # type: Dict
def run(self) -> List[Node]:
arguments = self.arguments[0].split('\n')
targetid = 'index-%s' % self.env.new_serialno('index')
targetnode = nodes.target('', '', ids=[targetid])
self.state.document.note_explicit_target(targetnode)
indexnode = addnodes.index()
indexnode['entries'] = []
indexnode['inline'] = False
self.set_source_info(indexnode)
for entry in arguments:
indexnode['entries'].extend(process_index_entry(entry, targetid))
return [indexnode, targetnode]
class IndexRole(ReferenceRole):
def run(self) -> Tuple[List[Node], List[system_message]]:
target_id = 'index-%s' % self.env.new_serialno('index')
if self.has_explicit_title:
# if an explicit target is given, process it as a full entry
title = self.title
entries = process_index_entry(self.target, target_id)
else:
# otherwise we just create a single entry
if self.target.startswith('!'):
title = self.title[1:]
entries = [('single', self.target[1:], target_id, 'main', None)]
else:
title = self.title
entries = [('single', self.target, target_id, '', None)]
index = addnodes.index(entries=entries)
target = nodes.target('', '', ids=[target_id])
text = nodes.Text(title, title)
self.set_source_info(index)
return [index, target, text], []
def setup(app: "Sphinx") -> Dict[str, Any]:
app.add_domain(IndexDomain)
app.add_directive('index', IndexDirective)
app.add_role('index', IndexRole())
return {
'version': 'builtin',

View File

@ -4,7 +4,7 @@
The JavaScript domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The math domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The Python domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The reStructuredText domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The standard domain.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -30,7 +30,7 @@ from sphinx.locale import _, __
from sphinx.roles import XRefRole
from sphinx.util import ws_re, logging, docname_join
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import clean_astext, make_refnode
from sphinx.util.nodes import clean_astext, make_id, make_refnode
from sphinx.util.typing import RoleFunction
if False:
@ -128,7 +128,7 @@ class Target(SphinxDirective):
targetname = '%s-%s' % (self.name, fullname)
node = nodes.target('', '', ids=[targetname])
self.state.document.note_explicit_target(node)
ret = [node] # type: List[nodes.Node]
ret = [node] # type: List[Node]
if self.indextemplate:
indexentry = self.indextemplate % (fullname,)
indextype = 'single'
@ -243,34 +243,44 @@ def split_term_classifiers(line: str) -> List[Optional[str]]:
def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index_key: str,
source: str, lineno: int, new_id: str = None) -> nodes.term:
source: str, lineno: int, node_id: str = None,
document: nodes.document = None) -> nodes.term:
# get a text-only representation of the term and register it
# as a cross-reference target
term = nodes.term('', '', *textnodes)
term.source = source
term.line = lineno
gloss_entries = env.temp_data.setdefault('gloss_entries', set())
termtext = term.astext()
if new_id is None:
new_id = nodes.make_id('term-' + termtext)
if new_id == 'term':
# the term is not good for node_id. Generate it by sequence number instead.
new_id = 'term-%d' % env.new_serialno('glossary')
while new_id in gloss_entries:
new_id = 'term-%d' % env.new_serialno('glossary')
gloss_entries.add(new_id)
if node_id:
# node_id is given from outside (mainly i18n module), use it forcedly
term['ids'].append(node_id)
elif document:
node_id = make_id(env, document, 'term', termtext)
term['ids'].append(node_id)
document.note_explicit_target(term)
else:
warnings.warn('make_glossary_term() expects document is passed as an argument.',
RemovedInSphinx40Warning)
gloss_entries = env.temp_data.setdefault('gloss_entries', set())
node_id = nodes.make_id('term-' + termtext)
if node_id == 'term':
# "term" is not good for node_id. Generate it by sequence number instead.
node_id = 'term-%d' % env.new_serialno('glossary')
while node_id in gloss_entries:
node_id = 'term-%d' % env.new_serialno('glossary')
gloss_entries.add(node_id)
term['ids'].append(node_id)
std = cast(StandardDomain, env.get_domain('std'))
std.add_object('term', termtext.lower(), env.docname, new_id)
std.add_object('term', termtext.lower(), env.docname, node_id)
# add an index entry too
indexnode = addnodes.index()
indexnode['entries'] = [('single', termtext, new_id, 'main', index_key)]
indexnode['entries'] = [('single', termtext, node_id, 'main', index_key)]
indexnode.source, indexnode.line = term.source, term.line
term.append(indexnode)
term['ids'].append(new_id)
term['names'].append(new_id)
return term
@ -303,7 +313,7 @@ class Glossary(SphinxDirective):
in_definition = True
in_comment = False
was_empty = True
messages = [] # type: List[nodes.Node]
messages = [] # type: List[Node]
for line, (source, lineno) in zip(self.content, self.content.items):
# empty line -> add to last definition
if not line:
@ -359,8 +369,8 @@ class Glossary(SphinxDirective):
items = []
for terms, definition in entries:
termtexts = [] # type: List[str]
termnodes = [] # type: List[nodes.Node]
system_messages = [] # type: List[nodes.Node]
termnodes = [] # type: List[Node]
system_messages = [] # type: List[Node]
for line, source, lineno in terms:
parts = split_term_classifiers(line)
# parse the term with inline markup
@ -368,7 +378,8 @@ class Glossary(SphinxDirective):
textnodes, sysmsg = self.state.inline_text(parts[0], lineno)
# use first classifier as a index key
term = make_glossary_term(self.env, textnodes, parts[1], source, lineno)
term = make_glossary_term(self.env, textnodes, parts[1], source, lineno,
document=self.state.document)
term.rawsource = line
system_messages.extend(sysmsg)
termtexts.append(term.astext())
@ -396,7 +407,7 @@ class Glossary(SphinxDirective):
def token_xrefs(text: str) -> List[Node]:
retnodes = [] # type: List[nodes.Node]
retnodes = [] # type: List[Node]
pos = 0
for m in token_re.finditer(text):
if m.start() > pos:
@ -425,7 +436,7 @@ class ProductionList(SphinxDirective):
def run(self) -> List[Node]:
domain = cast(StandardDomain, self.env.get_domain('std'))
node = addnodes.productionlist() # type: nodes.Element
node = addnodes.productionlist() # type: Element
i = 0
for rule in self.arguments[0].split('\n'):
@ -526,7 +537,7 @@ class StandardDomain(Domain):
nodes.figure: ('figure', None),
nodes.table: ('table', None),
nodes.container: ('code-block', None),
} # type: Dict[Type[nodes.Node], Tuple[str, Callable]]
} # type: Dict[Type[Node], Tuple[str, Callable]]
def __init__(self, env: "BuildEnvironment") -> None:
super().__init__(env)
@ -628,7 +639,7 @@ class StandardDomain(Domain):
self.progoptions[program, name] = (docname, labelid)
def build_reference_node(self, fromdocname: str, builder: "Builder", docname: str,
labelid: str, sectname: str, rolename: str, **options
labelid: str, sectname: str, rolename: str, **options: Any
) -> Element:
nodeclass = options.pop('nodeclass', nodes.reference)
newnode = nodeclass('', '', internal=True, **options)
@ -823,7 +834,7 @@ class StandardDomain(Domain):
# remove the ids we added in the CitationReferences
# transform since they can't be transfered to
# the contnode (if it's a Text node)
if not isinstance(contnode, nodes.Element):
if not isinstance(contnode, Element):
del node['ids'][:]
raise
@ -845,7 +856,7 @@ class StandardDomain(Domain):
def resolve_any_xref(self, env: "BuildEnvironment", fromdocname: str,
builder: "Builder", target: str, node: pending_xref,
contnode: Element) -> List[Tuple[str, Element]]:
results = [] # type: List[Tuple[str, nodes.Element]]
results = [] # type: List[Tuple[str, Element]]
ltarget = target.lower() # :ref: lowercases its target automatically
for role in ('ref', 'option'): # do not try "keyword"
res = self.resolve_xref(env, fromdocname, builder, role,
@ -896,7 +907,7 @@ class StandardDomain(Domain):
def get_numfig_title(self, node: Node) -> str:
"""Get the title of enumerable nodes to refer them using its title"""
if self.is_enumerable_node(node):
elem = cast(nodes.Element, node)
elem = cast(Element, node)
_, title_getter = self.enumerable_nodes.get(elem.__class__, (None, None))
if title_getter:
return title_getter(elem)

View File

@ -4,7 +4,7 @@
Global creation environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,6 +4,6 @@
Sphinx environment adapters
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Assets adapter for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Index entries adapters for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import bisect

View File

@ -4,12 +4,12 @@
Toctree adapter for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from typing import Any, Iterable, List
from typing import cast
from typing import Iterable, List
from docutils import nodes
from docutils.nodes import Element, Node
@ -314,18 +314,18 @@ class TocTree:
node['refuri'] = node['anchorname'] or '#'
return toc
def get_toctree_for(self, docname: str, builder: "Builder", collapse: bool, **kwds
) -> Element:
def get_toctree_for(self, docname: str, builder: "Builder", collapse: bool,
**kwargs: Any) -> Element:
"""Return the global TOC nodetree."""
doctree = self.env.get_doctree(self.env.config.master_doc)
toctrees = [] # type: List[Element]
if 'includehidden' not in kwds:
kwds['includehidden'] = True
if 'maxdepth' not in kwds:
kwds['maxdepth'] = 0
kwds['collapse'] = collapse
if 'includehidden' not in kwargs:
kwargs['includehidden'] = True
if 'maxdepth' not in kwargs:
kwargs['maxdepth'] = 0
kwargs['collapse'] = collapse
for toctreenode in doctree.traverse(addnodes.toctree):
toctree = self.resolve(docname, builder, toctreenode, prune=True, **kwds)
toctree = self.resolve(docname, builder, toctreenode, prune=True, **kwargs)
if toctree:
toctrees.append(toctree)
if not toctrees:

View File

@ -4,7 +4,7 @@
The data collector components for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The image collector for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The dependencies collector components for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Index entries collector for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The metadata collector components for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
The title collector components for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Toctree collector for sphinx.environment.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Contains SphinxError and a few subclasses (in an extra module to avoid
circular import problems).
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -6,7 +6,7 @@
Gracefully adapted from the TextPress system by Armin.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -81,7 +81,7 @@ class EventManager:
for event in self.listeners.values():
event.pop(listener_id, None)
def emit(self, name: str, *args) -> List:
def emit(self, name: str, *args: Any) -> List:
"""Emit a Sphinx event."""
try:
logger.debug('[app] emitting event: %r%s', name, repr(args)[:100])
@ -99,7 +99,7 @@ class EventManager:
results.append(callback(self.app, *args))
return results
def emit_firstresult(self, name: str, *args) -> Any:
def emit_firstresult(self, name: str, *args: Any) -> Any:
"""Emit a Sphinx event and returns first result.
This returns the result of the first handler that doesn't return ``None``.

View File

@ -4,6 +4,6 @@
Contains Sphinx features not activated by default.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -10,7 +10,7 @@
Copyright 2008 Société des arts technologiques (SAT),
https://sat.qc.ca/
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -128,7 +128,7 @@ def create_package_file(root: str, master_package: str, subroot: str, py_files:
subpackages = [module_join(master_package, subroot, pkgname)
for pkgname in subpackages]
# build a list of sub modules
submodules = [path.splitext(sub)[0] for sub in py_files
submodules = [sub.split('.')[0] for sub in py_files
if not is_skipped_module(path.join(root, sub), opts, excludes) and
sub != INITPY]
submodules = [module_join(master_package, subroot, modname)

View File

@ -6,7 +6,7 @@
the doctree, thus avoiding duplication between docstrings and documentation
for those who like elaborate docstrings.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -24,7 +24,7 @@ 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.importer import import_object, get_module_members, get_object_members
from sphinx.ext.autodoc.mock import mock
from sphinx.locale import _, __
from sphinx.pycode import ModuleAnalyzer, PycodeError
@ -32,9 +32,7 @@ from sphinx.util import inspect
from sphinx.util import logging
from sphinx.util import rpartition
from sphinx.util.docstrings import prepare_docstring
from sphinx.util.inspect import (
Signature, getdoc, object_description, safe_getattr, safe_getmembers
)
from sphinx.util.inspect import getdoc, object_description, safe_getattr, stringify_signature
if False:
# For type annotation
@ -221,7 +219,7 @@ class Documenter:
option_spec = {'noindex': bool_option} # type: Dict[str, Callable]
def get_attr(self, obj: Any, name: str, *defargs) -> Any:
def get_attr(self, obj: Any, name: str, *defargs: Any) -> Any:
"""getattr() override for types such as Zope interfaces."""
return autodoc_attrgetter(self.env.app, obj, name, *defargs)
@ -344,14 +342,13 @@ class Documenter:
if self.options.imported_members:
return True
modname = self.get_attr(self.object, '__module__', None)
if inspect.ispartial(self.object) and modname == '_functools': # for pypy
return True
elif modname and modname != self.modname:
subject = inspect.unpartial(self.object)
modname = self.get_attr(subject, '__module__', None)
if modname and modname != self.modname:
return False
return True
def format_args(self, **kwargs) -> str:
def format_args(self, **kwargs: Any) -> str:
"""Format the argument signature of *self.object*.
Should return None if the object does not have a signature.
@ -369,7 +366,7 @@ class Documenter:
# directives of course)
return '.'.join(self.objpath) or self.modname
def format_signature(self, **kwargs) -> str:
def format_signature(self, **kwargs: Any) -> str:
"""Format the signature (arguments and return annotation) of the object.
Let the user process it via the ``autodoc-process-signature`` event.
@ -530,7 +527,10 @@ class Documenter:
# process members and determine which to skip
for (membername, member) in members:
# if isattr is True, the member is documented as an attribute
isattr = False
if member is INSTANCEATTR:
isattr = True
else:
isattr = False
doc = getdoc(member, self.get_attr, self.env.config.autodoc_inherit_docstrings)
@ -750,7 +750,7 @@ class ModuleDocumenter(Documenter):
'imported-members': bool_option, 'ignore-module-all': bool_option
} # type: Dict[str, Callable]
def __init__(self, *args) -> None:
def __init__(self, *args: Any) -> None:
super().__init__(*args)
merge_special_members_option(self.options)
@ -794,7 +794,7 @@ class ModuleDocumenter(Documenter):
hasattr(self.object, '__all__')):
# for implicit module members, check __module__ to avoid
# documenting imported objects
return True, safe_getmembers(self.object)
return True, get_module_members(self.object)
else:
memberlist = self.object.__all__
# Sometimes __all__ is broken...
@ -807,7 +807,7 @@ class ModuleDocumenter(Documenter):
type='autodoc'
)
# fall back to all members
return True, safe_getmembers(self.object)
return True, get_module_members(self.object)
else:
memberlist = self.options.members or []
ret = []
@ -928,7 +928,7 @@ class DocstringSignatureMixin:
return lines
return super().get_doc(None, ignore) # type: ignore
def format_signature(self, **kwargs) -> str:
def format_signature(self, **kwargs: Any) -> 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
@ -943,7 +943,7 @@ class DocstringStripSignatureMixin(DocstringSignatureMixin):
Mixin for AttributeDocumenter to provide the
feature of stripping any function signature from the docstring.
"""
def format_signature(self, **kwargs) -> str:
def format_signature(self, **kwargs: Any) -> 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
@ -970,7 +970,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
return (inspect.isfunction(member) or inspect.isbuiltin(member) or
(inspect.isroutine(member) and isinstance(parent, ModuleDocumenter)))
def format_args(self, **kwargs) -> str:
def format_args(self, **kwargs: Any) -> str:
if self.env.config.autodoc_typehints == 'none':
kwargs.setdefault('show_annotation', False)
@ -983,9 +983,13 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
not inspect.isbuiltin(self.object) and
not inspect.isclass(self.object) and
hasattr(self.object, '__call__')):
args = Signature(self.object.__call__).format_args(**kwargs)
self.env.app.emit('autodoc-before-process-signature',
self.object.__call__, False)
sig = inspect.signature(self.object.__call__)
else:
args = Signature(self.object).format_args(**kwargs)
self.env.app.emit('autodoc-before-process-signature', self.object, False)
sig = inspect.signature(self.object)
args = stringify_signature(sig, **kwargs)
except TypeError:
if (inspect.is_builtin_class_method(self.object, '__new__') and
inspect.is_builtin_class_method(self.object, '__init__')):
@ -995,11 +999,15 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
# typing) we try to use the constructor signature as function
# signature without the first argument.
try:
sig = Signature(self.object.__new__, bound_method=True, has_retval=False)
args = sig.format_args(**kwargs)
self.env.app.emit('autodoc-before-process-signature',
self.object.__new__, True)
sig = inspect.signature(self.object.__new__, bound_method=True)
args = stringify_signature(sig, show_return_annotation=False, **kwargs)
except TypeError:
sig = Signature(self.object.__init__, bound_method=True, has_retval=False)
args = sig.format_args(**kwargs)
self.env.app.emit('autodoc-before-process-signature',
self.object.__init__, True)
sig = inspect.signature(self.object.__init__, bound_method=True)
args = stringify_signature(sig, show_return_annotation=False, **kwargs)
# escape backslashes for reST
args = args.replace('\\', '\\\\')
@ -1047,7 +1055,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
'private-members': bool_option, 'special-members': members_option,
} # type: Dict[str, Callable]
def __init__(self, *args) -> None:
def __init__(self, *args: Any) -> None:
super().__init__(*args)
merge_special_members_option(self.options)
@ -1067,7 +1075,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
self.doc_as_attr = True
return ret
def format_args(self, **kwargs) -> str:
def format_args(self, **kwargs: Any) -> str:
if self.env.config.autodoc_typehints == 'none':
kwargs.setdefault('show_annotation', False)
@ -1080,14 +1088,15 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)):
return None
try:
sig = Signature(initmeth, bound_method=True, has_retval=False)
return sig.format_args(**kwargs)
self.env.app.emit('autodoc-before-process-signature', initmeth, True)
sig = inspect.signature(initmeth, bound_method=True)
return stringify_signature(sig, show_return_annotation=False, **kwargs)
except TypeError:
# still not possible: happens e.g. for old-style classes
# with __init__ in C
return None
def format_signature(self, **kwargs) -> str:
def format_signature(self, **kwargs: Any) -> str:
if self.doc_as_attr:
return ''
@ -1243,6 +1252,37 @@ class DataDocumenter(ModuleLevelDocumenter):
or self.modname
class DataDeclarationDocumenter(DataDocumenter):
"""
Specialized Documenter subclass for data that cannot be imported
because they are declared without initial value (refs: PEP-526).
"""
objtype = 'datadecl'
directivetype = 'data'
member_order = 60
# must be higher than AttributeDocumenter
priority = 11
@classmethod
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
) -> bool:
"""This documents only INSTANCEATTR members."""
return (isinstance(parent, ModuleDocumenter) and
isattr and
member is INSTANCEATTR)
def import_object(self) -> bool:
"""Never import anything."""
# disguise as a data
self.objtype = 'data'
return True
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)
class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type: ignore
"""
Specialized Documenter subclass for methods (normal, static and class).
@ -1275,7 +1315,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
return ret
def format_args(self, **kwargs) -> str:
def format_args(self, **kwargs: Any) -> str:
if self.env.config.autodoc_typehints == 'none':
kwargs.setdefault('show_annotation', False)
@ -1283,14 +1323,18 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
# can never get arguments of a C function or method
return None
if inspect.isstaticmethod(self.object, cls=self.parent, name=self.object_name):
args = Signature(self.object, bound_method=False).format_args(**kwargs)
self.env.app.emit('autodoc-before-process-signature', self.object, False)
sig = inspect.signature(self.object, bound_method=False)
else:
args = Signature(self.object, bound_method=True).format_args(**kwargs)
self.env.app.emit('autodoc-before-process-signature', self.object, True)
sig = inspect.signature(self.object, bound_method=True)
args = stringify_signature(sig, **kwargs)
# escape backslashes for reST
args = args.replace('\\', '\\\\')
return args
def add_directive_header(self, sig) -> None:
def add_directive_header(self, sig: str) -> None:
super().add_directive_header(sig)
sourcename = self.get_sourcename()
@ -1426,7 +1470,9 @@ class InstanceAttributeDocumenter(AttributeDocumenter):
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)
return (not isinstance(parent, ModuleDocumenter) and
isattr and
member is INSTANCEATTR)
def import_object(self) -> bool:
"""Never import anything."""
@ -1492,7 +1538,7 @@ def get_documenters(app: Sphinx) -> Dict[str, "Type[Documenter]"]:
return app.registry.documenters
def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs) -> Any:
def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs: Any) -> Any:
"""Alternative getattr() for types"""
for typ, func in app.registry.autodoc_attrgettrs.items():
if isinstance(obj, typ):
@ -1538,6 +1584,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_autodocumenter(ClassDocumenter)
app.add_autodocumenter(ExceptionDocumenter)
app.add_autodocumenter(DataDocumenter)
app.add_autodocumenter(DataDeclarationDocumenter)
app.add_autodocumenter(FunctionDocumenter)
app.add_autodocumenter(DecoratorDocumenter)
app.add_autodocumenter(MethodDocumenter)
@ -1555,10 +1602,12 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('autodoc_typehints', "signature", True, ENUM("signature", "none"))
app.add_config_value('autodoc_warningiserror', True, True)
app.add_config_value('autodoc_inherit_docstrings', True, True)
app.add_event('autodoc-before-process-signature')
app.add_event('autodoc-process-docstring')
app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member')
app.connect('config-inited', merge_autodoc_default_flags)
app.setup_extension('sphinx.ext.autodoc.type_comment')
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -4,7 +4,7 @@
Importer utilities for autodoc
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -12,7 +12,7 @@ import importlib
import traceback
import warnings
from collections import namedtuple
from typing import Any, Callable, Dict, List
from typing import Any, Callable, Dict, List, Tuple
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
from sphinx.util import logging
@ -101,12 +101,35 @@ def import_object(modname: str, objpath: List[str], objtype: str = '',
raise ImportError(errmsg)
def get_module_members(module: Any) -> List[Tuple[str, Any]]:
"""Get members of target module."""
from sphinx.ext.autodoc import INSTANCEATTR
members = {} # type: Dict[str, Tuple[str, Any]]
for name in dir(module):
try:
value = safe_getattr(module, name, None)
members[name] = (name, value)
except AttributeError:
continue
# annotation only member (ex. attr: int)
if hasattr(module, '__annotations__'):
for name in module.__annotations__:
if name not in members:
members[name] = (name, INSTANCEATTR)
return sorted(list(members.values()))
Attribute = namedtuple('Attribute', ['name', 'directly_defined', 'value'])
def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
analyzer: Any = None) -> Dict[str, Attribute]:
"""Get members and attributes of target object."""
from sphinx.ext.autodoc import INSTANCEATTR
# the members directly defined in the class
obj_dict = attrgetter(subject, '__dict__', {})
@ -140,10 +163,14 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
except AttributeError:
continue
# annotation only member (ex. attr: int)
if hasattr(subject, '__annotations__'):
for name in subject.__annotations__:
if name not in members:
members[name] = Attribute(name, True, INSTANCEATTR)
if analyzer:
# append instance attributes (cf. self.attr1) if analyzer knows
from sphinx.ext.autodoc import INSTANCEATTR
namespace = '.'.join(objpath)
for (ns, name) in analyzer.find_attr_docs():
if namespace == ns and name not in members:

View File

@ -4,7 +4,7 @@
mock for autodoc
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -28,7 +28,7 @@ class _MockObject:
__display_name__ = '_MockObject'
def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
if len(args) == 3 and isinstance(args[1], tuple):
superclass = args[1][-1].__class__
if superclass is cls:
@ -38,7 +38,7 @@ class _MockObject:
return super().__new__(cls)
def __init__(self, *args, **kwargs) -> None:
def __init__(self, *args: Any, **kwargs: Any) -> None:
self.__qualname__ = ''
def __len__(self) -> int:
@ -59,7 +59,7 @@ class _MockObject:
def __getattr__(self, key: str) -> "_MockObject":
return _make_subclass(key, self.__display_name__, self.__class__)()
def __call__(self, *args, **kw) -> Any:
def __call__(self, *args: Any, **kwargs: Any) -> Any:
if args and type(args[0]) in [type, FunctionType, MethodType]:
# Appears to be a decorator, pass through unchanged
return args[0]

View File

@ -0,0 +1,74 @@
"""
sphinx.ext.autodoc.type_comment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Update annotations info of living objects using type_comments.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import ast
from inspect import getsource
from typing import Any, Dict
from typing import cast
import sphinx
from sphinx.application import Sphinx
from sphinx.pycode.ast import parse as ast_parse
from sphinx.pycode.ast import unparse as ast_unparse
from sphinx.util import inspect
from sphinx.util import logging
logger = logging.getLogger(__name__)
def get_type_comment(obj: Any) -> ast.FunctionDef:
"""Get type_comment'ed FunctionDef object from living object.
This tries to parse original code for living object and returns
AST node for given *obj*. It requires py38+ or typed_ast module.
"""
try:
source = getsource(obj)
if source.startswith((' ', r'\t')):
# subject is placed inside class or block. To read its docstring,
# this adds if-block before the declaration.
module = ast_parse('if True:\n' + source)
subject = cast(ast.FunctionDef, module.body[0].body[0]) # type: ignore
else:
module = ast_parse(source)
subject = cast(ast.FunctionDef, module.body[0]) # type: ignore
if getattr(subject, "type_comment", None):
return ast_parse(subject.type_comment, mode='func_type') # type: ignore
else:
return None
except (OSError, TypeError): # failed to load source code
return None
except SyntaxError: # failed to parse type_comments
return None
def update_annotations_using_type_comments(app: Sphinx, obj: Any, bound_method: bool) -> None:
"""Update annotations info of *obj* using type_comments."""
try:
function = get_type_comment(obj)
if function and hasattr(function, 'argtypes'):
if function.argtypes != [ast.Ellipsis]: # type: ignore
sig = inspect.signature(obj, bound_method)
for i, param in enumerate(sig.parameters.values()):
if param.name not in obj.__annotations__:
annotation = ast_unparse(function.argtypes[i]) # type: ignore
obj.__annotations__[param.name] = annotation
if 'return' not in obj.__annotations__:
obj.__annotations__['return'] = ast_unparse(function.returns) # type: ignore
except NotImplementedError as exc: # failed to ast.unparse()
logger.warning("Failed to parse type_comment for %r: %s", obj, exc)
def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('autodoc-before-process-signature', update_annotations_using_type_comments)
return {'version': sphinx.__display_version__, 'parallel_read_safe': True}

View File

@ -0,0 +1,144 @@
"""
sphinx.ext.autodoc.typehints
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Generating content for autodoc using typehints
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
from typing import Any, Dict, Iterable
from typing import cast
from docutils import nodes
from docutils.nodes import Element
from sphinx import addnodes
from sphinx.application import Sphinx
from sphinx.config import ENUM
from sphinx.util import inspect, typing
def config_inited(app, config):
if config.autodoc_typehints == 'description':
# HACK: override this to make autodoc suppressing typehints in signatures
config.autodoc_typehints = 'none'
# preserve user settings
app._autodoc_typehints_description = True
else:
app._autodoc_typehints_description = False
def record_typehints(app: Sphinx, objtype: str, name: str, obj: Any,
options: Dict, args: str, retann: str) -> None:
"""Record type hints to env object."""
try:
if callable(obj):
annotations = app.env.temp_data.setdefault('annotations', {}).setdefault(name, {})
sig = inspect.signature(obj)
for param in sig.parameters.values():
if param.annotation is not param.empty:
annotations[param.name] = typing.stringify(param.annotation)
if sig.return_annotation is not sig.empty:
annotations['return'] = typing.stringify(sig.return_annotation)
except TypeError:
pass
def merge_typehints(app: Sphinx, domain: str, objtype: str, contentnode: Element) -> None:
if domain != 'py':
return
if app._autodoc_typehints_description is False: # type: ignore
return
signature = cast(addnodes.desc_signature, contentnode.parent[0])
fullname = '.'.join([signature['module'], signature['fullname']])
annotations = app.env.temp_data.get('annotations', {})
if annotations.get(fullname, {}):
field_lists = [n for n in contentnode if isinstance(n, nodes.field_list)]
if field_lists == []:
field_list = insert_field_list(contentnode)
field_lists.append(field_list)
for field_list in field_lists:
modify_field_list(field_list, annotations[fullname])
def insert_field_list(node: Element) -> nodes.field_list:
field_list = nodes.field_list()
desc = [n for n in node if isinstance(n, addnodes.desc)]
if desc:
# insert just before sub object descriptions (ex. methods, nested classes, etc.)
index = node.index(desc[0])
node.insert(index - 1, [field_list])
else:
node += field_list
return field_list
def modify_field_list(node: nodes.field_list, annotations: Dict[str, str]) -> None:
arguments = {} # type: Dict[str, Dict[str, bool]]
fields = cast(Iterable[nodes.field], node)
for field in fields:
field_name = field[0].astext()
parts = re.split(' +', field_name)
if parts[0] == 'param':
if len(parts) == 2:
# :param xxx:
arg = arguments.setdefault(parts[1], {})
arg['param'] = True
elif len(parts) > 2:
# :param xxx yyy:
name = ' '.join(parts[2:])
arg = arguments.setdefault(name, {})
arg['param'] = True
arg['type'] = True
elif parts[0] == 'type':
name = ' '.join(parts[1:])
arg = arguments.setdefault(name, {})
arg['type'] = True
elif parts[0] == 'rtype':
arguments['return'] = {'type': True}
for name, annotation in annotations.items():
if name == 'return':
continue
arg = arguments.get(name, {})
field = nodes.field()
if arg.get('param') and arg.get('type'):
# both param and type are already filled manually
continue
elif arg.get('param'):
# only param: fill type field
field += nodes.field_name('', 'type ' + name)
field += nodes.field_body('', nodes.paragraph('', annotation))
elif arg.get('type'):
# only type: It's odd...
field += nodes.field_name('', 'param ' + name)
field += nodes.field_body('', nodes.paragraph('', ''))
else:
# both param and type are not found
field += nodes.field_name('', 'param ' + annotation + ' ' + name)
field += nodes.field_body('', nodes.paragraph('', ''))
node += field
if 'return' in annotations and 'return' not in arguments:
field = nodes.field()
field += nodes.field_name('', 'rtype')
field += nodes.field_body('', nodes.paragraph('', annotation))
node += field
def setup(app):
app.setup_extension('sphinx.ext.autodoc')
app.config.values['autodoc_typehints'] = ('signature', True,
ENUM("signature", "description", "none"))
app.connect('config-inited', config_inited)
app.connect('autodoc-process-signature', record_typehints)
app.connect('object-description-transform', merge_typehints)

View File

@ -4,7 +4,7 @@
Allow reference sections by :ref: role using its title.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -48,7 +48,7 @@
resolved to a Python object, and otherwise it becomes simple emphasis.
This can be used as the default role to make links 'smart'.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -13,7 +13,7 @@
generate:
sphinx-autogen -o source/generated source/*.rst
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -62,7 +62,7 @@ class DummyApplication:
self._warncount = 0
self.warningiserror = False
def emit_firstresult(self, *args) -> None:
def emit_firstresult(self, *args: Any) -> None:
pass
@ -71,13 +71,13 @@ def setup_documenters(app: Any) -> None:
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
SlotsAttributeDocumenter,
SlotsAttributeDocumenter, DataDeclarationDocumenter,
)
documenters = [
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
SlotsAttributeDocumenter,
SlotsAttributeDocumenter, DataDeclarationDocumenter,
] # type: List[Type[Documenter]]
for documenter in documenters:
app.registry.add_documenter(documenter.objtype, documenter)

View File

@ -5,7 +5,7 @@
Check Python modules and C API for coverage. Mostly written by Josip
Dzolonga for the Google Highly Open Participation contest.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -80,7 +80,7 @@ class CoverageBuilder(Builder):
def get_outdated_docs(self) -> str:
return 'coverage overview'
def write(self, *ignored) -> None:
def write(self, *ignored: Any) -> None:
self.py_undoc = {} # type: Dict[str, Dict[str, Any]]
self.build_py_coverage()
self.write_py_coverage()

View File

@ -5,7 +5,7 @@
Mimic doctest by automatically executing code snippets and checking
their results.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Measure durations of Sphinx processing.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -32,7 +32,7 @@ class DurationDomain(Domain):
def reading_durations(self) -> Dict[str, timedelta]:
return self.data.setdefault('reading_durations', {})
def note_reading_duration(self, duration: timedelta):
def note_reading_duration(self, duration: timedelta) -> None:
self.reading_durations[self.env.docname] = duration
def clear(self) -> None:
@ -69,7 +69,7 @@ def on_doctree_read(app: Sphinx, doctree: nodes.document) -> None:
domain.note_reading_duration(duration)
def on_build_finished(app: Sphinx, error):
def on_build_finished(app: Sphinx, error: Exception) -> None:
"""Display duration ranking on current build."""
domain = cast(DurationDomain, app.env.get_domain('duration'))
durations = sorted(domain.reading_durations.items(), key=itemgetter(1), reverse=True)

View File

@ -19,7 +19,7 @@
You can also give an explicit caption, e.g. :exmpl:`Foo <foo>`.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
To publish HTML docs at GitHub Pages, create .nojekyll file.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Allow graphviz-formatted graphs to be included in Sphinx-generated
documents inline.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -121,6 +121,7 @@ class Graphviz(SphinxDirective):
'layout': directives.unchanged,
'graphviz_dot': directives.unchanged, # an old alias of `layout` option
'name': directives.unchanged,
'class': directives.class_option,
}
def run(self) -> List[Node]:
@ -158,6 +159,8 @@ class Graphviz(SphinxDirective):
node['alt'] = self.options['alt']
if 'align' in self.options:
node['align'] = self.options['align']
if 'class' in self.options:
node['classes'] = self.options['class']
if 'caption' not in self.options:
self.add_name(node)
@ -182,6 +185,7 @@ class GraphvizSimple(SphinxDirective):
'caption': directives.unchanged,
'graphviz_dot': directives.unchanged,
'name': directives.unchanged,
'class': directives.class_option,
}
def run(self) -> List[Node]:
@ -195,6 +199,8 @@ class GraphvizSimple(SphinxDirective):
node['alt'] = self.options['alt']
if 'align' in self.options:
node['align'] = self.options['align']
if 'class' in self.options:
node['classes'] = self.options['class']
if 'caption' not in self.options:
self.add_name(node)
@ -267,10 +273,8 @@ def render_dot_html(self: HTMLTranslator, node: graphviz, code: str, options: Di
logger.warning(__('dot code %r: %s'), code, exc)
raise nodes.SkipNode
if imgcls:
imgcls += " graphviz"
else:
imgcls = "graphviz"
classes = [imgcls, 'graphviz'] + node.get('classes', [])
imgcls = ' '.join(filter(None, classes))
if fname is None:
self.body.append(self.encode(code))

View File

@ -15,7 +15,7 @@
namespace of the project configuration (that is, all variables from
``conf.py`` are available.)
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Image converter extension for Sphinx
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -27,6 +27,7 @@ class ImagemagickConverter(ImageConverter):
('image/svg+xml', 'image/png'),
('image/gif', 'image/png'),
('application/pdf', 'image/png'),
('application/illustrator', 'image/png'),
]
def is_available(self) -> bool:

View File

@ -4,7 +4,7 @@
Render math in HTML via dvipng or dvisvgm.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -31,7 +31,7 @@ r"""
The graph is inserted as a PNG+image map into HTML and a PDF in
LaTeX.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -19,7 +19,7 @@
also be specified individually, e.g. if the docs should be buildable
without Internet access.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Set up everything for use of JSMath to display math in HTML
via JavaScript.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Add external links to module code in Python object descriptions.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Set up math support in source files and LaTeX/text output.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -6,7 +6,7 @@
Sphinx's HTML writer -- requires the MathJax JavaScript library on your
webserver/computer.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Support for NumPy and Google style docstrings.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -265,7 +265,7 @@ class Config:
'napoleon_custom_sections': (None, 'env')
}
def __init__(self, **settings) -> None:
def __init__(self, **settings: Any) -> None:
for name, (default, rebuild) in self._config_values.items():
setattr(self, name, default)
for name, value in settings.items():

View File

@ -6,7 +6,7 @@
Classes for docstring parsing and formatting.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -101,8 +101,8 @@ class GoogleDocstring:
"""
_name_rgx = re.compile(r"^\s*((?::(?P<role>\S+):)?`(?P<name>[a-zA-Z0-9_.-]+)`|"
r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
_name_rgx = re.compile(r"^\s*((?::(?P<role>\S+):)?`(?P<name>~?[a-zA-Z0-9_.-]+)`|"
r" (?P<name2>~?[a-zA-Z0-9_.-]+))\s*", re.X)
def __init__(self, docstring: Union[str, List[str]], config: SphinxConfig = None,
app: Sphinx = None, what: str = '', name: str = '',

View File

@ -6,7 +6,7 @@
A collection of helpful iterators.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -47,7 +47,7 @@ class peek_iter:
be set to a new object instance: ``object()``.
"""
def __init__(self, *args) -> None:
def __init__(self, *args: Any) -> None:
"""__init__(o, sentinel=None)"""
self._iterable = iter(*args) # type: Iterable
self._cache = collections.deque() # type: collections.deque
@ -208,7 +208,7 @@ class modify_iter(peek_iter):
"whitespace."
"""
def __init__(self, *args, **kwargs) -> None:
def __init__(self, *args: Any, **kwargs: Any) -> None:
"""__init__(o, sentinel=None, modifier=lambda x: x)"""
if 'modifier' in kwargs:
self.modifier = kwargs['modifier']

View File

@ -7,7 +7,7 @@
all todos of your project and lists them along with a backlink to the
original location.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Add links to module code in Python object descriptions.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -4,7 +4,7 @@
Utilities for Sphinx extensions.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
class Extension:
def __init__(self, name: str, module: Any, **kwargs) -> None:
def __init__(self, name: str, module: Any, **kwargs: Any) -> None:
self.name = name
self.module = module
self.metadata = kwargs

View File

@ -4,7 +4,7 @@
Highlight code blocks using Pygments.
:copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -93,7 +93,7 @@ class PygmentsBridge:
else:
return get_style_by_name(stylename)
def get_formatter(self, **kwargs) -> Formatter:
def get_formatter(self, **kwargs: Any) -> Formatter:
kwargs.update(self.formatter_args)
return self.formatter(**kwargs)
@ -155,7 +155,7 @@ class PygmentsBridge:
return lexer
def highlight_block(self, source: str, lang: str, opts: Dict = None,
force: bool = False, location: Any = None, **kwargs) -> str:
force: bool = False, location: Any = None, **kwargs: Any) -> str:
if not isinstance(source, str):
source = source.decode()

Some files were not shown because too many files have changed in this diff Show More