diff --git a/CHANGES b/CHANGES index faabb32ad..8b52dd47c 100644 --- a/CHANGES +++ b/CHANGES @@ -145,10 +145,17 @@ Bugs fixed * #4924: html search: Upper characters problem in any other languages * #4932: apidoc: some subpackage is ignored if sibling subpackage contains a module starting with underscore -* #4938, #4939: i18n doesn't handle node.title correctly tat used for contents, - topic, admonition, table and section. +* #4863, #4938, #4939: i18n doesn't handle node.title correctly tat used for + contents, topic, admonition, table and section. * #4913: i18n: literal blocks in bullet list are not translated -* #4962: cpp domain: raises TypeError on duplicate declaration +* #4962: C++, raised TypeError on duplicate declaration. +* #4825: C++, properly parse expr roles and give better error messages when + (escaped) line breaks are present. +* C++, properly use ``desc_addname`` nodes for prefixes of names. +* #4915, #4916: links on search page are broken when using dirhtml builder +* #4969: autodoc: constructor method should not have return annotation +* latex: deeply nested enumerated list which is beginning with non-1 causes + LaTeX engine crashed Testing -------- diff --git a/sphinx/builders/epub3.py b/sphinx/builders/epub3.py index 5d3384b46..c1e6ab98a 100644 --- a/sphinx/builders/epub3.py +++ b/sphinx/builders/epub3.py @@ -190,7 +190,7 @@ class Epub3Builder(_epub_base.EpubBuilder): navstack[-1].children.append(navpoint) navstack.append(navpoint) else: - raise + raise RuntimeError('Should never reach here. It might be a bug.') return navstack[0].children diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py index 98eabb956..830f15f29 100644 --- a/sphinx/domains/cpp.py +++ b/sphinx/domains/cpp.py @@ -12,7 +12,7 @@ import re from copy import deepcopy -from docutils import nodes +from docutils import nodes, utils from docutils.parsers.rst import directives from six import iteritems, text_type @@ -1967,26 +1967,34 @@ class ASTNestedName(ASTBase): prefix = '' # type: unicode first = True names = self.names[:-1] if mode == 'lastIsName' else self.names + # If lastIsName, then wrap all of the prefix in a desc_addname, + # else append directly to signode. + # NOTE: Breathe relies on the prefix being in the desc_addname node, + # so it can remove it in inner declarations. + dest = signode + if mode == 'lastIsName': + dest = addnodes.desc_addname() for i in range(len(names)): name = names[i] template = self.templates[i] if not first: - signode += nodes.Text('::') + dest += nodes.Text('::') prefix += '::' if template: - signode += nodes.Text("template ") + dest += nodes.Text("template ") first = False if name != '': if (name.templateArgs and # type: ignore iTemplateParams < len(templateParams)): templateParamsPrefix += text_type(templateParams[iTemplateParams]) iTemplateParams += 1 - name.describe_signature(signode, 'markType', # type: ignore + name.describe_signature(dest, 'markType', # type: ignore env, templateParamsPrefix + prefix, symbol) prefix += text_type(name) if mode == 'lastIsName': if len(self.names) > 1: - signode += addnodes.desc_addname('::', '::') + dest += addnodes.desc_addname('::', '::') + signode += dest if self.templates[-1]: signode += nodes.Text("template ") self.names[-1].describe_signature(signode, mode, env, '', symbol) @@ -5961,7 +5969,7 @@ class CPPExprRole(object): class Warner(object): def warn(self, msg): inliner.reporter.warning(msg, line=lineno) - + text = utils.unescape(text).replace('\n', ' ') env = inliner.document.settings.env parser = DefinitionParser(text, Warner(), env.config) try: diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 1ebf6399b..353188aaf 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -1035,9 +1035,11 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ # typing) we try to use the constructor signature as function # signature without the first argument. try: - args = Signature(self.object.__new__, bound_method=True).format_args() + sig = Signature(self.object.__new__, bound_method=True, has_retval=False) + args = sig.format_args() except TypeError: - args = Signature(self.object.__init__, bound_method=True).format_args() + sig = Signature(self.object.__init__, bound_method=True, has_retval=False) + args = sig.format_args() # escape backslashes for reST args = args.replace('\\', '\\\\') @@ -1090,7 +1092,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: not(inspect.ismethod(initmeth) or inspect.isfunction(initmeth)): return None try: - return Signature(initmeth, bound_method=True).format_args() + return Signature(initmeth, bound_method=True, has_retval=False).format_args() except TypeError: # still not possible: happens e.g. for old-style classes # with __init__ in C diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html index a25a18b90..4795f7397 100644 --- a/sphinx/themes/basic/layout.html +++ b/sphinx/themes/basic/layout.html @@ -87,7 +87,7 @@ {%- endmacro %} {%- macro script() %} - + {%- for scriptfile in script_files %} {%- endfor %} diff --git a/sphinx/themes/basic/static/documentation_options.js_t b/sphinx/themes/basic/static/documentation_options.js_t index e76f55a4e..9da9801a1 100644 --- a/sphinx/themes/basic/static/documentation_options.js_t +++ b/sphinx/themes/basic/static/documentation_options.js_t @@ -1,5 +1,5 @@ var DOCUMENTATION_OPTIONS = { - URL_ROOT: '{{ url_root }}', + URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), VERSION: '{{ release|e }}', LANGUAGE: '{{ language }}', COLLAPSE_INDEX: false, diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 5dab5a710..7bda11503 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -309,8 +309,8 @@ class Signature(object): its return annotation. """ - def __init__(self, subject, bound_method=False): - # type: (Callable, bool) -> None + def __init__(self, subject, bound_method=False, has_retval=True): + # type: (Callable, bool, bool) -> None # check subject is not a built-in class (ex. int, str) if (isinstance(subject, type) and is_builtin_class_method(subject, "__new__") and @@ -318,6 +318,7 @@ class Signature(object): raise TypeError("can't compute signature for built-in type {}".format(subject)) self.subject = subject + self.has_retval = has_retval self.partialmethod_with_noargs = False if PY3: @@ -386,7 +387,10 @@ class Signature(object): def return_annotation(self): # type: () -> Any if PY3 and self.signature: - return self.signature.return_annotation + if self.has_retval: + return self.signature.return_annotation + else: + return inspect.Parameter.empty else: return None diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 6c4b66881..2c0cc0424 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -19,6 +19,7 @@ from collections import defaultdict from os import path from docutils import nodes, writers +from docutils.utils.roman import toRoman from docutils.writers.latex2e import Babel from six import itervalues, text_type @@ -1500,8 +1501,8 @@ class LaTeXTranslator(nodes.NodeVisitor): self.body.append('\\begin{enumerate}\n') if 'start' in node: - nested = get_nested_level(node) - self.body.append('\\setcounter{enum%s}{%d}\n' % ('i' * nested, node['start'] - 1)) + enum_depth = "enum%s" % toRoman(get_nested_level(node)).lower() + self.body.append('\\setcounter{%s}{%d}\n' % (enum_depth, node['start'] - 1)) if self.table: self.table.has_problematic = True diff --git a/tests/roots/test-nested-enumerated-list/index.rst b/tests/roots/test-nested-enumerated-list/index.rst index e1a9b5cbc..28ad72f9d 100644 --- a/tests/roots/test-nested-enumerated-list/index.rst +++ b/tests/roots/test-nested-enumerated-list/index.rst @@ -9,6 +9,12 @@ nested-enumerated-list 10) Pyramid 11) Nile River + (x) Atbara + (y) Blue Nile + (#) Sobat + (#) Semliki + (#) Kagera + 6. Markup iii. reStructuredText diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py index 459ac9f1d..bfdf06b2b 100644 --- a/tests/test_build_latex.py +++ b/tests/test_build_latex.py @@ -1231,6 +1231,7 @@ def test_latex_nested_enumerated_list(app, status, warning): assert r'\setcounter{enumi}{4}' in result assert r'\setcounter{enumii}{3}' in result assert r'\setcounter{enumiii}{9}' in result + assert r'\setcounter{enumiv}{23}' in result assert r'\setcounter{enumii}{2}' in result diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py index 0c7c7667d..09aff512f 100644 --- a/tests/test_util_inspect.py +++ b/tests/test_util_inspect.py @@ -280,6 +280,10 @@ def test_Signature_annotations(): sig = inspect.Signature(f11).format_args() assert sig == '(x: CustomAnnotation, y: 123) -> None' + # has_retval=False + sig = inspect.Signature(f11, has_retval=False).format_args() + assert sig == '(x: CustomAnnotation, y: 123)' + def test_safe_getattr_with_default(): class Foo(object):