diff --git a/CHANGES b/CHANGES index a344a5752..57257bff2 100644 --- a/CHANGES +++ b/CHANGES @@ -171,6 +171,9 @@ Bugs fixed * #2665, #2607: Link names in C++ docfields, and make it possible for other domains. * #3542: C++, fix parsing error of non-type template argument with template. * #3065, #3520: python domain fails to recognize nested class +* #3575: Problems with pdflatex in a Turkish document built with sphinx has + reappeared (refs #2997, #2397) +* #3577: Fix intersphinx debug tool Testing -------- diff --git a/doc/conf.py b/doc/conf.py index 1a5be5736..d52b996dd 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -4,7 +4,7 @@ import re import sphinx - +language = 'ja' extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.todo', 'sphinx.ext.autosummary', 'sphinx.ext.extlinks', diff --git a/doc/domains.rst b/doc/domains.rst index 5236b3205..1b0dfac8c 100644 --- a/doc/domains.rst +++ b/doc/domains.rst @@ -76,9 +76,10 @@ directive name. .. rubric:: Default Domain -To avoid having to writing the domain name all the time when you e.g. only -describe Python objects, a default domain can be selected with either the config -value :confval:`primary_domain` or this directive: +For documentation describing objects from solely one domain, authors will not +have to state again its name at each directive, role, etc... after +having specified a default. This can be done either via the config +value :confval:`primary_domain` or via this directive: .. rst:directive:: .. default-domain:: name diff --git a/sphinx/config.py b/sphinx/config.py index 03d38fd77..0dbe8a58e 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -56,7 +56,7 @@ class ENUM(object): """represents the config value should be a one of candidates. Example: - app.add_config_value('latex_show_urls', 'no', ENUM('no', 'footnote', 'inline')) + app.add_config_value('latex_show_urls', 'no', None, ENUM('no', 'footnote', 'inline')) """ def __init__(self, *candidates): # type: (unicode) -> None diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index d952812bc..90cb94de6 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -26,6 +26,7 @@ from __future__ import print_function +import sys import time import functools import posixpath @@ -340,17 +341,27 @@ def setup(app): return {'version': sphinx.__display_version__, 'parallel_read_safe': True} -if __name__ == '__main__': - # debug functionality to print out an inventory - import sys +def debug(argv): + # type: (List[unicode]) -> None + """Debug functionality to print out an inventory""" + if len(argv) < 2: + print("Print out an inventory file.\n" + "Error: must specify local path or URL to an inventory file.", + file=sys.stderr) + sys.exit(1) + + class MockConfig(object): + intersphinx_timeout = None # type: int + tls_verify = False class MockApp(object): srcdir = '' + config = MockConfig() def warn(self, msg): print(msg, file=sys.stderr) - filename = sys.argv[1] + filename = argv[1] invdata = fetch_inventory(MockApp(), '', filename) # type: ignore for key in sorted(invdata or {}): print(key) @@ -358,3 +369,7 @@ if __name__ == '__main__': print('\t%-40s %s%s' % (entry, einfo[3] != '-' and '%-40s: ' % einfo[3] or '', einfo[2])) + + +if __name__ == '__main__': + debug(argv=sys.argv) # type: ignore diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 36f2062d4..ddc6e239c 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -185,9 +185,10 @@ class ExtBabel(Babel): if shortlang in ('de', 'ngerman', 'sl', 'slovene', 'pt', 'portuges', 'es', 'spanish', 'nl', 'dutch', 'pl', 'polish', 'it', 'italian'): - return '\\if\\catcode`\\"\\active\\shorthandoff{"}\\fi' + return '\\ifnum\\catcode`\\"=\\active\\shorthandoff{"}\\fi' elif shortlang in ('tr', 'turkish'): - return '\\if\\catcode`\\=\\active\\shorthandoff{=}\\fi' + # memo: if ever Sphinx starts supporting 'Latin', do as for Turkish + return '\\ifnum\\catcode`\\=\\string=\\active\\shorthandoff{=}\\fi' return '' def uses_cyrillic(self): diff --git a/tests/test_ext_intersphinx.py b/tests/test_ext_intersphinx.py index 6e722b90b..79e41bb13 100644 --- a/tests/test_ext_intersphinx.py +++ b/tests/test_ext_intersphinx.py @@ -13,12 +13,15 @@ import unittest from docutils import nodes import mock +import pytest +import requests +from io import BytesIO from sphinx import addnodes from sphinx.ext.intersphinx import setup as intersphinx_setup from sphinx.ext.intersphinx import ( load_mappings, missing_reference, _strip_basic_auth, - _get_safe_url, fetch_inventory, INVENTORY_FILENAME + _get_safe_url, fetch_inventory, INVENTORY_FILENAME, debug ) from test_util_inventory import inventory_v2 @@ -229,3 +232,53 @@ def test_getsafeurl_unauthed(): expected = 'https://domain.com/project/objects.inv' actual = _get_safe_url(url) assert expected == actual + + +def test_debug_noargs(capsys): + """debug interface, without arguments""" + with pytest.raises(SystemExit): + debug(['sphinx/ext/intersphinx.py']) + + expected = ( + "Print out an inventory file.\n" + "Error: must specify local path or URL to an inventory file." + ) + stdout, stderr = capsys.readouterr() + assert stdout == "" + assert stderr == expected + "\n" + + +def test_debug_file(capsys, tempdir): + """debug interface, with file argument""" + inv_file = tempdir / 'inventory' + inv_file.write_bytes(inventory_v2) + + debug(['sphinx/ext/intersphinx.py', str(inv_file)]) + + stdout, stderr = capsys.readouterr() + assert stdout.startswith("c:function\n") + assert stderr == "" + + +@mock.patch('requests.get') +def test_debug_url(fake_get, capsys): + """debug interface, with url argument""" + raw = BytesIO(inventory_v2) + real_read = raw.read + + def fake_read(*args, **kwargs): + return real_read() + + raw.read = fake_read + url = 'http://hostname/' + INVENTORY_FILENAME + resp = requests.Response() + resp.status_code = 200 + resp.url = url + resp.raw = raw + fake_get.return_value = resp + + debug(['sphinx/ext/intersphinx.py', url]) + + stdout, stderr = capsys.readouterr() + assert stdout.startswith("c:function\n") + assert stderr == ""