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()`` * The ``decode`` argument of ``sphinx.pycode.ModuleAnalyzer()``
* ``sphinx.directives.other.Index``
* ``sphinx.environment.temp_data['gloss_entries']``
* ``sphinx.environment.BuildEnvironment.indexentries`` * ``sphinx.environment.BuildEnvironment.indexentries``
* ``sphinx.environment.collectors.indexentries.IndexEntriesCollector`` * ``sphinx.environment.collectors.indexentries.IndexEntriesCollector``
* ``sphinx.io.FiletypeNotFoundError`` * ``sphinx.io.FiletypeNotFoundError``
* ``sphinx.io.get_filetype()`` * ``sphinx.io.get_filetype()``
* ``sphinx.pycode.ModuleAnalyzer.encoding`` * ``sphinx.pycode.ModuleAnalyzer.encoding``
* ``sphinx.roles.Index``
* ``sphinx.util.detect_encoding()`` * ``sphinx.util.detect_encoding()``
* ``sphinx.util.get_module_source()`` * ``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.author``
* ``sphinx.writers.latex.LaTeXTranslator.settings.contentsname`` * ``sphinx.writers.latex.LaTeXTranslator.settings.contentsname``
* ``sphinx.writers.latex.LaTeXTranslator.settings.docclass`` * ``sphinx.writers.latex.LaTeXTranslator.settings.docclass``
@ -31,6 +36,23 @@ Features added
* #6446: duration: Add ``sphinx.ext.durations`` to inspect which documents slow * #6446: duration: Add ``sphinx.ext.durations`` to inspect which documents slow
down the build down the build
* #6837: LaTeX: Support a nested table * #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 Bugs fixed
---------- ----------
@ -38,6 +60,13 @@ Bugs fixed
* #6925: html: Remove redundant type="text/javascript" from <script> elements * #6925: html: Remove redundant type="text/javascript" from <script> elements
* #6906, #6907: autodoc: failed to read the source codes encoeded in cp1251 * #6906, #6907: autodoc: failed to read the source codes encoeded in cp1251
* #6961: latex: warning for babel shown twice * #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 Testing
-------- --------
@ -1126,6 +1155,8 @@ Features added
* #5029: autosummary: expose ``inherited_members`` to template * #5029: autosummary: expose ``inherited_members`` to template
* #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag * #3784: mathjax: Add :confval:`mathjax_options` to give options to script tag
for mathjax 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 * #4362: latex: Don't overwrite .tex file if document not changed
* #1431: latex: Add alphanumeric enumerated list support * #1431: latex: Add alphanumeric enumerated list support
* Add :confval:`latex_use_xindy` for UTF-8 savvy indexing, defaults to ``True`` * 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 .. 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) .. event:: doctree-read (app, doctree)
Emitted when a doctree has been parsed and read by the environment, and is 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 - 4.0
- N/A - 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`` * - ``sphinx.environment.BuildEnvironment.indexentries``
- 2.4 - 2.4
- 4.0 - 4.0
@ -51,21 +61,37 @@ The following is a list of deprecated interfaces.
- 4.0 - 4.0
- ``sphinx.util.get_filetype()`` - ``sphinx.util.get_filetype()``
* - ``sphinx.util.get_module_source()``
- 2.4
- 4.0
- N/A
* - ``sphinx.pycode.ModuleAnalyzer.encoding`` * - ``sphinx.pycode.ModuleAnalyzer.encoding``
- 2.4 - 2.4
- 4.0 - 4.0
- N/A - N/A
* - ``sphinx.roles.Index``
- 2.4
- 4.0
- ``sphinx.domains.index.IndexRole``
* - ``sphinx.util.detect_encoding()`` * - ``sphinx.util.detect_encoding()``
- 2.4 - 2.4
- 4.0 - 4.0
- ``tokenize.detect_encoding()`` - ``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`` * - ``sphinx.writers.latex.LaTeXTranslator.settings.author``
- 2.4 - 2.4
- 4.0 - 4.0

View File

