From faebc58074ba2fe253fa50145f4f1ebd3d4b4f65 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 18 Feb 2018 17:54:26 +0900 Subject: [PATCH 01/17] Show opt:scheme attribute only for EPUB3.1 (refs: #4622) --- sphinx/builders/epub3.py | 2 ++ sphinx/templates/epub3/content.opf_t | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sphinx/builders/epub3.py b/sphinx/builders/epub3.py index da252b359..4f50e6505 100644 --- a/sphinx/builders/epub3.py +++ b/sphinx/builders/epub3.py @@ -133,6 +133,7 @@ class Epub3Builder(_epub_base.EpubBuilder): metadata['ibook_scroll_axis'] = IBOOK_SCROLL_AXIS.get(writing_mode) metadata['date'] = self.esc(format_date("%Y-%m-%dT%H:%M:%SZ")) metadata['version'] = self.esc(self.config.version) + metadata['epub_version'] = self.config.epub_version return metadata def prepare_writing(self, docnames): @@ -229,6 +230,7 @@ def setup(app): # config values app.add_config_value('epub_basename', lambda self: make_filename(self.project), None) + app.add_config_value('epub_version', 3.0, 'epub') # experimental app.add_config_value('epub_theme', 'epub', 'epub') app.add_config_value('epub_theme_options', {}, 'epub') app.add_config_value('epub_title', lambda self: self.html_title, 'epub') diff --git a/sphinx/templates/epub3/content.opf_t b/sphinx/templates/epub3/content.opf_t index c201e49d6..417888c7e 100644 --- a/sphinx/templates/epub3/content.opf_t +++ b/sphinx/templates/epub3/content.opf_t @@ -1,5 +1,5 @@ - {{ contributor }} {{ publisher }} {{ copyright }} + {%- if epub_version == 3.1 %} {{ id }} + {%- else %} + {{ id }} + {%- endif %} {{ date }} {{ date }} {{ version }} From 07de0ed10b4a24f6850702bf075d3cdbb5cf83d3 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Sun, 18 Feb 2018 22:55:58 +0900 Subject: [PATCH 02/17] Fix #4641: A external link in TOC cannot contain "?" with ``:glob:`` option --- CHANGES | 1 + sphinx/directives/other.py | 12 ++++++------ tests/roots/test-toctree-glob/index.rst | 1 + tests/test_environment_toctree.py | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 7f841a5d0..fcbd409f5 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ Bugs fixed * #4630: Have order on msgids in sphinx.pot deterministic * #4563: autosummary: Incorrect end of line punctuation detection * #4577: Enumerated sublists with explicit start with wrong number +* #4641: A external link in TOC cannot contain "?" with ``:glob:`` option Testing -------- diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 6c1a4cd86..f04e429c2 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -73,7 +73,9 @@ class TocTree(Directive): for entry in self.content: if not entry: continue - if glob and ('*' in entry or '?' in entry or '[' in entry): + # look for explicit titles ("Some Title ") + explicit = explicit_title_re.match(entry) + if glob and ('*' in entry or '?' in entry or '[' in entry) and not explicit: patname = docname_join(env.docname, entry) docnames = sorted(patfilter(all_docnames, patname)) for docname in docnames: @@ -85,11 +87,9 @@ class TocTree(Directive): 'toctree glob pattern %r didn\'t match any documents' % entry, line=self.lineno)) else: - # look for explicit titles ("Some Title ") - m = explicit_title_re.match(entry) - if m: - ref = m.group(2) - title = m.group(1) + if explicit: + ref = explicit.group(2) + title = explicit.group(1) docname = ref else: ref = docname = entry diff --git a/tests/roots/test-toctree-glob/index.rst b/tests/roots/test-toctree-glob/index.rst index a3c198ce3..3fda0618b 100644 --- a/tests/roots/test-toctree-glob/index.rst +++ b/tests/roots/test-toctree-glob/index.rst @@ -12,6 +12,7 @@ normal order bar/* baz qux/index + hyperref reversed order ------------- diff --git a/tests/test_environment_toctree.py b/tests/test_environment_toctree.py index 26334858b..ad97b94fb 100644 --- a/tests/test_environment_toctree.py +++ b/tests/test_environment_toctree.py @@ -113,7 +113,7 @@ def test_glob(app): maxdepth=-1, numbered=0, includefiles=includefiles, entries=[(None, 'foo'), (None, 'bar/index'), (None, 'bar/bar_1'), (None, 'bar/bar_2'), (None, 'bar/bar_3'), (None, 'baz'), - (None, 'qux/index')]) + (None, 'qux/index'), ('hyperref', 'https://sphinx-doc.org/?q=sphinx')]) assert_node(toctree[0][1][1], [list_item, ([compact_paragraph, reference, "reversed order"], [bullet_list, addnodes.toctree])]) # [0][1][1][1][0] From 7d49a5311ff9267940e9accd69a3f2fe5b955248 Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Wed, 17 Jan 2018 12:35:33 +0100 Subject: [PATCH 03/17] C++, parse explicit casts and typeid in expression --- CHANGES | 1 + sphinx/domains/cpp.py | 163 ++++++++++++++++++++++++++++++++------- tests/test_domain_cpp.py | 7 +- 3 files changed, 144 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index fcbd409f5..1d57236df 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,7 @@ Bugs fixed * #4563: autosummary: Incorrect end of line punctuation detection * #4577: Enumerated sublists with explicit start with wrong number * #4641: A external link in TOC cannot contain "?" with ``:glob:`` option +* C++, add missing parsing of explicit casts and typeid in expression parsing. Testing -------- diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index c7bb82203..e71343b6a 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -530,6 +530,12 @@ _expression_bin_ops = [ _expression_unary_ops = ["++", "--", "*", "&", "+", "-", "!", "~"] _expression_assignment_ops = ["=", "*=", "/=", "%=", "+=", "-=", ">>=", "<<=", "&=", "^=", "|="] +_id_explicit_cast = { + 'dynamic_cast': 'dc', + 'static_cast': 'sc', + 'const_cast': 'cc', + 'reinterpret_cast': 'rc' +} class NoOldIdError(UnicodeMixin, Exception): @@ -1027,6 +1033,56 @@ class ASTNoexceptExpr(ASTBase): signode.append(nodes.Text(')')) +class ASTExplicitCast(ASTBase): + def __init__(self, cast, typ, expr): + assert cast in _id_explicit_cast + self.cast = cast + self.typ = typ + self.expr = expr + + def __unicode__(self): + res = [self.cast] + res.append('<') + res.append(text_type(self.typ)) + res.append('>(') + res.append(text_type(self.expr)) + res.append(')') + return u''.join(res) + + def get_id(self, version): + return (_id_explicit_cast[self.cast] + + self.typ.get_id(version) + + self.expr.get_id(version)) + + def describe_signature(self, signode, mode, env, symbol): + signode.append(nodes.Text(self.cast)) + signode.append(nodes.Text('<')) + self.typ.describe_signature(signode, mode, env, symbol) + signode.append(nodes.Text('>')) + signode.append(nodes.Text('(')) + self.expr.describe_signature(signode, mode, env, symbol) + signode.append(nodes.Text(')')) + + +class ASTTypeId(ASTBase): + def __init__(self, typeOrExpr, isType): + self.typeOrExpr = typeOrExpr + self.isType = isType + + def __unicode__(self): + return 'typeid(' + text_type(self.typeOrExpr) + ')' + + def get_id(self, version): + prefix = 'ti' if self.isType else 'te' + return prefix + self.typeOrExpr.get_id(version) + + def describe_signature(self, signode, mode, env, symbol): + signode.append(nodes.Text('typeid')) + signode.append(nodes.Text('(')) + self.typeOrExpr.describe_signature(signode, mode, env, symbol) + signode.append(nodes.Text(')')) + + class ASTPostfixCallExpr(ASTBase): def __init__(self, exprs): self.exprs = exprs @@ -4096,39 +4152,94 @@ class DefinitionParser(object): # | "typeid" "(" expression ")" # | "typeid" "(" type-id ")" - # TODO: try the productions with prefixes: - # dynamic_cast, static_cast, reinterpret_cast, const_cast, typeid prefixType = None - pos = self.pos - try: - prefix = self._parse_primary_expression() - prefixType = 'expr' - except DefinitionError as eOuter: - self.pos = pos + prefix = None # type: Any + self.skip_ws() + + cast = None + for c in _id_explicit_cast: + if self.skip_word_and_ws(c): + cast = c + break + if cast is not None: + prefixType = "cast" + if not self.skip_string("<"): + self.fail("Expected '<' afer '%s'." % cast) + typ = self._parse_type(False) + self.skip_ws() + if not self.skip_string_and_ws(">"): + self.fail("Expected '>' after type in '%s'." % cast) + if not self.skip_string("("): + self.fail("Expected '(' in '%s'." % cast) + + def parser(): + return self._parse_expression(inTemplate=False) + expr = self._parse_expression_fallback([')'], parser) + self.skip_ws() + if not self.skip_string(")"): + self.fail("Expected ')' to end '%s'." % cast) + prefix = ASTExplicitCast(cast, typ, expr) + elif self.skip_word_and_ws("typeid"): + prefixType = "typeid" + if not self.skip_string_and_ws('('): + self.fail("Expected '(' after 'typeid'.") + pos = self.pos try: - # we are potentially casting, so save parens for us - # TODO: hmm, would we need to try both with operatorCast and with None? - prefix = self._parse_type(False, 'operatorCast') - prefixType = 'typeOperatorCast' - # | simple-type-specifier "(" expression-list [opt] ")" - # | simple-type-specifier braced-init-list - # | typename-specifier "(" expression-list [opt] ")" - # | typename-specifier braced-init-list - self.skip_ws() - if self.current_char != '(' and self.current_char != '{': - self.fail("Expecting '(' or '{' after type in cast expression.") - except DefinitionError as eInner: + typ = self._parse_type(False) + prefix = ASTTypeId(typ, isType=True) + if not self.skip_string(')'): + self.fail("Expected ')' to end 'typeid' of type.") + except DefinitionError as eType: self.pos = pos - header = "Error in postfix expression, expected primary expression or type." - errors = [] - errors.append((eOuter, "If primary expression")) - errors.append((eInner, "If type")) - raise self._make_multi_error(errors, header) + try: + + def parser(): + return self._parse_expression(inTemplate=False) + expr = self._parse_expression_fallback([')'], parser) + prefix = ASTTypeId(expr, isType=False) + if not self.skip_string(')'): + self.fail("Expected ')' to end 'typeid' of expression.") + except DefinitionError as eExpr: + self.pos = pos + header = "Error in 'typeid(...)'." + header += " Expected type or expression." + errors = [] + errors.append((eType, "If type")) + errors.append((eExpr, "If expression")) + raise self._make_multi_error(errors, header) + else: # a primary expression or a type + pos = self.pos + try: + prefix = self._parse_primary_expression() + prefixType = 'expr' + except DefinitionError as eOuter: + self.pos = pos + try: + # we are potentially casting, so save parens for us + # TODO: hmm, would we need to try both with operatorCast and with None? + prefix = self._parse_type(False, 'operatorCast') + prefixType = 'typeOperatorCast' + # | simple-type-specifier "(" expression-list [opt] ")" + # | simple-type-specifier braced-init-list + # | typename-specifier "(" expression-list [opt] ")" + # | typename-specifier braced-init-list + self.skip_ws() + if self.current_char != '(' and self.current_char != '{': + self.fail("Expecting '(' or '{' after type in cast expression.") + except DefinitionError as eInner: + self.pos = pos + header = "Error in postfix expression," + header += " expected primary expression or type." + errors = [] + errors.append((eOuter, "If primary expression")) + errors.append((eInner, "If type")) + raise self._make_multi_error(errors, header) + # and now parse postfixes postFixes = [] while True: self.skip_ws() - if prefixType == 'expr': + if prefixType in ['expr', 'cast', 'typeid']: if self.skip_string_and_ws('['): expr = self._parse_expression(inTemplate=False) self.skip_ws() diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index b6de66989..6f6932626 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -137,7 +137,12 @@ def test_expressions(): exprCheck('a->b->c', 'ptpt1a1b1c') exprCheck('i++', 'pp1i') exprCheck('i--', 'mm1i') - # TODO, those with prefixes + exprCheck('dynamic_cast(i)++', 'ppdcR1T1i') + exprCheck('static_cast(i)++', 'ppscR1T1i') + exprCheck('reinterpret_cast(i)++', 'pprcR1T1i') + exprCheck('const_cast(i)++', 'ppccR1T1i') + exprCheck('typeid(T).name', 'dtti1T4name') + exprCheck('typeid(a + b).name', 'dttepl1a1b4name') # unary exprCheck('++5', 'pp_L5E') exprCheck('--5', 'mm_L5E') From bde93246c6d129831c13fc7f7ff2f1f960eb42dd Mon Sep 17 00:00:00 2001 From: Jakob Lykke Andersen Date: Wed, 17 Jan 2018 16:12:30 +0100 Subject: [PATCH 04/17] C++, parse 'this' in expressions. --- CHANGES | 1 + sphinx/domains/cpp.py | 16 +++++++++++++++- tests/test_domain_cpp.py | 1 + 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 1d57236df..5ecfbab6d 100644 --- a/CHANGES +++ b/CHANGES @@ -36,6 +36,7 @@ Bugs fixed * #4577: Enumerated sublists with explicit start with wrong number * #4641: A external link in TOC cannot contain "?" with ``:glob:`` option * C++, add missing parsing of explicit casts and typeid in expression parsing. +* C++, add missing parsing of ``this`` in expression parsing. Testing -------- diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index e71343b6a..1d52962e9 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -784,6 +784,17 @@ class ASTStringLiteral(ASTBase): signode.append(nodes.Text(txt, txt)) +class ASTThisLiteral(ASTBase): + def __unicode__(self): + return "this" + + def get_id(self, version): + return "fpT" + + def describe_signature(self, signode, mode, env, symbol): + signode.append(nodes.Text("this")) + + class ASTParenExpr(ASTBase): def __init__(self, expr): self.expr = expr @@ -4124,7 +4135,10 @@ class DefinitionParser(object): res = self._parse_literal() if res is not None: return res - # TODO: try 'this' and lambda expression + self.skip_ws() + if self.skip_word("this"): + return ASTThisLiteral() + # TODO: try lambda expression res = self._parse_fold_or_paren_expression() if res is not None: return res diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py index 6f6932626..de72148a5 100644 --- a/tests/test_domain_cpp.py +++ b/tests/test_domain_cpp.py @@ -126,6 +126,7 @@ def test_expressions(): expr = '5.0' + suffix exprCheck(expr, 'L' + expr + 'E') exprCheck('"abc\\"cba"', 'LA8_KcE') # string + exprCheck('this', 'fpT') # TODO: test the rest exprCheck('(... + Ns)', '(... + Ns)') exprCheck('(5)', 'L5E') From 93d117076917d5a93354b587387dc5a1df7c5839 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 20 Feb 2018 20:51:53 +0900 Subject: [PATCH 05/17] Adjust .codecov.yml (again) --- .codecov.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.codecov.yml b/.codecov.yml index 0e6fdf0c3..2ce4fda70 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -4,3 +4,7 @@ coverage: default: # allowed to drop X% and still result in a "success" commit status threshold: 0.05 + patch: + default: + # allowed to drop X% and still result in a "success" commit status + threshold: 0.05 From b45c47757d6cb9ea616992b74bcb114244087600 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Tue, 20 Feb 2018 22:50:14 +0900 Subject: [PATCH 06/17] Fix incomplete localization strings in Polish (refs: #4655) --- sphinx/locale/pl/LC_MESSAGES/sphinx.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/locale/pl/LC_MESSAGES/sphinx.po b/sphinx/locale/pl/LC_MESSAGES/sphinx.po index 2c8d7960e..6bbb2e543 100644 --- a/sphinx/locale/pl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pl/LC_MESSAGES/sphinx.po @@ -1298,12 +1298,12 @@ msgstr "znaleziono więcej niż jeden cel dla cross-referencji „any”: może #: sphinx/transforms/post_transforms/__init__.py:169 #, python-format msgid "%s:%s reference target not found: %%(target)s" -msgstr "nie znaleziono celu referencji %s:%s: %%(cel)e" +msgstr "nie znaleziono celu referencji %s:%s: %%(target)s" #: sphinx/transforms/post_transforms/__init__.py:172 #, python-format msgid "%r reference target not found: %%(target)s" -msgstr "nie znaleziono celu referencji %r: %%(cel)e" +msgstr "nie znaleziono celu referencji %r: %%(target)s" #: sphinx/util/docutils.py:202 msgid "when adding directive classes, no additional arguments may be given" From 6a2ec96c9721bd873ba93cb8c714f61a3e98012f Mon Sep 17 00:00:00 2001 From: adam-azarchs <22033990+adam-azarchs@users.noreply.github.com> Date: Mon, 19 Feb 2018 12:50:28 -0800 Subject: [PATCH 07/17] Fix error reporting for parameterless ImportErrors In some cases, a module may raise an ImportError without any arguments, e.g. if not_allowed(): raise ImportError In this case, the exception has no args. This is bad practice, but it happens. Currently, autodoc will crash with IndexError: tuple index out of range --- sphinx/ext/autodoc/importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index db33b4215..857b6a91e 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -179,7 +179,7 @@ def import_object(modname, objpath, objtype='', attrgetter=safe_getattr, warning if isinstance(real_exc, SystemExit): errmsg += ('; the module executes module level statement ' 'and it might call sys.exit().') - elif isinstance(real_exc, ImportError): + elif isinstance(real_exc, ImportError) and real_exc.args: errmsg += '; the following exception was raised:\n%s' % real_exc.args[0] else: errmsg += '; the following exception was raised:\n%s' % traceback_msg From a34d39dd274180b907b21e76020aba6aff9632c4 Mon Sep 17 00:00:00 2001 From: Takeshi Suzuki Date: Thu, 22 Feb 2018 14:35:53 +0900 Subject: [PATCH 08/17] Fix incomplete localization strings in Polish (refs: #4655) Reflects the changes suggested in the comment below https://github.com/sphinx-doc/sphinx/issues/4655#issuecomment-367310280 --- sphinx/locale/pl/LC_MESSAGES/sphinx.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinx/locale/pl/LC_MESSAGES/sphinx.po b/sphinx/locale/pl/LC_MESSAGES/sphinx.po index 6bbb2e543..6d0d655fb 100644 --- a/sphinx/locale/pl/LC_MESSAGES/sphinx.po +++ b/sphinx/locale/pl/LC_MESSAGES/sphinx.po @@ -1293,7 +1293,7 @@ msgstr "Treść" #: sphinx/transforms/post_transforms/__init__.py:139 #, python-format msgid "more than one target found for 'any' cross-reference %r: could be %s" -msgstr "znaleziono więcej niż jeden cel dla cross-referencji „any”: może być %s" +msgstr "znaleziono więcej niż jeden cel dla cross-referencji „any” %r: może być %s" #: sphinx/transforms/post_transforms/__init__.py:169 #, python-format From 16a7539007a24829f78fdf545890ee9d719c8f18 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 22 Feb 2018 21:09:21 +0900 Subject: [PATCH 09/17] Update CHANGES --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 5ecfbab6d..1882e0f92 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,7 @@ Bugs fixed * #4641: A external link in TOC cannot contain "?" with ``:glob:`` option * C++, add missing parsing of explicit casts and typeid in expression parsing. * C++, add missing parsing of ``this`` in expression parsing. +* #4655: Fix incomplete localization strings in Polish Testing -------- From 6f05c96027e1a63939d448f4031974018937c483 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 00:13:17 +0900 Subject: [PATCH 10/17] Update CHANGES for PR #4653 --- CHANGES | 1 + sphinx/ext/intersphinx.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 1882e0f92..689a235b6 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,7 @@ Bugs fixed * C++, add missing parsing of explicit casts and typeid in expression parsing. * C++, add missing parsing of ``this`` in expression parsing. * #4655: Fix incomplete localization strings in Polish +* #4653: Fix error reporting for parameterless ImportErrors Testing -------- diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 8d84af7d7..e9de4e4c7 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -375,7 +375,7 @@ def setup(app): def debug(argv): # type: (List[unicode]) -> None """Debug functionality to print out an inventory""" - if len(argv) < 2: + if len(argv) < 1: print("Print out an inventory file.\n" "Error: must specify local path or URL to an inventory file.", file=sys.stderr) @@ -392,7 +392,7 @@ def debug(argv): def warn(self, msg): print(msg, file=sys.stderr) - filename = argv[1] + filename = argv[0] invdata = fetch_inventory(MockApp(), '', filename) # type: ignore for key in sorted(invdata or {}): print(key) From 7999aca6068957f915640d0f91e2d4ba09419b8a Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 00:44:25 +0900 Subject: [PATCH 11/17] Revert "Update CHANGES for PR #4653" This reverts commit 6f05c96027e1a63939d448f4031974018937c483. --- CHANGES | 1 - sphinx/ext/intersphinx.py | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 689a235b6..1882e0f92 100644 --- a/CHANGES +++ b/CHANGES @@ -38,7 +38,6 @@ Bugs fixed * C++, add missing parsing of explicit casts and typeid in expression parsing. * C++, add missing parsing of ``this`` in expression parsing. * #4655: Fix incomplete localization strings in Polish -* #4653: Fix error reporting for parameterless ImportErrors Testing -------- diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index e9de4e4c7..8d84af7d7 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -375,7 +375,7 @@ def setup(app): def debug(argv): # type: (List[unicode]) -> None """Debug functionality to print out an inventory""" - if len(argv) < 1: + 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) @@ -392,7 +392,7 @@ def debug(argv): def warn(self, msg): print(msg, file=sys.stderr) - filename = argv[0] + filename = argv[1] invdata = fetch_inventory(MockApp(), '', filename) # type: ignore for key in sorted(invdata or {}): print(key) From f4a527d8a605535b53a45a42bf44323b58471f82 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 00:44:39 +0900 Subject: [PATCH 12/17] Update CHANGES for PR #4653 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 1882e0f92..689a235b6 100644 --- a/CHANGES +++ b/CHANGES @@ -38,6 +38,7 @@ Bugs fixed * C++, add missing parsing of explicit casts and typeid in expression parsing. * C++, add missing parsing of ``this`` in expression parsing. * #4655: Fix incomplete localization strings in Polish +* #4653: Fix error reporting for parameterless ImportErrors Testing -------- From 4b0ff9a0d3048c7170c572d2e5055c65d42bc2d4 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 00:13:17 +0900 Subject: [PATCH 13/17] Update CHANGES for PR #4653 --- sphinx/ext/intersphinx.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index 8d84af7d7..e9de4e4c7 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -375,7 +375,7 @@ def setup(app): def debug(argv): # type: (List[unicode]) -> None """Debug functionality to print out an inventory""" - if len(argv) < 2: + if len(argv) < 1: print("Print out an inventory file.\n" "Error: must specify local path or URL to an inventory file.", file=sys.stderr) @@ -392,7 +392,7 @@ def debug(argv): def warn(self, msg): print(msg, file=sys.stderr) - filename = argv[1] + filename = argv[0] invdata = fetch_inventory(MockApp(), '', filename) # type: ignore for key in sorted(invdata or {}): print(key) From cd08a6503c781124241c4a8a949a01971ba43cf8 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 00:49:08 +0900 Subject: [PATCH 14/17] Fix #4664: Reading objects.inv fails again --- CHANGES | 3 +++ sphinx/ext/intersphinx.py | 13 ++++++++++++- tests/test_ext_intersphinx.py | 20 ++++++++++---------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 689a235b6..565235519 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,8 @@ Deprecated ``sphinx.cmd.build.build_main()`` instead. * autosummary: The interface of ``sphinx.ext.autosummary.get_documenter()`` has been changed (Since 1.7.0) +* #4664: ``sphinx.ext.intersphinx.debug()`` is deprecated. Use + ``sphinx.ext.intersphinx.inspect_main()`` instead. Features added -------------- @@ -39,6 +41,7 @@ Bugs fixed * C++, add missing parsing of ``this`` in expression parsing. * #4655: Fix incomplete localization strings in Polish * #4653: Fix error reporting for parameterless ImportErrors +* #4664: Reading objects.inv fails again Testing -------- diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py index e9de4e4c7..77962c095 100644 --- a/sphinx/ext/intersphinx.py +++ b/sphinx/ext/intersphinx.py @@ -30,6 +30,7 @@ import functools import posixpath import sys import time +import warnings from os import path from typing import TYPE_CHECKING @@ -40,6 +41,7 @@ from six.moves.urllib.parse import urlsplit, urlunsplit import sphinx from sphinx.builders.html import INVENTORY_FILENAME +from sphinx.deprecation import RemovedInSphinx20Warning from sphinx.locale import _ from sphinx.util import requests, logging from sphinx.util.inventory import InventoryFile @@ -373,6 +375,15 @@ def setup(app): def debug(argv): + # type: (List[unicode]) -> None + """Debug functionality to print out an inventory""" + warnings.warn('sphinx.ext.intersphinx.debug() is deprecated. ' + 'Please use inspect_main() instead', + RemovedInSphinx20Warning) + inspect_main(argv[1:]) + + +def inspect_main(argv): # type: (List[unicode]) -> None """Debug functionality to print out an inventory""" if len(argv) < 1: @@ -406,4 +417,4 @@ if __name__ == '__main__': import logging # type: ignore logging.basicConfig() - debug(argv=sys.argv[1:]) # type: ignore + inspect_main(argv=sys.argv[1:]) # type: ignore diff --git a/tests/test_ext_intersphinx.py b/tests/test_ext_intersphinx.py index ff08ded1c..b9bb8421b 100644 --- a/tests/test_ext_intersphinx.py +++ b/tests/test_ext_intersphinx.py @@ -22,7 +22,7 @@ from test_util_inventory import inventory_v2, inventory_v2_not_having_version from sphinx import addnodes from sphinx.ext.intersphinx import ( load_mappings, missing_reference, _strip_basic_auth, - _get_safe_url, fetch_inventory, INVENTORY_FILENAME, debug + _get_safe_url, fetch_inventory, INVENTORY_FILENAME, inspect_main ) from sphinx.ext.intersphinx import setup as intersphinx_setup @@ -393,10 +393,10 @@ def test_getsafeurl_unauthed(): assert expected == actual -def test_debug_noargs(capsys): - """debug interface, without arguments""" +def test_inspect_main_noargs(capsys): + """inspect_main interface, without arguments""" with pytest.raises(SystemExit): - debug(['sphinx/ext/intersphinx.py']) + inspect_main([]) expected = ( "Print out an inventory file.\n" @@ -407,12 +407,12 @@ def test_debug_noargs(capsys): assert stderr == expected + "\n" -def test_debug_file(capsys, tempdir): - """debug interface, with file argument""" +def test_inspect_main_file(capsys, tempdir): + """inspect_main interface, with file argument""" inv_file = tempdir / 'inventory' inv_file.write_bytes(inventory_v2) - debug(['sphinx/ext/intersphinx.py', str(inv_file)]) + inspect_main([str(inv_file)]) stdout, stderr = capsys.readouterr() assert stdout.startswith("c:function\n") @@ -420,8 +420,8 @@ def test_debug_file(capsys, tempdir): @mock.patch('requests.get') -def test_debug_url(fake_get, capsys): - """debug interface, with url argument""" +def test_inspect_main_url(fake_get, capsys): + """inspect_main interface, with url argument""" raw = BytesIO(inventory_v2) real_read = raw.read @@ -436,7 +436,7 @@ def test_debug_url(fake_get, capsys): resp.raw = raw fake_get.return_value = resp - debug(['sphinx/ext/intersphinx.py', url]) + inspect_main([url]) stdout, stderr = capsys.readouterr() assert stdout.startswith("c:function\n") From c41e746b7a9640e7fbc6d5bc86d40484996434cc Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 23:05:48 +0900 Subject: [PATCH 15/17] Fix #4662: any refs with term targets crash when an ambiguity is encountered --- CHANGES | 2 ++ sphinx/transforms/post_transforms/__init__.py | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 565235519..84428ab7d 100644 --- a/CHANGES +++ b/CHANGES @@ -42,6 +42,8 @@ Bugs fixed * #4655: Fix incomplete localization strings in Polish * #4653: Fix error reporting for parameterless ImportErrors * #4664: Reading objects.inv fails again +* #4662: ``any`` refs with ``term`` targets crash when an ambiguity is + encountered Testing -------- diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py index e1f8260a3..952b972f7 100644 --- a/sphinx/transforms/post_transforms/__init__.py +++ b/sphinx/transforms/post_transforms/__init__.py @@ -135,10 +135,12 @@ class ReferencesResolver(SphinxTransform): if not results: return None if len(results) > 1: - nice_results = ' or '.join(':%s:`%s`' % (name, role["reftitle"]) - for name, role in results) + def stringify(name, node): + reftitle = node.get('reftitle', node.astext()) + return ':%s:`%s`' % (name, reftitle) + candidates = ' or '.join(stringify(name, role) for name, role in results) logger.warning(__('more than one target found for \'any\' cross-' - 'reference %r: could be %s'), target, nice_results, + 'reference %r: could be %s'), target, candidates, location=node) res_role, newnode = results[0] # Override "any" class with the actual role type to get the styling From d4b6839295a9c45ec6d3622ddc6e6ede5c906fe6 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 23:39:34 +0900 Subject: [PATCH 16/17] Bump to 1.7.1 final --- CHANGES | 16 ++-------------- sphinx/__init__.py | 4 ++-- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/CHANGES b/CHANGES index 84428ab7d..4d06de4f7 100644 --- a/CHANGES +++ b/CHANGES @@ -1,11 +1,5 @@ -Release 1.7.1 (in development) -============================== - -Dependencies ------------- - -Incompatible changes --------------------- +Release 1.7.1 (released Feb 23, 2018) +===================================== Deprecated ---------- @@ -17,9 +11,6 @@ Deprecated * #4664: ``sphinx.ext.intersphinx.debug()`` is deprecated. Use ``sphinx.ext.intersphinx.inspect_main()`` instead. -Features added --------------- - Bugs fixed ---------- @@ -45,9 +36,6 @@ Bugs fixed * #4662: ``any`` refs with ``term`` targets crash when an ambiguity is encountered -Testing --------- - Release 1.7.0 (released Feb 12, 2018) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 5acaaa2ca..fcc17430d 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -31,13 +31,13 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.7.1+' +__version__ = '1.7.1' __released__ = '1.7.1' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' # 'final' has 0 as the last element -version_info = (1, 7, 1, 'beta', 0) +version_info = (1, 7, 1, 'final', 0) package_dir = path.abspath(path.dirname(__file__)) From a37f253a6bff2a25e997abdcb360cce2912da965 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Fri, 23 Feb 2018 23:42:01 +0900 Subject: [PATCH 17/17] Bump version --- CHANGES | 21 +++++++++++++++++++++ sphinx/__init__.py | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 4d06de4f7..d907eddb6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Release 1.7.2 (in development) +============================== + +Dependencies +------------ + +Incompatible changes +-------------------- + +Deprecated +---------- + +Features added +-------------- + +Bugs fixed +---------- + +Testing +-------- + Release 1.7.1 (released Feb 23, 2018) ===================================== diff --git a/sphinx/__init__.py b/sphinx/__init__.py index fcc17430d..4234f49cb 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -31,13 +31,13 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '1.7.1' -__released__ = '1.7.1' # used when Sphinx builds its own docs +__version__ = '1.7.2+' +__released__ = '1.7.2' # used when Sphinx builds its own docs # version info for better programmatic use # possible values for 3rd element: 'alpha', 'beta', 'rc', 'final' # 'final' has 0 as the last element -version_info = (1, 7, 1, 'final', 0) +version_info = (1, 7, 2, 'beta', 0) package_dir = path.abspath(path.dirname(__file__))