From e98f39d21d788490aa5fa974a2e26c01fbb75785 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 23 Jul 2020 03:20:08 +0900 Subject: [PATCH] Fix #7993: texinfo: TypeError is raised for nested object descriptions The texinfo writer remembers the current desc node to render a desc_annotation node. This makes the mechanism robust to support nested object descriptions. --- CHANGES | 2 ++ doc/extdev/deprecated.rst | 5 +++++ sphinx/writers/texinfo.py | 26 ++++++++++++++++++-------- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/CHANGES b/CHANGES index bc932a7d4..4fbe7e8bd 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ Incompatible changes Deprecated ---------- +* ``sphinx.writers.texinfo.TexinfoWriter.desc`` * C, parsing of pre-v3 style type directives and roles, along with the options :confval:`c_allow_pre_v3` and :confval:`c_warn_on_allowed_pre_v3`. @@ -62,6 +63,7 @@ Bugs fixed * #7928: py domain: failed to resolve a type annotation for the attribute * #7968: i18n: The content of ``math`` directive is interpreted as reST on translation +* #7993: texinfo: TypeError is raised for nested object descriptions * #7869: :rst:role:`abbr` role without an explanation will show the explanation from the previous abbr role * C and C++, removed ``noindex`` directive option as it did diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index 7e59184ec..ceb88d45f 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -26,6 +26,11 @@ The following is a list of deprecated interfaces. - (will be) Removed - Alternatives + * - ``sphinx.writers.texinfo.TexinfoWriter.desc`` + - 3.2 + - 5.0 + - ``sphinx.writers.texinfo.TexinfoWriter.descs`` + * - The first argument for ``sphinx.ext.autosummary.generate.AutosummaryRenderer`` has been changed to Sphinx object diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index b77bf4352..8579e6654 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -10,14 +10,16 @@ import re import textwrap +import warnings from os import path -from typing import Any, Dict, Iterable, Iterator, List, Pattern, Set, Tuple, Union +from typing import Any, Dict, Iterable, Iterator, List, Optional, Pattern, Set, Tuple, Union from typing import cast from docutils import nodes, writers from docutils.nodes import Element, Node, Text from sphinx import addnodes, __display_version__ +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.domains import IndexEntry from sphinx.domains.index import IndexDomain from sphinx.errors import ExtensionError @@ -189,6 +191,7 @@ class TexinfoTranslator(SphinxTranslator): self.body = [] # type: List[str] self.context = [] # type: List[str] + self.descs = [] # type: List[addnodes.desc] self.previous_section = None # type: nodes.section self.section_level = 0 self.seen_title = False @@ -1365,12 +1368,12 @@ class TexinfoTranslator(SphinxTranslator): # -- Desc - def visit_desc(self, node: Element) -> None: - self.desc = node + def visit_desc(self, node: addnodes.desc) -> None: + self.descs.append(node) self.at_deffnx = '@deffn' - def depart_desc(self, node: Element) -> None: - self.desc = None + def depart_desc(self, node: addnodes.desc) -> None: + self.descs.pop() self.ensure_eol() self.body.append('@end deffn\n') @@ -1454,9 +1457,8 @@ class TexinfoTranslator(SphinxTranslator): # -- instead of -- # @deffn {Class} class Foo txt = node.astext().strip() - if txt == self.desc['desctype'] or \ - txt == self.desc['objtype'] or \ - txt in self.desc_type_name.split(): + if ((self.descs and txt == self.descs[-1]['objtype']) or + (self.desc_type_name and txt in self.desc_type_name.split())): raise nodes.SkipNode def depart_desc_annotation(self, node: Element) -> None: @@ -1526,3 +1528,11 @@ class TexinfoTranslator(SphinxTranslator): self.body.append('\n\n@example\n%s\n@end example\n\n' % self.escape_arg(node.astext())) raise nodes.SkipNode + + @property + def desc(self) -> Optional[addnodes.desc]: + warnings.warn('TexinfoWriter.desc is deprecated.', RemovedInSphinx50Warning) + if len(self.descs): + return self.descs[-1] + else: + return None