mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge branch '3.x'
This commit is contained in:
commit
75203967d8
@ -8,4 +8,7 @@ jobs:
|
|||||||
- checkout
|
- checkout
|
||||||
- run: /python3.6/bin/pip install -U pip setuptools
|
- run: /python3.6/bin/pip install -U pip setuptools
|
||||||
- run: /python3.6/bin/pip install -U .[test]
|
- run: /python3.6/bin/pip install -U .[test]
|
||||||
- run: make test PYTHON=/python3.6/bin/python
|
- run: mkdir -p test-reports/pytest
|
||||||
|
- run: make test PYTHON=/python3.6/bin/python TEST=--junitxml=test-reports/pytest/results.xml
|
||||||
|
- store_test_results:
|
||||||
|
path: test-reports
|
||||||
|
7
CHANGES
7
CHANGES
@ -47,6 +47,7 @@ Deprecated
|
|||||||
been changed to Sphinx object
|
been changed to Sphinx object
|
||||||
* ``sphinx.ext.autosummary.generate.AutosummaryRenderer`` takes an object type
|
* ``sphinx.ext.autosummary.generate.AutosummaryRenderer`` takes an object type
|
||||||
as an argument
|
as an argument
|
||||||
|
* The ``ignore`` argument of ``sphinx.ext.autodoc.Documenter.get_doc()``
|
||||||
* The ``template_dir`` argument of ``sphinx.ext.autosummary.generate.
|
* The ``template_dir`` argument of ``sphinx.ext.autosummary.generate.
|
||||||
AutosummaryRenderer``
|
AutosummaryRenderer``
|
||||||
* The ``module`` argument of ``sphinx.ext.autosummary.generate.
|
* The ``module`` argument of ``sphinx.ext.autosummary.generate.
|
||||||
@ -55,6 +56,7 @@ Deprecated
|
|||||||
generate_autosummary_docs()``
|
generate_autosummary_docs()``
|
||||||
* The ``template_dir`` argument of ``sphinx.ext.autosummary.generate.
|
* The ``template_dir`` argument of ``sphinx.ext.autosummary.generate.
|
||||||
generate_autosummary_docs()``
|
generate_autosummary_docs()``
|
||||||
|
* The ``ignore`` argument of ``sphinx.util.docstring.prepare_docstring()``
|
||||||
* ``sphinx.ext.autosummary.generate.AutosummaryRenderer.exists()``
|
* ``sphinx.ext.autosummary.generate.AutosummaryRenderer.exists()``
|
||||||
|
|
||||||
Features added
|
Features added
|
||||||
@ -80,6 +82,7 @@ Features added
|
|||||||
to generate stub files recursively
|
to generate stub files recursively
|
||||||
* #4030: autosummary: Add :confval:`autosummary_context` to add template
|
* #4030: autosummary: Add :confval:`autosummary_context` to add template
|
||||||
variables for custom templates
|
variables for custom templates
|
||||||
|
* #7530: html: Support nested <kbd> elements
|
||||||
* #7481: html theme: Add right margin to footnote/citation labels
|
* #7481: html theme: Add right margin to footnote/citation labels
|
||||||
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
|
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
|
||||||
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
|
||||||
@ -98,6 +101,7 @@ Features added
|
|||||||
* C++, parse trailing return types.
|
* C++, parse trailing return types.
|
||||||
* #7143: py domain: Add ``:final:`` option to :rst:dir:`py:class:`,
|
* #7143: py domain: Add ``:final:`` option to :rst:dir:`py:class:`,
|
||||||
:rst:dir:`py:exception:` and :rst:dir:`py:method:` directives
|
:rst:dir:`py:exception:` and :rst:dir:`py:method:` directives
|
||||||
|
* #7582: napoleon: a type for attribute are represented like type annotation
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
@ -108,6 +112,9 @@ Bugs fixed
|
|||||||
* #7469: autodoc: The change of autodoc-process-docstring for variables is
|
* #7469: autodoc: The change of autodoc-process-docstring for variables is
|
||||||
cached unexpectedly
|
cached unexpectedly
|
||||||
* #7559: autodoc: misdetects a sync function is async
|
* #7559: autodoc: misdetects a sync function is async
|
||||||
|
* #6857: autodoc: failed to detect a classmethod on Enum class
|
||||||
|
* #7562: autodoc: a typehint contains spaces is wrongly rendered under
|
||||||
|
autodoc_typehints='description' mode
|
||||||
* #7535: sphinx-autogen: crashes when custom template uses inheritance
|
* #7535: sphinx-autogen: crashes when custom template uses inheritance
|
||||||
* #7536: sphinx-autogen: crashes when template uses i18n feature
|
* #7536: sphinx-autogen: crashes when template uses i18n feature
|
||||||
* #2785: html: Bad alignment of equation links
|
* #2785: html: Bad alignment of equation links
|
||||||
|
@ -69,6 +69,11 @@ The following is a list of deprecated interfaces.
|
|||||||
- 5.0
|
- 5.0
|
||||||
- N/A
|
- N/A
|
||||||
|
|
||||||
|
* - The ``ignore`` argument of ``sphinx.ext.autodoc.Documenter.get_doc()``
|
||||||
|
- 3.1
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
* - The ``template_dir`` argument of
|
* - The ``template_dir`` argument of
|
||||||
``sphinx.ext.autosummary.generate.AutosummaryRenderer``
|
``sphinx.ext.autosummary.generate.AutosummaryRenderer``
|
||||||
- 3.1
|
- 3.1
|
||||||
@ -98,6 +103,11 @@ The following is a list of deprecated interfaces.
|
|||||||
- 5.0
|
- 5.0
|
||||||
- N/A
|
- N/A
|
||||||
|
|
||||||
|
* - The ``ignore`` argument of ``sphinx.util.docstring.prepare_docstring()``
|
||||||
|
- 3.1
|
||||||
|
- 5.0
|
||||||
|
- N/A
|
||||||
|
|
||||||
* - ``desc_signature['first']``
|
* - ``desc_signature['first']``
|
||||||
-
|
-
|
||||||
- 3.0
|
- 3.0
|
||||||
|
@ -1227,6 +1227,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
# load default math renderer
|
# load default math renderer
|
||||||
app.setup_extension('sphinx.ext.mathjax')
|
app.setup_extension('sphinx.ext.mathjax')
|
||||||
|
|
||||||
|
# load transforms for HTML builder
|
||||||
|
app.setup_extension('sphinx.builders.html.transforms')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
'parallel_read_safe': True,
|
'parallel_read_safe': True,
|
||||||
|
69
sphinx/builders/html/transforms.py
Normal file
69
sphinx/builders/html/transforms.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
"""
|
||||||
|
sphinx.builders.html.transforms
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Transforms for HTML builder.
|
||||||
|
|
||||||
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
||||||
|
:license: BSD, see LICENSE for details.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from docutils import nodes
|
||||||
|
|
||||||
|
from sphinx.application import Sphinx
|
||||||
|
from sphinx.transforms.post_transforms import SphinxPostTransform
|
||||||
|
from sphinx.util.nodes import NodeMatcher
|
||||||
|
|
||||||
|
|
||||||
|
class KeyboardTransform(SphinxPostTransform):
|
||||||
|
"""Transform :kbd: role to more detailed form.
|
||||||
|
|
||||||
|
Before::
|
||||||
|
|
||||||
|
<literal class="kbd">
|
||||||
|
Control-x
|
||||||
|
|
||||||
|
After::
|
||||||
|
|
||||||
|
<literal class="kbd">
|
||||||
|
<literal class="kbd">
|
||||||
|
Control
|
||||||
|
-
|
||||||
|
<literal class="kbd">
|
||||||
|
x
|
||||||
|
"""
|
||||||
|
default_priority = 400
|
||||||
|
builders = ('html',)
|
||||||
|
pattern = re.compile(r'(-|\+|\^|\s+)')
|
||||||
|
|
||||||
|
def run(self, **kwargs: Any) -> None:
|
||||||
|
matcher = NodeMatcher(nodes.literal, classes=["kbd"])
|
||||||
|
for node in self.document.traverse(matcher): # type: nodes.literal
|
||||||
|
parts = self.pattern.split(node[-1].astext())
|
||||||
|
if len(parts) == 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
node.pop()
|
||||||
|
while parts:
|
||||||
|
key = parts.pop(0)
|
||||||
|
node += nodes.literal('', key, classes=["kbd"])
|
||||||
|
|
||||||
|
try:
|
||||||
|
# key separator (ex. -, +, ^)
|
||||||
|
sep = parts.pop(0)
|
||||||
|
node += nodes.Text(sep)
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def setup(app: Sphinx) -> Dict[str, Any]:
|
||||||
|
app.add_post_transform(KeyboardTransform)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'version': 'builtin',
|
||||||
|
'parallel_read_safe': True,
|
||||||
|
'parallel_write_safe': True,
|
||||||
|
}
|
@ -775,10 +775,11 @@ class PyDecoratorMixin:
|
|||||||
if cls.__name__ != 'DirectiveAdapter':
|
if cls.__name__ != 'DirectiveAdapter':
|
||||||
warnings.warn('PyDecoratorMixin is deprecated. '
|
warnings.warn('PyDecoratorMixin is deprecated. '
|
||||||
'Please check the implementation of %s' % cls,
|
'Please check the implementation of %s' % cls,
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
warnings.warn('PyDecoratorMixin is deprecated', RemovedInSphinx50Warning)
|
warnings.warn('PyDecoratorMixin is deprecated',
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
ret = super().handle_signature(sig, signode) # type: ignore
|
ret = super().handle_signature(sig, signode) # type: ignore
|
||||||
signode.insert(0, addnodes.desc_addname('@', '@'))
|
signode.insert(0, addnodes.desc_addname('@', '@'))
|
||||||
|
@ -645,7 +645,7 @@ class StandardDomain(Domain):
|
|||||||
|
|
||||||
def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None:
|
def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None:
|
||||||
warnings.warn('StandardDomain.add_object() is deprecated.',
|
warnings.warn('StandardDomain.add_object() is deprecated.',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
self.objects[objtype, name] = (docname, labelid)
|
self.objects[objtype, name] = (docname, labelid)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -395,9 +395,9 @@ class Documenter:
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
# retry without arguments for old documenters
|
# retry without arguments for old documenters
|
||||||
args = self.format_args()
|
args = self.format_args()
|
||||||
except Exception as err:
|
except Exception:
|
||||||
logger.warning(__('error while formatting arguments for %s: %s') %
|
logger.warning(__('error while formatting arguments for %s:') %
|
||||||
(self.fullname, err), type='autodoc')
|
self.fullname, type='autodoc', exc_info=True)
|
||||||
args = None
|
args = None
|
||||||
|
|
||||||
retann = self.retann
|
retann = self.retann
|
||||||
@ -428,8 +428,12 @@ class Documenter:
|
|||||||
# etc. don't support a prepended module name
|
# etc. don't support a prepended module name
|
||||||
self.add_line(' :module: %s' % self.modname, sourcename)
|
self.add_line(' :module: %s' % self.modname, sourcename)
|
||||||
|
|
||||||
def get_doc(self, ignore: int = 1) -> List[List[str]]:
|
def get_doc(self, ignore: int = None) -> List[List[str]]:
|
||||||
"""Decode and return lines of the docstring(s) for the object."""
|
"""Decode and return lines of the docstring(s) for the object."""
|
||||||
|
if ignore is not None:
|
||||||
|
warnings.warn("The 'ignore' argument to autodoc.%s.get_doc() is deprecated."
|
||||||
|
% self.__class__.__name__,
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
docstring = getdoc(self.object, self.get_attr,
|
docstring = getdoc(self.object, self.get_attr,
|
||||||
self.env.config.autodoc_inherit_docstrings,
|
self.env.config.autodoc_inherit_docstrings,
|
||||||
self.parent, self.object_name)
|
self.parent, self.object_name)
|
||||||
@ -741,8 +745,8 @@ class Documenter:
|
|||||||
# parse right now, to get PycodeErrors on parsing (results will
|
# parse right now, to get PycodeErrors on parsing (results will
|
||||||
# be cached anyway)
|
# be cached anyway)
|
||||||
self.analyzer.find_attr_docs()
|
self.analyzer.find_attr_docs()
|
||||||
except PycodeError as err:
|
except PycodeError:
|
||||||
logger.debug('[autodoc] module analyzer failed: %s', err)
|
logger.debug('[autodoc] module analyzer failed:', exc_info=True)
|
||||||
# no source file -- e.g. for builtin and C modules
|
# no source file -- e.g. for builtin and C modules
|
||||||
self.analyzer = None
|
self.analyzer = None
|
||||||
# at least add the module.__file__ as a dependency
|
# at least add the module.__file__ as a dependency
|
||||||
@ -844,7 +848,7 @@ class ModuleDocumenter(Documenter):
|
|||||||
if self.options.deprecated:
|
if self.options.deprecated:
|
||||||
self.add_line(' :deprecated:', sourcename)
|
self.add_line(' :deprecated:', sourcename)
|
||||||
|
|
||||||
def get_object_members(self, want_all: bool) -> Tuple[bool, List[Tuple[str, object]]]:
|
def get_object_members(self, want_all: bool) -> Tuple[bool, List[Tuple[str, Any]]]:
|
||||||
if want_all:
|
if want_all:
|
||||||
if (self.options.ignore_module_all or not
|
if (self.options.ignore_module_all or not
|
||||||
hasattr(self.object, '__all__')):
|
hasattr(self.object, '__all__')):
|
||||||
@ -970,7 +974,7 @@ class DocstringSignatureMixin:
|
|||||||
break
|
break
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_doc(self, ignore: int = 1) -> List[List[str]]:
|
def get_doc(self, ignore: int = None) -> List[List[str]]:
|
||||||
lines = getattr(self, '_new_docstrings', None)
|
lines = getattr(self, '_new_docstrings', None)
|
||||||
if lines is not None:
|
if lines is not None:
|
||||||
return lines
|
return lines
|
||||||
@ -1226,7 +1230,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
|
|||||||
self.add_line(' ' + _('Bases: %s') % ', '.join(bases),
|
self.add_line(' ' + _('Bases: %s') % ', '.join(bases),
|
||||||
sourcename)
|
sourcename)
|
||||||
|
|
||||||
def get_doc(self, ignore: int = 1) -> List[List[str]]:
|
def get_doc(self, ignore: int = None) -> List[List[str]]:
|
||||||
lines = getattr(self, '_new_docstrings', None)
|
lines = getattr(self, '_new_docstrings', None)
|
||||||
if lines is not None:
|
if lines is not None:
|
||||||
return lines
|
return lines
|
||||||
@ -1719,8 +1723,12 @@ class SlotsAttributeDocumenter(AttributeDocumenter):
|
|||||||
self.env.note_reread()
|
self.env.note_reread()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def get_doc(self, ignore: int = 1) -> List[List[str]]:
|
def get_doc(self, ignore: int = None) -> List[List[str]]:
|
||||||
"""Decode and return lines of the docstring(s) for the object."""
|
"""Decode and return lines of the docstring(s) for the object."""
|
||||||
|
if ignore is not None:
|
||||||
|
warnings.warn("The 'ignore' argument to autodoc.%s.get_doc() is deprecated."
|
||||||
|
% self.__class__.__name__,
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
name = self.objpath[-1]
|
name = self.objpath[-1]
|
||||||
__slots__ = safe_getattr(self.parent, '__slots__', [])
|
__slots__ = safe_getattr(self.parent, '__slots__', [])
|
||||||
if isinstance(__slots__, dict) and isinstance(__slots__.get(name), str):
|
if isinstance(__slots__, dict) and isinstance(__slots__.get(name), str):
|
||||||
@ -1732,7 +1740,7 @@ class SlotsAttributeDocumenter(AttributeDocumenter):
|
|||||||
|
|
||||||
def get_documenters(app: Sphinx) -> Dict[str, Type[Documenter]]:
|
def get_documenters(app: Sphinx) -> Dict[str, Type[Documenter]]:
|
||||||
"""Returns registered Documenter classes"""
|
"""Returns registered Documenter classes"""
|
||||||
warnings.warn("get_documenters() is deprecated.", RemovedInSphinx50Warning)
|
warnings.warn("get_documenters() is deprecated.", RemovedInSphinx50Warning, stacklevel=2)
|
||||||
return app.registry.documenters
|
return app.registry.documenters
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import traceback
|
|||||||
import warnings
|
import warnings
|
||||||
from typing import Any, Callable, Dict, List, Mapping, NamedTuple, Tuple
|
from typing import Any, Callable, Dict, List, Mapping, NamedTuple, Tuple
|
||||||
|
|
||||||
|
from sphinx.pycode import ModuleAnalyzer
|
||||||
from sphinx.util import logging
|
from sphinx.util import logging
|
||||||
from sphinx.util.inspect import isclass, isenumclass, safe_getattr
|
from sphinx.util.inspect import isclass, isenumclass, safe_getattr
|
||||||
|
|
||||||
@ -127,7 +128,7 @@ class Attribute(NamedTuple):
|
|||||||
|
|
||||||
|
|
||||||
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: ModuleAnalyzer = None) -> Dict[str, Attribute]:
|
||||||
"""Get members and attributes of target object."""
|
"""Get members and attributes of target object."""
|
||||||
from sphinx.ext.autodoc import INSTANCEATTR
|
from sphinx.ext.autodoc import INSTANCEATTR
|
||||||
|
|
||||||
@ -143,8 +144,9 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
|
|||||||
members[name] = Attribute(name, True, value)
|
members[name] = Attribute(name, True, value)
|
||||||
|
|
||||||
superclass = subject.__mro__[1]
|
superclass = subject.__mro__[1]
|
||||||
for name, value in obj_dict.items():
|
for name in obj_dict:
|
||||||
if name not in superclass.__dict__:
|
if name not in superclass.__dict__:
|
||||||
|
value = safe_getattr(subject, name)
|
||||||
members[name] = Attribute(name, True, value)
|
members[name] = Attribute(name, True, value)
|
||||||
|
|
||||||
# members in __slots__
|
# members in __slots__
|
||||||
|
@ -122,7 +122,7 @@ class AutosummaryRenderer:
|
|||||||
RemovedInSphinx50Warning, stacklevel=2)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
if template_dir:
|
if template_dir:
|
||||||
warnings.warn('template_dir argument for AutosummaryRenderer is deprecated.',
|
warnings.warn('template_dir argument for AutosummaryRenderer is deprecated.',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
|
system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
|
||||||
loader = SphinxTemplateLoader(app.srcdir, app.config.templates_path,
|
loader = SphinxTemplateLoader(app.srcdir, app.config.templates_path,
|
||||||
@ -274,11 +274,11 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None,
|
|||||||
overwrite: bool = True) -> None:
|
overwrite: bool = True) -> None:
|
||||||
if builder:
|
if builder:
|
||||||
warnings.warn('builder argument for generate_autosummary_docs() is deprecated.',
|
warnings.warn('builder argument for generate_autosummary_docs() is deprecated.',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
if template_dir:
|
if template_dir:
|
||||||
warnings.warn('template_dir argument for generate_autosummary_docs() is deprecated.',
|
warnings.warn('template_dir argument for generate_autosummary_docs() is deprecated.',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
showed_sources = list(sorted(sources))
|
showed_sources = list(sorted(sources))
|
||||||
if len(showed_sources) > 20:
|
if len(showed_sources) > 20:
|
||||||
@ -371,7 +371,7 @@ def find_autosummary_in_docstring(name: str, module: str = None, filename: str =
|
|||||||
"""
|
"""
|
||||||
if module:
|
if module:
|
||||||
warnings.warn('module argument for find_autosummary_in_docstring() is deprecated.',
|
warnings.warn('module argument for find_autosummary_in_docstring() is deprecated.',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
real_name, obj, parent, modname = import_by_name(name)
|
real_name, obj, parent, modname = import_by_name(name)
|
||||||
|
@ -168,11 +168,10 @@ class Config:
|
|||||||
**If False**::
|
**If False**::
|
||||||
|
|
||||||
.. attribute:: attr1
|
.. attribute:: attr1
|
||||||
|
:type: int
|
||||||
|
|
||||||
Description of `attr1`
|
Description of `attr1`
|
||||||
|
|
||||||
:type: int
|
|
||||||
|
|
||||||
napoleon_use_param : :obj:`bool` (Defaults to True)
|
napoleon_use_param : :obj:`bool` (Defaults to True)
|
||||||
True to use a ``:param:`` role for each function parameter. False to
|
True to use a ``:param:`` role for each function parameter. False to
|
||||||
use a single ``:parameters:`` role for all the parameters.
|
use a single ``:parameters:`` role for all the parameters.
|
||||||
|
@ -584,13 +584,12 @@ class GoogleDocstring:
|
|||||||
lines.append('.. attribute:: ' + _name)
|
lines.append('.. attribute:: ' + _name)
|
||||||
if self._opt and 'noindex' in self._opt:
|
if self._opt and 'noindex' in self._opt:
|
||||||
lines.append(' :noindex:')
|
lines.append(' :noindex:')
|
||||||
|
if _type:
|
||||||
|
lines.extend(self._indent([':type: %s' % _type], 3))
|
||||||
lines.append('')
|
lines.append('')
|
||||||
|
|
||||||
fields = self._format_field('', '', _desc)
|
fields = self._format_field('', '', _desc)
|
||||||
lines.extend(self._indent(fields, 3))
|
lines.extend(self._indent(fields, 3))
|
||||||
if _type:
|
|
||||||
lines.append('')
|
|
||||||
lines.extend(self._indent([':type: %s' % _type], 3))
|
|
||||||
lines.append('')
|
lines.append('')
|
||||||
if self._config.napoleon_use_ivar:
|
if self._config.napoleon_use_ivar:
|
||||||
lines.append('')
|
lines.append('')
|
||||||
|
@ -63,7 +63,7 @@ class Parser(docutils.parsers.Parser):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def app(self) -> "Sphinx":
|
def app(self) -> "Sphinx":
|
||||||
warnings.warn('parser.app is deprecated.', RemovedInSphinx50Warning)
|
warnings.warn('parser.app is deprecated.', RemovedInSphinx50Warning, stacklevel=2)
|
||||||
return self._app
|
return self._app
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,10 +10,13 @@
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
import warnings
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
|
|
||||||
from docutils.parsers.rst.states import Body
|
from docutils.parsers.rst.states import Body
|
||||||
|
|
||||||
|
from sphinx.deprecation import RemovedInSphinx50Warning
|
||||||
|
|
||||||
|
|
||||||
field_list_item_re = re.compile(Body.patterns['field_marker'])
|
field_list_item_re = re.compile(Body.patterns['field_marker'])
|
||||||
|
|
||||||
@ -42,7 +45,7 @@ def extract_metadata(s: str) -> Dict[str, str]:
|
|||||||
return metadata
|
return metadata
|
||||||
|
|
||||||
|
|
||||||
def prepare_docstring(s: str, ignore: int = 1, tabsize: int = 8) -> List[str]:
|
def prepare_docstring(s: str, ignore: int = None, tabsize: int = 8) -> List[str]:
|
||||||
"""Convert a docstring into lines of parseable reST. Remove common leading
|
"""Convert a docstring into lines of parseable reST. Remove common leading
|
||||||
indentation, where the indentation of a given number of lines (usually just
|
indentation, where the indentation of a given number of lines (usually just
|
||||||
one) is ignored.
|
one) is ignored.
|
||||||
@ -51,6 +54,12 @@ def prepare_docstring(s: str, ignore: int = 1, tabsize: int = 8) -> List[str]:
|
|||||||
ViewList (used as argument of nested_parse().) An empty line is added to
|
ViewList (used as argument of nested_parse().) An empty line is added to
|
||||||
act as a separator between this docstring and following content.
|
act as a separator between this docstring and following content.
|
||||||
"""
|
"""
|
||||||
|
if ignore is None:
|
||||||
|
ignore = 1
|
||||||
|
else:
|
||||||
|
warnings.warn("The 'ignore' argument to parepare_docstring() is deprecated.",
|
||||||
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
lines = s.expandtabs(tabsize).splitlines()
|
lines = s.expandtabs(tabsize).splitlines()
|
||||||
# Find minimum indentation of any non-blank lines after ignored lines.
|
# Find minimum indentation of any non-blank lines after ignored lines.
|
||||||
margin = sys.maxsize
|
margin = sys.maxsize
|
||||||
|
@ -58,7 +58,7 @@ def getargspec(func: Callable) -> Any:
|
|||||||
"""Like inspect.getfullargspec but supports bound methods, and wrapped
|
"""Like inspect.getfullargspec but supports bound methods, and wrapped
|
||||||
methods."""
|
methods."""
|
||||||
warnings.warn('sphinx.ext.inspect.getargspec() is deprecated',
|
warnings.warn('sphinx.ext.inspect.getargspec() is deprecated',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
# On 3.5+, signature(int) or similar raises ValueError. On 3.4, it
|
# On 3.5+, signature(int) or similar raises ValueError. On 3.4, it
|
||||||
# succeeds with a bogus signature. We want a TypeError uniformly, to
|
# succeeds with a bogus signature. We want a TypeError uniformly, to
|
||||||
# match historical behavior.
|
# match historical behavior.
|
||||||
|
@ -411,9 +411,13 @@ class WarningIsErrorFilter(logging.Filter):
|
|||||||
message = record.msg # use record.msg itself
|
message = record.msg # use record.msg itself
|
||||||
|
|
||||||
if location:
|
if location:
|
||||||
raise SphinxWarning(location + ":" + str(message))
|
exc = SphinxWarning(location + ":" + str(message))
|
||||||
else:
|
else:
|
||||||
raise SphinxWarning(message)
|
exc = SphinxWarning(message)
|
||||||
|
if record.exc_info is not None:
|
||||||
|
raise exc from record.exc_info[1]
|
||||||
|
else:
|
||||||
|
raise exc
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -58,8 +58,8 @@ class NodeMatcher:
|
|||||||
# => [<reference ...>, <reference ...>, ...]
|
# => [<reference ...>, <reference ...>, ...]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, *classes: "Type[Node]", **attrs: Any) -> None:
|
def __init__(self, *node_classes: "Type[Node]", **attrs: Any) -> None:
|
||||||
self.classes = classes
|
self.classes = node_classes
|
||||||
self.attrs = attrs
|
self.attrs = attrs
|
||||||
|
|
||||||
def match(self, node: Node) -> bool:
|
def match(self, node: Node) -> bool:
|
||||||
|
@ -93,7 +93,7 @@ class LaTeXWriter(writers.Writer):
|
|||||||
visitor = self.builder.create_translator(self.document, self.builder, self.theme)
|
visitor = self.builder.create_translator(self.document, self.builder, self.theme)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
warnings.warn('LaTeXTranslator now takes 3rd argument; "theme".',
|
warnings.warn('LaTeXTranslator now takes 3rd argument; "theme".',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
visitor = self.builder.create_translator(self.document, self.builder)
|
visitor = self.builder.create_translator(self.document, self.builder)
|
||||||
|
|
||||||
self.document.walkabout(visitor)
|
self.document.walkabout(visitor)
|
||||||
@ -289,7 +289,7 @@ class LaTeXTranslator(SphinxTranslator):
|
|||||||
|
|
||||||
if theme is None:
|
if theme is None:
|
||||||
warnings.warn('LaTeXTranslator now takes 3rd argument; "theme".',
|
warnings.warn('LaTeXTranslator now takes 3rd argument; "theme".',
|
||||||
RemovedInSphinx50Warning)
|
RemovedInSphinx50Warning, stacklevel=2)
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
self.in_title = 0
|
self.in_title = 0
|
||||||
|
@ -16,3 +16,8 @@ class EnumCls(enum.Enum):
|
|||||||
def say_hello(self):
|
def say_hello(self):
|
||||||
"""a method says hello to you."""
|
"""a method says hello to you."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def say_goodbye(cls):
|
||||||
|
"""a classmethod says good-bye to you."""
|
||||||
|
pass
|
||||||
|
@ -1112,8 +1112,7 @@ def test_slots(app):
|
|||||||
|
|
||||||
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
@pytest.mark.sphinx('html', testroot='ext-autodoc')
|
||||||
def test_enum_class(app):
|
def test_enum_class(app):
|
||||||
options = {"members": None,
|
options = {"members": None}
|
||||||
"undoc-members": True}
|
|
||||||
actual = do_autodoc(app, 'class', 'target.enum.EnumCls', options)
|
actual = do_autodoc(app, 'class', 'target.enum.EnumCls', options)
|
||||||
assert list(actual) == [
|
assert list(actual) == [
|
||||||
'',
|
'',
|
||||||
@ -1123,6 +1122,13 @@ def test_enum_class(app):
|
|||||||
' this is enum class',
|
' this is enum class',
|
||||||
'',
|
'',
|
||||||
'',
|
'',
|
||||||
|
' .. py:method:: EnumCls.say_goodbye()',
|
||||||
|
' :module: target.enum',
|
||||||
|
' :classmethod:',
|
||||||
|
'',
|
||||||
|
' a classmethod says good-bye to you.',
|
||||||
|
'',
|
||||||
|
'',
|
||||||
' .. py:method:: EnumCls.say_hello()',
|
' .. py:method:: EnumCls.say_hello()',
|
||||||
' :module: target.enum',
|
' :module: target.enum',
|
||||||
'',
|
'',
|
||||||
@ -1149,11 +1155,6 @@ def test_enum_class(app):
|
|||||||
'',
|
'',
|
||||||
' doc for val3',
|
' doc for val3',
|
||||||
'',
|
'',
|
||||||
'',
|
|
||||||
' .. py:attribute:: EnumCls.val4',
|
|
||||||
' :module: target.enum',
|
|
||||||
' :value: 34',
|
|
||||||
''
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# checks for an attribute of EnumClass
|
# checks for an attribute of EnumClass
|
||||||
|
@ -53,22 +53,19 @@ class NamedtupleSubclassTest(BaseDocstringTest):
|
|||||||
Sample namedtuple subclass
|
Sample namedtuple subclass
|
||||||
|
|
||||||
.. attribute:: attr1
|
.. attribute:: attr1
|
||||||
|
:type: Arbitrary type
|
||||||
|
|
||||||
Quick description of attr1
|
Quick description of attr1
|
||||||
|
|
||||||
:type: Arbitrary type
|
|
||||||
|
|
||||||
.. attribute:: attr2
|
.. attribute:: attr2
|
||||||
|
:type: Another arbitrary type
|
||||||
|
|
||||||
Quick description of attr2
|
Quick description of attr2
|
||||||
|
|
||||||
:type: Another arbitrary type
|
|
||||||
|
|
||||||
.. attribute:: attr3
|
.. attribute:: attr3
|
||||||
|
:type: Type
|
||||||
|
|
||||||
Adds a newline after the type
|
Adds a newline after the type
|
||||||
|
|
||||||
:type: Type
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
@ -412,10 +409,9 @@ Attributes:
|
|||||||
actual = str(GoogleDocstring(docstring))
|
actual = str(GoogleDocstring(docstring))
|
||||||
expected = """\
|
expected = """\
|
||||||
.. attribute:: in_attr
|
.. attribute:: in_attr
|
||||||
|
:type: :class:`numpy.ndarray`
|
||||||
|
|
||||||
super-dooper attribute
|
super-dooper attribute
|
||||||
|
|
||||||
:type: :class:`numpy.ndarray`
|
|
||||||
"""
|
"""
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
@ -427,10 +423,9 @@ Attributes:
|
|||||||
actual = str(GoogleDocstring(docstring))
|
actual = str(GoogleDocstring(docstring))
|
||||||
expected = """\
|
expected = """\
|
||||||
.. attribute:: in_attr
|
.. attribute:: in_attr
|
||||||
|
:type: numpy.ndarray
|
||||||
|
|
||||||
super-dooper attribute
|
super-dooper attribute
|
||||||
|
|
||||||
:type: numpy.ndarray
|
|
||||||
"""
|
"""
|
||||||
self.assertEqual(expected, actual)
|
self.assertEqual(expected, actual)
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ from docutils.parsers.rst import Parser as RstParser
|
|||||||
from docutils.transforms.universal import SmartQuotes
|
from docutils.transforms.universal import SmartQuotes
|
||||||
|
|
||||||
from sphinx import addnodes
|
from sphinx import addnodes
|
||||||
|
from sphinx.builders.html.transforms import KeyboardTransform
|
||||||
from sphinx.builders.latex import LaTeXBuilder
|
from sphinx.builders.latex import LaTeXBuilder
|
||||||
from sphinx.roles import XRefRole
|
from sphinx.roles import XRefRole
|
||||||
from sphinx.testing.util import Struct, assert_node
|
from sphinx.testing.util import Struct, assert_node
|
||||||
@ -94,6 +95,7 @@ class ForgivingLaTeXTranslator(LaTeXTranslator, ForgivingTranslator):
|
|||||||
def verify_re_html(app, parse):
|
def verify_re_html(app, parse):
|
||||||
def verify(rst, html_expected):
|
def verify(rst, html_expected):
|
||||||
document = parse(rst)
|
document = parse(rst)
|
||||||
|
KeyboardTransform(document).apply()
|
||||||
html_translator = ForgivingHTMLTranslator(document, app.builder)
|
html_translator = ForgivingHTMLTranslator(document, app.builder)
|
||||||
document.walkabout(html_translator)
|
document.walkabout(html_translator)
|
||||||
html_translated = ''.join(html_translator.fragment).strip()
|
html_translated = ''.join(html_translator.fragment).strip()
|
||||||
@ -237,6 +239,32 @@ def get_verifier(verify, verify_re):
|
|||||||
'<p><kbd class="kbd docutils literal notranslate">space</kbd></p>',
|
'<p><kbd class="kbd docutils literal notranslate">space</kbd></p>',
|
||||||
'\\sphinxkeyboard{\\sphinxupquote{space}}',
|
'\\sphinxkeyboard{\\sphinxupquote{space}}',
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
# kbd role
|
||||||
|
'verify',
|
||||||
|
':kbd:`Control+X`',
|
||||||
|
('<p><kbd class="kbd docutils literal notranslate">'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">Control</kbd>'
|
||||||
|
'+'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">X</kbd>'
|
||||||
|
'</kbd></p>'),
|
||||||
|
'\\sphinxkeyboard{\\sphinxupquote{Control+X}}',
|
||||||
|
),
|
||||||
|
(
|
||||||
|
# kbd role
|
||||||
|
'verify',
|
||||||
|
':kbd:`M-x M-s`',
|
||||||
|
('<p><kbd class="kbd docutils literal notranslate">'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">M</kbd>'
|
||||||
|
'-'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">x</kbd>'
|
||||||
|
' '
|
||||||
|
'<kbd class="kbd docutils literal notranslate">M</kbd>'
|
||||||
|
'-'
|
||||||
|
'<kbd class="kbd docutils literal notranslate">s</kbd>'
|
||||||
|
'</kbd></p>'),
|
||||||
|
'\\sphinxkeyboard{\\sphinxupquote{M\\sphinxhyphen{}x M\\sphinxhyphen{}s}}',
|
||||||
|
),
|
||||||
(
|
(
|
||||||
# non-interpolation of dashes in option role
|
# non-interpolation of dashes in option role
|
||||||
'verify_re',
|
'verify_re',
|
||||||
|
Loading…
Reference in New Issue
Block a user