@ -494,6 +494,17 @@ autodoc provides the following additional events:
auto directive auto directive
:param lines: the lines of the docstring, see above :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) .. event:: autodoc-process-signature (app, what, name, obj, options, signature, return_annotation)
.. versionadded:: 0.5 .. 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 ``inherited_members``, ``undoc_members``, ``show_inheritance`` and
``noindex`` that are true if the flag option of same name was given to the ``noindex`` that are true if the flag option of same name was given to the
auto directive 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 .. 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 .. rst:directive:: graph
@ -131,6 +138,13 @@ It adds these directives:
.. versionadded:: 1.6 .. 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 .. rst:directive:: digraph
@ -176,6 +190,13 @@ It adds these directives:
.. versionadded:: 1.6 .. 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: 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 (``{}``). The default is empty (``{}``).
.. versionadded:: 1.8
.. confval:: mathjax_config .. confval:: mathjax_config
The inline configuration options for mathjax. The value is used as a 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). 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 .. _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 :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 When you use this role, the referenced file is automatically marked for
inclusion in the output when building (obviously, for HTML output only). inclusion in the output when building (obviously, for HTML output only).
All downloadable files are put into the ``_downloads`` subdirectory of the All downloadable files are put into a ``_downloads/<unique hash>/``
output directory; duplicate filenames are handled. subdirectory of the output directory; duplicate filenames are handled.
An example:: An example::

View File

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

View File

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

View File

@ -4,7 +4,7 @@
The Sphinx documentation toolchain. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The Sphinx documentation toolchain. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Additional docutils nodes. 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. :license: BSD, see LICENSE for details.
""" """
@ -12,6 +12,7 @@ import warnings
from typing import Any, Dict, List, Sequence from typing import Any, Dict, List, Sequence
from docutils import nodes from docutils import nodes
from docutils.nodes import Node
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
@ -358,7 +359,8 @@ class abbreviation(nodes.abbreviation):
.. deprecated:: 2.0 .. 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'.", warnings.warn("abbrevition node for Sphinx was replaced by docutils'.",
RemovedInSphinx40Warning, stacklevel=2) RemovedInSphinx40Warning, stacklevel=2)

View File

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

View File

@ -4,7 +4,7 @@
Builder superclass for all builders. 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. :license: BSD, see LICENSE for details.
""" """
@ -118,11 +118,11 @@ class Builder:
self.env.set_versioning_method(self.versioning_method, self.env.set_versioning_method(self.versioning_method,
self.versioning_compare) 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 a class of translator."""
return self.app.registry.get_translator_class(self) 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. """Return an instance of translator.
This method returns an instance of ``default_translator_class`` by default. This method returns an instance of ``default_translator_class`` by default.

View File

@ -4,7 +4,7 @@
Base class of epub2/epub3 builders. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Build Apple help books. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Changelog builder. 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. :license: BSD, see LICENSE for details.
""" """
@ -50,7 +50,7 @@ class ChangesBuilder(Builder):
'deprecated': 'deprecated', 'deprecated': 'deprecated',
} }
def write(self, *ignored) -> None: def write(self, *ignored: Any) -> None:
version = self.config.version version = self.config.version
domain = cast(ChangeSetDomain, self.env.get_domain('changeset')) domain = cast(ChangeSetDomain, self.env.get_domain('changeset'))
libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]] libchanges = {} # type: Dict[str, List[Tuple[str, str, int]]]

View File

@ -6,7 +6,7 @@
.. _Devhelp: https://wiki.gnome.org/Apps/Devhelp .. _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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Directory HTML builders. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The MessageCatalogBuilder class. 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. :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.console import bold # type: ignore
from sphinx.util.i18n import CatalogInfo, docname_to_domain from sphinx.util.i18n import CatalogInfo, docname_to_domain
from sphinx.util.nodes import extract_messages, traverse_translatable_index 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.tags import Tags
from sphinx.util.template import SphinxRenderer from sphinx.util.template import SphinxRenderer
@ -108,7 +108,8 @@ class MsgOrigin:
class GettextRenderer(SphinxRenderer): 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: if template_path is None:
template_path = path.join(package_dir, 'templates', 'gettext') template_path = path.join(package_dir, 'templates', 'gettext')
super().__init__(template_path) super().__init__(template_path)
@ -122,6 +123,13 @@ class GettextRenderer(SphinxRenderer):
self.env.filters['e'] = escape self.env.filters['e'] = escape
self.env.filters['escape'] = 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): class I18nTags(Tags):
"""Dummy tags module for I18nBuilder. """Dummy tags module for I18nBuilder.
@ -198,8 +206,8 @@ if source_date_epoch is not None:
class LocalTimeZone(tzinfo): class LocalTimeZone(tzinfo):
def __init__(self, *args, **kw) -> None: def __init__(self, *args: Any, **kwargs: Any) -> None:
super().__init__(*args, **kw) # type: ignore super().__init__(*args, **kwargs) # type: ignore
self.tzdelta = tzdelta self.tzdelta = tzdelta
def utcoffset(self, dt: datetime) -> timedelta: def utcoffset(self, dt: datetime) -> timedelta:
@ -212,7 +220,7 @@ class LocalTimeZone(tzinfo):
ltz = LocalTimeZone() ltz = LocalTimeZone()
def should_write(filepath: str, new_content: str): def should_write(filepath: str, new_content: str) -> bool:
if not path.exists(filepath): if not path.exists(filepath):
return True return True
try: try:
@ -297,7 +305,7 @@ class MessageCatalogBuilder(I18nBuilder):
ensuredir(path.join(self.outdir, path.dirname(textdomain))) ensuredir(path.join(self.outdir, path.dirname(textdomain)))
context['messages'] = list(catalog) 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') pofn = path.join(self.outdir, textdomain + '.pot')
if should_write(pofn, content): if should_write(pofn, content):

