Skip to content

Commit

Permalink
Merge branch '3.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
tk0miya committed May 3, 2020
2 parents e7e9b4c + 787fda8 commit 7520396
Show file tree
Hide file tree
Showing 22 changed files with 195 additions and 52 deletions.
5 changes: 4 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ jobs:
- checkout
- run: /python3.6/bin/pip install -U pip setuptools
- 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 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Deprecated
been changed to Sphinx object
* ``sphinx.ext.autosummary.generate.AutosummaryRenderer`` takes an object type
as an argument
* The ``ignore`` argument of ``sphinx.ext.autodoc.Documenter.get_doc()``
* The ``template_dir`` argument of ``sphinx.ext.autosummary.generate.
AutosummaryRenderer``
* The ``module`` argument of ``sphinx.ext.autosummary.generate.
Expand All @@ -55,6 +56,7 @@ Deprecated
generate_autosummary_docs()``
* The ``template_dir`` argument of ``sphinx.ext.autosummary.generate.
generate_autosummary_docs()``
* The ``ignore`` argument of ``sphinx.util.docstring.prepare_docstring()``
* ``sphinx.ext.autosummary.generate.AutosummaryRenderer.exists()``

Features added
Expand All @@ -80,6 +82,7 @@ Features added
to generate stub files recursively
* #4030: autosummary: Add :confval:`autosummary_context` to add template
variables for custom templates
* #7530: html: Support nested <kbd> elements
* #7481: html theme: Add right margin to footnote/citation labels
* #7482: html theme: CSS spacing for code blocks with captions and line numbers
* #7443: html theme: Add new options :confval:`globaltoc_collapse` and
Expand All @@ -98,6 +101,7 @@ Features added
* C++, parse trailing return types.
* #7143: py domain: Add ``:final:`` option to :rst:dir:`py:class:`,
:rst:dir:`py:exception:` and :rst:dir:`py:method:` directives
* #7582: napoleon: a type for attribute are represented like type annotation

Bugs fixed
----------
Expand All @@ -108,6 +112,9 @@ Bugs fixed
* #7469: autodoc: The change of autodoc-process-docstring for variables is
cached unexpectedly
* #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
* #7536: sphinx-autogen: crashes when template uses i18n feature
* #2785: html: Bad alignment of equation links
Expand Down
10 changes: 10 additions & 0 deletions doc/extdev/deprecated.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ The following is a list of deprecated interfaces.
- 5.0
- N/A

* - The ``ignore`` argument of ``sphinx.ext.autodoc.Documenter.get_doc()``
- 3.1
- 5.0
- N/A

* - The ``template_dir`` argument of
``sphinx.ext.autosummary.generate.AutosummaryRenderer``
- 3.1
Expand Down Expand Up @@ -98,6 +103,11 @@ The following is a list of deprecated interfaces.
- 5.0
- N/A

* - The ``ignore`` argument of ``sphinx.util.docstring.prepare_docstring()``
- 3.1
- 5.0
- N/A

* - ``desc_signature['first']``
-
- 3.0
Expand Down
3 changes: 3 additions & 0 deletions sphinx/builders/html/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
# load default math renderer
app.setup_extension('sphinx.ext.mathjax')

# load transforms for HTML builder
app.setup_extension('sphinx.builders.html.transforms')

return {
'version': 'builtin',
'parallel_read_safe': True,
Expand Down
69 changes: 69 additions & 0 deletions sphinx/builders/html/transforms.py
Original file line number Diff line number Diff line change
@@ -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,
}
5 changes: 3 additions & 2 deletions sphinx/domains/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,10 +775,11 @@ def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]
if cls.__name__ != 'DirectiveAdapter':
warnings.warn('PyDecoratorMixin is deprecated. '
'Please check the implementation of %s' % cls,
RemovedInSphinx50Warning)
RemovedInSphinx50Warning, stacklevel=2)
break
else:
warnings.warn('PyDecoratorMixin is deprecated', RemovedInSphinx50Warning)
warnings.warn('PyDecoratorMixin is deprecated',
RemovedInSphinx50Warning, stacklevel=2)

