Merge branch '2.0' into refactor_autosummary3

This commit is contained in:
Takeshi KOMIYA
2019-06-22 01:34:47 +09:00
committed by GitHub
21 changed files with 74 additions and 47 deletions
+11 -1
View File
@@ -41,12 +41,13 @@ Bugs fixed
* #5502: linkcheck: Consider HTTP 503 response as not an error
* #6439: Make generated download links reproducible
* #6486: UnboundLocalError is raised if broken extension installed
* #6498: autosummary: crashed with wrong autosummary_generate setting
* #6507: autosummary: crashes without no autosummary_generate setting
Testing
--------
Release 2.1.2 (in development)
Release 2.1.3 (in development)
==============================
Dependencies
@@ -67,6 +68,15 @@ Bugs fixed
Testing
--------
Release 2.1.2 (released Jun 19, 2019)
=====================================
Bugs fixed
----------
* #6497: custom lexers fails highlighting when syntax error
* #6478, #6488: info field lists are incorrectly recognized
Release 2.1.1 (released Jun 10, 2019)
=====================================
+1 -1
View File
@@ -47,7 +47,7 @@ extras_require = {
'html5lib',
'flake8>=3.5.0',
'flake8-import-order',
'mypy>=0.590',
'mypy>=0.710',
'docutils-stubs',
],
}
+1
View File
@@ -73,6 +73,7 @@ class ObjectDescription(SphinxDirective):
def get_field_type_map(self) -> Dict[str, Tuple[Field, bool]]:
if self._doc_field_type_map == {}:
self._doc_field_type_map = {}
for field in self.doc_field_types:
for name in field.names:
self._doc_field_type_map[name] = (field, False)
+5 -4
View File
@@ -910,12 +910,13 @@ class StandardDomain(Domain):
# type: (nodes.Node) -> str
"""Get the title of enumerable nodes to refer them using its title"""
if self.is_enumerable_node(node):
_, title_getter = self.enumerable_nodes.get(node.__class__, (None, None))
elem = cast(nodes.Element, node)
_, title_getter = self.enumerable_nodes.get(elem.__class__, (None, None))
if title_getter:
return title_getter(node)
return title_getter(elem)
else:
for subnode in node:
if subnode.tagname in ('caption', 'title'):
for subnode in elem:
if isinstance(subnode, (nodes.caption, nodes.title)):
return clean_astext(subnode)
return None
+13 -7
View File
@@ -58,6 +58,7 @@ import posixpath
import re
import sys
import warnings
from os import path
from types import ModuleType
from typing import List, cast
@@ -738,26 +739,31 @@ def process_generate_options(app):
# type: (Sphinx) -> None
genfiles = app.config.autosummary_generate
if genfiles and not hasattr(genfiles, '__len__'):
if genfiles is True:
env = app.builder.env
genfiles = [env.doc2path(x, base=None) for x in env.found_docs
if os.path.isfile(env.doc2path(x))]
else:
ext = list(app.config.source_suffix)
genfiles = [genfile + (not genfile.endswith(tuple(ext)) and ext[0] or '')
for genfile in genfiles]
for entry in genfiles[:]:
if not path.isfile(path.join(app.srcdir, entry)):
logger.warning(__('autosummary_generate: file not found: %s'), entry)
genfiles.remove(entry)
if not genfiles:
return
from sphinx.ext.autosummary.generate import generate_autosummary_docs
ext = list(app.config.source_suffix)
genfiles = [genfile + (not genfile.endswith(tuple(ext)) and ext[0] or '')
for genfile in genfiles]
suffix = get_rst_suffix(app)
if suffix is None:
logger.warning(__('autosummary generats .rst files internally. '
'But your source_suffix does not contain .rst. Skipped.'))
return
from sphinx.ext.autosummary.generate import generate_autosummary_docs
imported_members = app.config.autosummary_imported_members
with mock(app.config.autosummary_mock_imports):
generate_autosummary_docs(genfiles, builder=app.builder,
+8 -6
View File
@@ -208,23 +208,25 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
if info:
warnings.warn('info argument for generate_autosummary_docs() is deprecated.',
RemovedInSphinx40Warning)
_info = info
else:
info = logger.info
_info = logger.info
if warn:
warnings.warn('warn argument for generate_autosummary_docs() is deprecated.',
RemovedInSphinx40Warning)
_warn = warn
else:
warn = logger.warning
_warn = logger.warning
showed_sources = list(sorted(sources))
if len(showed_sources) > 20:
showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:]
info(__('[autosummary] generating autosummary for: %s') %
', '.join(showed_sources))
_info(__('[autosummary] generating autosummary for: %s') %
', '.join(showed_sources))
if output_dir:
info(__('[autosummary] writing to %s') % output_dir)
_info(__('[autosummary] writing to %s') % output_dir)
if base_path is not None:
sources = [os.path.join(base_path, filename) for filename in sources]
@@ -250,7 +252,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
try:
name, obj, parent, mod_name = import_by_name(name)
except ImportError as e:
warn('[autosummary] failed to import %r: %s' % (name, e))
_warn('[autosummary] failed to import %r: %s' % (name, e))
continue
fn = os.path.join(path, name + suffix)
+2 -1
View File
@@ -139,7 +139,8 @@ class PygmentsBridge:
lexer = lexers['none']
if lang in lexers:
lexer = lexers[lang]
# just return custom lexers here (without installing raiseonerror filter)
return lexers[lang]
elif lang in lexer_classes:
lexer = lexer_classes[lang](**opts)
else:
+1 -1
View File
@@ -123,7 +123,7 @@ def isenumattribute(x: Any) -> bool:
def ispartial(obj: Any) -> bool:
"""Check if the object is partial."""
return isinstance(obj, (partial, partialmethod))
return isinstance(obj, (partial, partialmethod)) # type: ignore
def isclassmethod(obj: Any) -> bool:
+1 -1
View File
@@ -30,7 +30,7 @@ class PyStemmer(BaseStemmer):
return self.stemmer.stemWord(word)
class StandardStemmer(PorterStemmer, BaseStemmer): # type: ignore
class StandardStemmer(PorterStemmer, BaseStemmer):
"""All those porter stemmer implementations look hideous;
make at least the stem method nicer.
"""
+1 -1
View File
@@ -2598,7 +2598,7 @@ class LaTeXTranslator(SphinxTranslator):
RemovedInSphinx30Warning)
def visit_admonition(self, node):
# type: (nodes.Element) -> None
# type: (LaTeXTranslator, nodes.Element) -> None
self.body.append('\n\\begin{sphinxadmonition}{%s}{%s:}' %
(name, admonitionlabels[name]))
return visit_admonition
+1 -1
View File
@@ -1752,6 +1752,6 @@ class TexinfoTranslator(SphinxTranslator):
RemovedInSphinx30Warning)
def visit(self, node):
# type: (nodes.Element) -> None
# type: (TexinfoTranslator, nodes.Element) -> None
self.visit_admonition(node, admonitionlabels[name])
return visit
+1 -1
View File
@@ -1375,6 +1375,6 @@ class TextTranslator(SphinxTranslator):
RemovedInSphinx30Warning)
def depart_admonition(self, node):
# type: (nodes.Element) -> None
# type: (TextTranslator, nodes.Element) -> None
self.end_state(first=admonitionlabels[name] + ': ')
return depart_admonition
+1 -1
View File
@@ -26,4 +26,4 @@ test-image
.. image:: https://www.python.org/static/img/python-logo.png
.. non-exist remote image
.. image:: http://example.com/NOT_EXIST.PNG
.. image:: https://www.google.com/NOT_EXIST.PNG
+2 -2
View File
@@ -23,8 +23,8 @@ link to external1_ and external2_.
link to `Sphinx Site <http://sphinx-doc.org>`_ and `Python Site <http://python.org>`_.
.. _external1: http://example.com/external1
.. _external2: http://example.com/external2
.. _external1: https://www.google.com/external1
.. _external2: https://www.google.com/external2
Multiple references in the same line
+5 -5
View File
@@ -6,11 +6,11 @@ This is from CPython documentation.
Some additional anchors to exercise ignore code
* `Example Bar invalid <http://example.com/#!bar>`_
* `Example Bar invalid <http://example.com#!bar>`_ tests that default ignore anchor of #! does not need to be prefixed with /
* `Example Bar invalid <http://example.com/#top>`_
* `Example Bar invalid <https://www.google.com/#!bar>`_
* `Example Bar invalid <https://www.google.com#!bar>`_ tests that default ignore anchor of #! does not need to be prefixed with /
* `Example Bar invalid <https://www.google.com/#top>`_
* `Example anchor invalid <http://www.sphinx-doc.org/en/1.7/intro.html#does-not-exist>`_
* `Complete nonsense <https://localhost:7777/doesnotexist>`_
.. image:: http://example.com/image.png
.. figure:: http://example.com/image2.png
.. image:: https://www.google.com/image.png
.. figure:: https://www.google.com/image2.png
+5 -5
View File
@@ -1240,25 +1240,25 @@ def test_html_entity(app):
def test_html_inventory(app):
app.builder.build_all()
with open(app.outdir / 'objects.inv', 'rb') as f:
invdata = InventoryFile.load(f, 'http://example.com', os.path.join)
invdata = InventoryFile.load(f, 'https://www.google.com', os.path.join)
assert set(invdata.keys()) == {'std:label', 'std:doc'}
assert set(invdata['std:label'].keys()) == {'modindex', 'genindex', 'search'}
assert invdata['std:label']['modindex'] == ('Python',
'',
'http://example.com/py-modindex.html',
'https://www.google.com/py-modindex.html',
'Module Index')
assert invdata['std:label']['genindex'] == ('Python',
'',
'http://example.com/genindex.html',
'https://www.google.com/genindex.html',
'Index')
assert invdata['std:label']['search'] == ('Python',
'',
'http://example.com/search.html',
'https://www.google.com/search.html',
'Search Page')
assert set(invdata['std:doc'].keys()) == {'index'}
assert invdata['std:doc']['index'] == ('Python',
'',
'http://example.com/index.html',
'https://www.google.com/index.html',
'The basic Sphinx documentation for testing')
+1 -1
View File
@@ -1242,7 +1242,7 @@ def test_latex_images(app, status, warning):
# not found images
assert '\\sphinxincludegraphics{{NOT_EXIST}.PNG}' not in result
assert ('WARNING: Could not fetch remote image: '
'http://example.com/NOT_EXIST.PNG [404]' in warning.getvalue())
'https://www.google.com/NOT_EXIST.PNG [404]' in warning.getvalue())
# an image having target
assert ('\\sphinxhref{https://www.sphinx-doc.org/}'
+4 -4
View File
@@ -25,8 +25,8 @@ def test_defaults(app, status, warning):
# looking for non-existent URL should fail
assert " Max retries exceeded with url: /doesnotexist" in content
# images should fail
assert "Not Found for url: http://example.com/image.png" in content
assert "Not Found for url: http://example.com/image2.png" in content
assert "Not Found for url: https://www.google.com/image.png" in content
assert "Not Found for url: https://www.google.com/image2.png" in content
assert len(content.splitlines()) == 5
@@ -36,8 +36,8 @@ def test_defaults(app, status, warning):
'linkcheck_ignore': [
'https://localhost:7777/doesnotexist',
'http://www.sphinx-doc.org/en/1.7/intro.html#',
'http://example.com/image.png',
'http://example.com/image2.png']
'https://www.google.com/image.png',
'https://www.google.com/image2.png']
})
def test_anchors_ignored(app, status, warning):
app.builder.build_all()
+6
View File
@@ -310,3 +310,9 @@ def test_empty_autosummary_generate(app, status, warning):
app.build()
assert ("WARNING: autosummary: stub file not found 'autosummary_importfail'"
in warning.getvalue())
@pytest.mark.sphinx('dummy', testroot='ext-autosummary',
confoverrides={'autosummary_generate': ['unknown']})
def test_invalid_autosummary_generate(app, status, warning):
assert 'WARNING: autosummary_generate: file not found: unknown.rst' in warning.getvalue()
+2 -2
View File
@@ -885,8 +885,8 @@ def test_xml_keep_external_links(app):
assert_elem(
para1[0],
['LINK TO', 'external2', 'AND', 'external1', '.'],
['http://example.com/external2',
'http://example.com/external1'])
['https://www.google.com/external2',
'https://www.google.com/external1'])
assert_elem(
para1[1],
['LINK TO', 'THE PYTHON SITE', 'AND', 'THE SPHINX SITE', '.'],
+2 -2
View File
@@ -279,9 +279,9 @@ def get_verifier(verify, verify_re):
(
# in URIs
'verify_re',
'`test <http://example.com/~me/>`_',
'`test <https://www.google.com/~me/>`_',
None,
r'\\sphinxhref{http://example.com/~me/}{test}.*',
r'\\sphinxhref{https://www.google.com/~me/}{test}.*',
),
(
# description list: simple