View File

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

View File

@ -5,7 +5,7 @@
Build HTML help support files. Build HTML help support files.
Parts adapted from Python's Doc/tools/prechm.py. 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -4,7 +4,7 @@
Additional nodes for LaTeX writer. 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -4,7 +4,7 @@
The CheckExternalLinksBuilder class. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Manual pages builder. 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. :license: BSD, see LICENSE for details.
""" """
@ -53,10 +53,10 @@ class ManualPageBuilder(Builder):
def get_target_uri(self, docname: str, typ: str = None) -> str: def get_target_uri(self, docname: str, typ: str = None) -> str:
if typ == 'token': if typ == 'token':
return '' return ''
raise NoUri raise NoUri(docname, typ)
@progress_message(__('writing')) @progress_message(__('writing'))
def write(self, *ignored) -> None: def write(self, *ignored: Any) -> None:
docwriter = ManualPageWriter(self) docwriter = ManualPageWriter(self)
docsettings = OptionParser( docsettings = OptionParser(
defaults=self.env.settings, defaults=self.env.settings,

View File

@ -4,7 +4,7 @@
Build input files for the Qt collection generator. 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -4,7 +4,7 @@
Texinfo builder. 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. :license: BSD, see LICENSE for details.
""" """
@ -63,7 +63,7 @@ class TexinfoBuilder(Builder):
def get_target_uri(self, docname: str, typ: str = None) -> str: def get_target_uri(self, docname: str, typ: str = None) -> str:
if docname not in self.docnames: if docname not in self.docnames:
raise NoUri raise NoUri(docname, typ)
else: else:
return '%' + docname return '%' + docname
@ -90,7 +90,7 @@ class TexinfoBuilder(Builder):
docname = docname[:-5] docname = docname[:-5]
self.titles.append((docname, entry[2])) self.titles.append((docname, entry[2]))
def write(self, *ignored) -> None: def write(self, *ignored: Any) -> None:
self.init_document_data() self.init_document_data()
for entry in self.document_data: for entry in self.document_data:
docname, targetname, title, author = entry[:4] docname, targetname, title, author = entry[:4]

View File

@ -4,7 +4,7 @@
Plain-text Sphinx builder. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Docutils-native XML and pseudo-XML builders. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,6 +4,6 @@
Modules for command line executables. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Build documentation from a provided source. 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. :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 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). 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Quickly setup documentation source to work with Sphinx. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
sphinx-build command-line handling. 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -4,7 +4,7 @@
Sphinx deprecation classes and utilities. 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -2,7 +2,7 @@
sphinx.directives.code 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -2,7 +2,7 @@
sphinx.directives.other 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. :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 docutils.parsers.rst.directives.misc import Include as BaseInclude
from sphinx import addnodes from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
from sphinx.domains.changeset import VersionChange # NOQA # for compatibility from sphinx.domains.changeset import VersionChange # NOQA # for compatibility
from sphinx.locale import _ from sphinx.locale import _
from sphinx.util import url_re, docname_join from sphinx.util import url_re, docname_join
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.matching import Matcher, patfilter 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: if False:
# For type annotation # For type annotation
@ -182,30 +183,6 @@ class Author(SphinxDirective):
return ret 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): class SeeAlso(BaseAdmonition):
""" """
An admonition mentioning things to look at as reference. An admonition mentioning things to look at as reference.
@ -383,12 +360,21 @@ class Include(BaseInclude, SphinxDirective):
return super().run() 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]: def setup(app: "Sphinx") -> Dict[str, Any]:
directives.register_directive('toctree', TocTree) directives.register_directive('toctree', TocTree)
directives.register_directive('sectionauthor', Author) directives.register_directive('sectionauthor', Author)
directives.register_directive('moduleauthor', Author) directives.register_directive('moduleauthor', Author)
directives.register_directive('codeauthor', Author) directives.register_directive('codeauthor', Author)
directives.register_directive('index', Index)
directives.register_directive('seealso', SeeAlso) directives.register_directive('seealso', SeeAlso)
directives.register_directive('tabularcolumns', TabularColumns) directives.register_directive('tabularcolumns', TabularColumns)
directives.register_directive('centered', Centered) directives.register_directive('centered', Centered)