ret = super().handle_signature(sig, signode) # type: ignore
signode.insert(0, addnodes.desc_addname('@', '@'))
Expand Down
2 changes: 1 addition & 1 deletion sphinx/domains/std.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,7 @@ def note_object(self, objtype: str, name: str, labelid: str, location: Any = Non

def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None:
warnings.warn('StandardDomain.add_object() is deprecated.',
RemovedInSphinx50Warning)
RemovedInSphinx50Warning, stacklevel=2)
self.objects[objtype, name] = (docname, labelid)

@property
Expand Down
30 changes: 19 additions & 11 deletions sphinx/ext/autodoc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,9 @@ def format_signature(self, **kwargs: Any) -> str:
except TypeError:
# retry without arguments for old documenters
args = self.format_args()
except Exception as err:
logger.warning(__('error while formatting arguments for %s: %s') %
(self.fullname, err), type='autodoc')
except Exception:
logger.warning(__('error while formatting arguments for %s:') %
self.fullname, type='autodoc', exc_info=True)
args = None

retann = self.retann
Expand Down Expand Up @@ -428,8 +428,12 @@ def add_directive_header(self, sig: str) -> None:
# etc. don't support a prepended module name
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."""
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,
self.env.config.autodoc_inherit_docstrings,
self.parent, self.object_name)
Expand Down Expand Up @@ -741,8 +745,8 @@ def generate(self, more_content: Any = None, real_modname: str = None,
# parse right now, to get PycodeErrors on parsing (results will
# be cached anyway)
self.analyzer.find_attr_docs()
except PycodeError as err:
logger.debug('[autodoc] module analyzer failed: %s', err)
except PycodeError:
logger.debug('[autodoc] module analyzer failed:', exc_info=True)
# no source file -- e.g. for builtin and C modules
self.analyzer = None
# at least add the module.__file__ as a dependency
Expand Down Expand Up @@ -844,7 +848,7 @@ def add_directive_header(self, sig: str) -> None:
if self.options.deprecated:
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 (self.options.ignore_module_all or not
hasattr(self.object, '__all__')):
Expand Down Expand Up @@ -970,7 +974,7 @@ def _find_signature(self) -> Tuple[str, str]:
break
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)
if lines is not None:
return lines
Expand Down Expand Up @@ -1226,7 +1230,7 @@ def add_directive_header(self, sig: str) -> None:
self.add_line(' ' + _('Bases: %s') % ', '.join(bases),
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)
if lines is not None:
return lines
Expand Down Expand Up @@ -1719,8 +1723,12 @@ def import_object(self) -> Any:
self.env.note_reread()
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."""
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]
__slots__ = safe_getattr(self.parent, '__slots__', [])
if isinstance(__slots__, dict) and isinstance(__slots__.get(name), str):
Expand All @@ -1732,7 +1740,7 @@ def get_doc(self, ignore: int = 1) -> List[List[str]]:

def get_documenters(app: Sphinx) -> Dict[str, Type[Documenter]]:
"""Returns registered Documenter classes"""
warnings.warn("get_documenters() is deprecated.", RemovedInSphinx50Warning)
warnings.warn("get_documenters() is deprecated.", RemovedInSphinx50Warning, stacklevel=2)
return app.registry.documenters


Expand Down
6 changes: 4 additions & 2 deletions sphinx/ext/autodoc/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import warnings
from typing import Any, Callable, Dict, List, Mapping, NamedTuple, Tuple

from sphinx.pycode import ModuleAnalyzer
from sphinx.util import logging
from sphinx.util.inspect import isclass, isenumclass, safe_getattr

