diff --git a/CHANGES b/CHANGES index 1358cfc98f..c709b014ea 100644 --- a/CHANGES +++ b/CHANGES @@ -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) ===================================== diff --git a/setup.py b/setup.py index 91b3e12cc6..2b6e257130 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ extras_require = { 'html5lib', 'flake8>=3.5.0', 'flake8-import-order', - 'mypy>=0.590', + 'mypy>=0.710', 'docutils-stubs', ], } diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index 13f48e8275..393df0ca9f 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -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) diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 01cc797c3a..45516ebd9f 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -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 diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index eab7b22fb9..de9d6dcd35 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -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, diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index b6ced22565..5419e41dfb 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -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) diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py index 2d825e9f1d..b4e63209fa 100644 --- a/sphinx/highlighting.py +++ b/sphinx/highlighting.py @@ -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: diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index c1fc0e9607..1d0dfa6250 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -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: diff --git a/sphinx/util/stemmer/__init__.py b/sphinx/util/stemmer/__init__.py index bda5d2bc2f..8d8d36c680 100644 --- a/sphinx/util/stemmer/__init__.py +++ b/sphinx/util/stemmer/__init__.py @@ -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. """ diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 5c7f525074..24ec059e54 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -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 diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index 4262ccd666..b952812f0a 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -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 diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index 1447510c32..dc8a7963ae 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -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 diff --git a/tests/roots/test-images/index.rst b/tests/roots/test-images/index.rst index 67b742b278..14a2987a0d 100644 --- a/tests/roots/test-images/index.rst +++ b/tests/roots/test-images/index.rst @@ -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 diff --git a/tests/roots/test-intl/external_links.txt b/tests/roots/test-intl/external_links.txt index 96e3973de7..1cecbeeb80 100644 --- a/tests/roots/test-intl/external_links.txt +++ b/tests/roots/test-intl/external_links.txt @@ -23,8 +23,8 @@ link to external1_ and external2_. link to `Sphinx Site `_ and `Python Site `_. -.. _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 diff --git a/tests/roots/test-linkcheck/links.txt b/tests/roots/test-linkcheck/links.txt index ac5ed32465..fa8f11e4cf 100644 --- a/tests/roots/test-linkcheck/links.txt +++ b/tests/roots/test-linkcheck/links.txt @@ -6,11 +6,11 @@ This is from CPython documentation. Some additional anchors to exercise ignore code -* `Example Bar invalid `_ -* `Example Bar invalid `_ tests that default ignore anchor of #! does not need to be prefixed with / -* `Example Bar invalid `_ +* `Example Bar invalid `_ +* `Example Bar invalid `_ tests that default ignore anchor of #! does not need to be prefixed with / +* `Example Bar invalid `_ * `Example anchor invalid `_ * `Complete nonsense `_ -.. 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 diff --git a/tests/test_build_html.py b/tests/test_build_html.py index 352166d945..3255bb71e4 100644 --- a/tests/test_build_html.py +++ b/tests/test_build_html.py @@ -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') diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 13bb22e96e..56dfa7ca47 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -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/}' diff --git a/tests/test_build_linkcheck.py b/tests/test_build_linkcheck.py index 6d25058eb8..4bf47a9626 100644 --- a/tests/test_build_linkcheck.py +++ b/tests/test_build_linkcheck.py @@ -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() diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index 351789a487..1e50ac0ac3 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -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() \ No newline at end of file diff --git a/tests/test_intl.py b/tests/test_intl.py index a052266b8a..9790f50a35 100644 --- a/tests/test_intl.py +++ b/tests/test_intl.py @@ -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', '.'], diff --git a/tests/test_markup.py b/tests/test_markup.py index 006d19caa7..b8c9b66d9a 100644 --- a/tests/test_markup.py +++ b/tests/test_markup.py @@ -279,9 +279,9 @@ def get_verifier(verify, verify_re): ( # in URIs 'verify_re', - '`test `_', + '`test `_', None, - r'\\sphinxhref{http://example.com/~me/}{test}.*', + r'\\sphinxhref{https://www.google.com/~me/}{test}.*', ), ( # description list: simple