View File

@ -2,7 +2,7 @@
sphinx.directives.patches 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Support for domains, which are groupings of description directives Support for domains, which are groupings of description directives
and roles describing e.g. constructs of one programming language. 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. :license: BSD, see LICENSE for details.
""" """
@ -48,7 +48,7 @@ class ObjType:
'searchprio': 1, 'searchprio': 1,
} }
def __init__(self, lname: str, *roles, **attrs) -> None: def __init__(self, lname: str, *roles: Any, **attrs: Any) -> None:
self.lname = lname self.lname = lname
self.roles = roles # type: Tuple self.roles = roles # type: Tuple
self.attrs = self.known_attrs.copy() # type: Dict self.attrs = self.known_attrs.copy() # type: Dict

View File

@ -4,7 +4,7 @@
The C language domain. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The changeset domain. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The citation domain. 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. :license: BSD, see LICENSE for details.
""" """
@ -112,7 +112,7 @@ class CitationDefinitionTransform(SphinxTransform):
"""Mark citation definition labels as not smartquoted.""" """Mark citation definition labels as not smartquoted."""
default_priority = 619 default_priority = 619
def apply(self, **kwargs) -> None: def apply(self, **kwargs: Any) -> None:
domain = cast(CitationDomain, self.env.get_domain('citation')) domain = cast(CitationDomain, self.env.get_domain('citation'))
for node in self.document.traverse(nodes.citation): for node in self.document.traverse(nodes.citation):
# register citation node to domain # register citation node to domain
@ -131,7 +131,7 @@ class CitationReferenceTransform(SphinxTransform):
""" """
default_priority = 619 default_priority = 619
def apply(self, **kwargs) -> None: def apply(self, **kwargs: Any) -> None:
domain = cast(CitationDomain, self.env.get_domain('citation')) domain = cast(CitationDomain, self.env.get_domain('citation'))
for node in self.document.traverse(nodes.citation_reference): for node in self.document.traverse(nodes.citation_reference):
target = node.astext() target = node.astext()

View File

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

View File