Expand Down Expand Up @@ -127,7 +128,7 @@ class Attribute(NamedTuple):


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."""
from sphinx.ext.autodoc import INSTANCEATTR

Expand All @@ -143,8 +144,9 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable,
members[name] = Attribute(name, True, value)

superclass = subject.__mro__[1]
for name, value in obj_dict.items():
for name in obj_dict:
if name not in superclass.__dict__:
value = safe_getattr(subject, name)
members[name] = Attribute(name, True, value)

# members in __slots__
Expand Down
8 changes: 4 additions & 4 deletions sphinx/ext/autosummary/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def __init__(self, app: Union[Builder, Sphinx], template_dir: str = None) -> Non
RemovedInSphinx50Warning, stacklevel=2)
if template_dir:
warnings.warn('template_dir argument for AutosummaryRenderer is deprecated.',
RemovedInSphinx50Warning)
RemovedInSphinx50Warning, stacklevel=2)

system_templates_path = [os.path.join(package_dir, 'ext', 'autosummary', 'templates')]
loader = SphinxTemplateLoader(app.srcdir, app.config.templates_path,
Expand Down Expand Up @@ -274,11 +274,11 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None,
overwrite: bool = True) -> None:
if builder:
warnings.warn('builder argument for generate_autosummary_docs() is deprecated.',
RemovedInSphinx50Warning)
RemovedInSphinx50Warning, stacklevel=2)

if template_dir:
warnings.warn('template_dir argument for generate_autosummary_docs() is deprecated.',
RemovedInSphinx50Warning)
RemovedInSphinx50Warning, stacklevel=2)

showed_sources = list(sorted(sources))
if len(showed_sources) > 20:
Expand Down Expand Up @@ -371,7 +371,7 @@ def find_autosummary_in_docstring(name: str, module: str = None, filename: str =
"""
if module:
warnings.warn('module argument for find_autosummary_in_docstring() is deprecated.',
RemovedInSphinx50Warning)
RemovedInSphinx50Warning, stacklevel=2)

try:
real_name, obj, parent, modname = import_by_name(name)
Expand Down
3 changes: 1 addition & 2 deletions sphinx/ext/napoleon/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,10 @@ def __unicode__(self):
**If False**::
.. attribute:: attr1
:type: int
Description of `attr1`
:type: int
napoleon_use_param : :obj:`bool` (Defaults to True)
True to use a ``:param:`` role for each function parameter. False to
use a single ``:parameters:`` role for all the parameters.
Expand Down
5 changes: 2 additions & 3 deletions sphinx/ext/napoleon/docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,13 +584,12 @@ def _parse_attributes_section(self, section: str) -> List[str]:
lines.append('.. attribute:: ' + _name)
if self._opt and 'noindex' in self._opt:
lines.append(' :noindex:')
if _type:
lines.extend(self._indent([':type: %s' % _type], 3))
lines.append('')

fields = self._format_field('', '', _desc)
lines.extend(self._indent(fields, 3))
if _type:
lines.append('')
lines.extend(self._indent([':type: %s' % _type], 3))
lines.append('')
if self._config.napoleon_use_ivar:
lines.append('')
Expand Down
2 changes: 1 addition & 1 deletion sphinx/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def set_application(self, app: "Sphinx") -> None:

@property
def app(self) -> "Sphinx":
warnings.warn('parser.app is deprecated.', RemovedInSphinx50Warning)
warnings.warn('parser.app is deprecated.', RemovedInSphinx50Warning, stacklevel=2)
return self._app


Expand Down
11 changes: 10 additions & 1 deletion sphinx/util/docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@

import re
import sys
import warnings
from typing import Dict, List

from docutils.parsers.rst.states import Body

from sphinx.deprecation import RemovedInSphinx50Warning


field_list_item_re = re.compile(Body.patterns['field_marker'])

Expand Down Expand Up @@ -42,7 +45,7 @@ def extract_metadata(s: str) -> Dict[str, str]:
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
indentation, where the indentation of a given number of lines (usually just
one) is ignored.
Expand All @@ -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
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()
# Find minimum indentation of any non-blank lines after ignored lines.
margin = sys.maxsize
Expand Down

0 comments on commit 7520396

Please sign in to comment.