@ -4,20 +4,26 @@
The index domain. 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. :license: BSD, see LICENSE for details.
""" """
from typing import Any, Dict, Iterable, List, Tuple 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 import addnodes
from sphinx.application import Sphinx
from sphinx.domains import Domain from sphinx.domains import Domain
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.util import logging from sphinx.util import logging
from sphinx.util import split_index_msg 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__) logger = logging.getLogger(__name__)
@ -54,8 +60,57 @@ class IndexDomain(Domain):
entries.append(entry) 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_domain(IndexDomain)
app.add_directive('index', IndexDirective)
app.add_role('index', IndexRole())
return { return {
'version': 'builtin', 'version': 'builtin',

View File

@ -4,7 +4,7 @@
The JavaScript domain. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The math domain. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The Python domain. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The reStructuredText domain. 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -4,7 +4,7 @@
Global creation environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,6 +4,6 @@
Sphinx environment adapters 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Assets adapter for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Index entries adapters for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """
import bisect import bisect

View File

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

View File

@ -4,7 +4,7 @@
The data collector components for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The image collector for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The dependencies collector components for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Index entries collector for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The metadata collector components for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
The title collector components for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Toctree collector for sphinx.environment. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Contains SphinxError and a few subclasses (in an extra module to avoid Contains SphinxError and a few subclasses (in an extra module to avoid
circular import problems). 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -10,7 +10,7 @@
Copyright 2008 Société des arts technologiques (SAT), Copyright 2008 Société des arts technologiques (SAT),
https://sat.qc.ca/ 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. :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) subpackages = [module_join(master_package, subroot, pkgname)
for pkgname in subpackages] for pkgname in subpackages]
# build a list of sub modules # 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 if not is_skipped_module(path.join(root, sub), opts, excludes) and
sub != INITPY] sub != INITPY]
submodules = [module_join(master_package, subroot, modname) submodules = [module_join(master_package, subroot, modname)

View File

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

View File

@ -4,7 +4,7 @@
Importer utilities for autodoc 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. :license: BSD, see LICENSE for details.
""" """
@ -12,7 +12,7 @@ import importlib
import traceback import traceback
import warnings import warnings
from collections import namedtuple 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.deprecation import RemovedInSphinx40Warning, deprecated_alias
from sphinx.util import logging from sphinx.util import logging
@ -101,12 +101,35 @@ def import_object(modname: str, objpath: List[str], objtype: str = '',
raise ImportError(errmsg) 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']) Attribute = namedtuple('Attribute', ['name', 'directly_defined', 'value'])
def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable, def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
analyzer: Any = None) -> Dict[str, Attribute]: analyzer: Any = None) -> Dict[str, Attribute]:
"""Get members and attributes of target object.""" """Get members and attributes of target object."""
from sphinx.ext.autodoc import INSTANCEATTR
# the members directly defined in the class # the members directly defined in the class
obj_dict = attrgetter(subject, '__dict__', {}) obj_dict = attrgetter(subject, '__dict__', {})
@ -140,10 +163,14 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
except AttributeError: except AttributeError:
continue 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: if analyzer:
# append instance attributes (cf. self.attr1) if analyzer knows # append instance attributes (cf. self.attr1) if analyzer knows
from sphinx.ext.autodoc import INSTANCEATTR
namespace = '.'.join(objpath) namespace = '.'.join(objpath)
for (ns, name) in analyzer.find_attr_docs(): for (ns, name) in analyzer.find_attr_docs():
if namespace == ns and name not in members: if namespace == ns and name not in members:

View File

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

View File

@ -48,7 +48,7 @@
resolved to a Python object, and otherwise it becomes simple emphasis. resolved to a Python object, and otherwise it becomes simple emphasis.
This can be used as the default role to make links 'smart'. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -13,7 +13,7 @@
generate: generate:
sphinx-autogen -o source/generated source/*.rst 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. :license: BSD, see LICENSE for details.
""" """
@ -62,7 +62,7 @@ class DummyApplication:
self._warncount = 0 self._warncount = 0
self.warningiserror = False self.warningiserror = False
def emit_firstresult(self, *args) -> None: def emit_firstresult(self, *args: Any) -> None:
pass pass
@ -71,13 +71,13 @@ def setup_documenters(app: Any) -> None:
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
FunctionDocumenter, MethodDocumenter, AttributeDocumenter, FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter, InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
SlotsAttributeDocumenter, SlotsAttributeDocumenter, DataDeclarationDocumenter,
) )
documenters = [ documenters = [
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
FunctionDocumenter, MethodDocumenter, AttributeDocumenter, FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter, InstanceAttributeDocumenter, DecoratorDocumenter, PropertyDocumenter,
SlotsAttributeDocumenter, SlotsAttributeDocumenter, DataDeclarationDocumenter,
] # type: List[Type[Documenter]] ] # type: List[Type[Documenter]]
for documenter in documenters: for documenter in documenters:
app.registry.add_documenter(documenter.objtype, documenter) 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 Check Python modules and C API for coverage. Mostly written by Josip
Dzolonga for the Google Highly Open Participation contest. 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. :license: BSD, see LICENSE for details.
""" """
@ -80,7 +80,7 @@ class CoverageBuilder(Builder):
def get_outdated_docs(self) -> str: def get_outdated_docs(self) -> str:
return 'coverage overview' return 'coverage overview'
def write(self, *ignored) -> None: def write(self, *ignored: Any) -> None:
self.py_undoc = {} # type: Dict[str, Dict[str, Any]] self.py_undoc = {} # type: Dict[str, Dict[str, Any]]
self.build_py_coverage() self.build_py_coverage()
self.write_py_coverage() self.write_py_coverage()

View File

@ -5,7 +5,7 @@
Mimic doctest by automatically executing code snippets and checking Mimic doctest by automatically executing code snippets and checking
their results. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Measure durations of Sphinx processing. 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. :license: BSD, see LICENSE for details.
""" """
@ -32,7 +32,7 @@ class DurationDomain(Domain):
def reading_durations(self) -> Dict[str, timedelta]: def reading_durations(self) -> Dict[str, timedelta]:
return self.data.setdefault('reading_durations', {}) 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 self.reading_durations[self.env.docname] = duration
def clear(self) -> None: def clear(self) -> None:
@ -69,7 +69,7 @@ def on_doctree_read(app: Sphinx, doctree: nodes.document) -> None:
domain.note_reading_duration(duration) 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.""" """Display duration ranking on current build."""
domain = cast(DurationDomain, app.env.get_domain('duration')) domain = cast(DurationDomain, app.env.get_domain('duration'))
durations = sorted(domain.reading_durations.items(), key=itemgetter(1), reverse=True) 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>`. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
To publish HTML docs at GitHub Pages, create .nojekyll file. 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. :license: BSD, see LICENSE for details.
""" """

View File

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

View File

@ -15,7 +15,7 @@
namespace of the project configuration (that is, all variables from namespace of the project configuration (that is, all variables from
``conf.py`` are available.) ``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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Image converter extension for Sphinx 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. :license: BSD, see LICENSE for details.
""" """
@ -27,6 +27,7 @@ class ImagemagickConverter(ImageConverter):
('image/svg+xml', 'image/png'), ('image/svg+xml', 'image/png'),
('image/gif', 'image/png'), ('image/gif', 'image/png'),
('application/pdf', 'image/png'), ('application/pdf', 'image/png'),
('application/illustrator', 'image/png'),
] ]
def is_available(self) -> bool: def is_available(self) -> bool:

View File

@ -4,7 +4,7 @@
Render math in HTML via dvipng or dvisvgm. 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. :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 The graph is inserted as a PNG+image map into HTML and a PDF in
LaTeX. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -19,7 +19,7 @@
also be specified individually, e.g. if the docs should be buildable also be specified individually, e.g. if the docs should be buildable
without Internet access. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -5,7 +5,7 @@
Set up everything for use of JSMath to display math in HTML Set up everything for use of JSMath to display math in HTML
via JavaScript. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Add external links to module code in Python object descriptions. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Set up math support in source files and LaTeX/text output. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -6,7 +6,7 @@
Sphinx's HTML writer -- requires the MathJax JavaScript library on your Sphinx's HTML writer -- requires the MathJax JavaScript library on your
webserver/computer. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Support for NumPy and Google style docstrings. 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. :license: BSD, see LICENSE for details.
""" """
@ -265,7 +265,7 @@ class Config:
'napoleon_custom_sections': (None, 'env') '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(): for name, (default, rebuild) in self._config_values.items():
setattr(self, name, default) setattr(self, name, default)
for name, value in settings.items(): for name, value in settings.items():

View File

@ -6,7 +6,7 @@
Classes for docstring parsing and formatting. 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. :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_.-]+)`|" _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) r" (?P<name2>~?[a-zA-Z0-9_.-]+))\s*", re.X)
def __init__(self, docstring: Union[str, List[str]], config: SphinxConfig = None, def __init__(self, docstring: Union[str, List[str]], config: SphinxConfig = None,
app: Sphinx = None, what: str = '', name: str = '', app: Sphinx = None, what: str = '', name: str = '',

View File

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

View File

@ -7,7 +7,7 @@
all todos of your project and lists them along with a backlink to the all todos of your project and lists them along with a backlink to the
original location. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Add links to module code in Python object descriptions. 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. :license: BSD, see LICENSE for details.
""" """

View File

@ -4,7 +4,7 @@
Utilities for Sphinx extensions. 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. :license: BSD, see LICENSE for details.
""" """
@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
class Extension: 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.name = name
self.module = module self.module = module
self.metadata = kwargs self.metadata = kwargs

View File

@ -4,7 +4,7 @@
Highlight code blocks using Pygments. 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. :license: BSD, see LICENSE for details.
""" """
@ -93,7 +93,7 @@ class PygmentsBridge:
else: else:
return get_style_by_name(stylename) return get_style_by_name(stylename)
def get_formatter(self, **kwargs) -> Formatter: def get_formatter(self, **kwargs: Any) -> Formatter:
kwargs.update(self.formatter_args) kwargs.update(self.formatter_args)
return self.formatter(**kwargs) return self.formatter(**kwargs)
@ -155,7 +155,7 @@ class PygmentsBridge:
return lexer return lexer
def highlight_block(self, source: str, lang: str, opts: Dict = None, 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): if not isinstance(source, str):
source = source.decode() source = source.decode()

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