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.
This commit is contained in:
Takeshi KOMIYA 2020-07-23 03:20:08 +09:00
parent f30284ef92
commit e98f39d21d
3 changed files with 25 additions and 8 deletions

View File

@ -10,6 +10,7 @@ Incompatible changes
Deprecated Deprecated
---------- ----------
* ``sphinx.writers.texinfo.TexinfoWriter.desc``
* C, parsing of pre-v3 style type directives and roles, along with the options * 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`. :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 * #7928: py domain: failed to resolve a type annotation for the attribute
* #7968: i18n: The content of ``math`` directive is interpreted as reST on * #7968: i18n: The content of ``math`` directive is interpreted as reST on
translation translation
* #7993: texinfo: TypeError is raised for nested object descriptions
* #7869: :rst:role:`abbr` role without an explanation will show the explanation * #7869: :rst:role:`abbr` role without an explanation will show the explanation
from the previous abbr role from the previous abbr role
* C and C++, removed ``noindex`` directive option as it did * C and C++, removed ``noindex`` directive option as it did

View File

@ -26,6 +26,11 @@ The following is a list of deprecated interfaces.
- (will be) Removed - (will be) Removed
- Alternatives - Alternatives
* - ``sphinx.writers.texinfo.TexinfoWriter.desc``
- 3.2
- 5.0
- ``sphinx.writers.texinfo.TexinfoWriter.descs``
* - The first argument for * - The first argument for
``sphinx.ext.autosummary.generate.AutosummaryRenderer`` has been changed ``sphinx.ext.autosummary.generate.AutosummaryRenderer`` has been changed
to Sphinx object to Sphinx object

View File

@ -10,14 +10,16 @@
import re import re
import textwrap import textwrap
import warnings
from os import path 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 typing import cast
from docutils import nodes, writers from docutils import nodes, writers
from docutils.nodes import Element, Node, Text from docutils.nodes import Element, Node, Text
from sphinx import addnodes, __display_version__ from sphinx import addnodes, __display_version__
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.domains import IndexEntry from sphinx.domains import IndexEntry
from sphinx.domains.index import IndexDomain from sphinx.domains.index import IndexDomain
from sphinx.errors import ExtensionError from sphinx.errors import ExtensionError
@ -189,6 +191,7 @@ class TexinfoTranslator(SphinxTranslator):
self.body = [] # type: List[str] self.body = [] # type: List[str]
self.context = [] # type: List[str] self.context = [] # type: List[str]
self.descs = [] # type: List[addnodes.desc]
self.previous_section = None # type: nodes.section self.previous_section = None # type: nodes.section
self.section_level = 0 self.section_level = 0
self.seen_title = False self.seen_title = False
@ -1365,12 +1368,12 @@ class TexinfoTranslator(SphinxTranslator):
# -- Desc # -- Desc
def visit_desc(self, node: Element) -> None: def visit_desc(self, node: addnodes.desc) -> None:
self.desc = node self.descs.append(node)
self.at_deffnx = '@deffn' self.at_deffnx = '@deffn'
def depart_desc(self, node: Element) -> None: def depart_desc(self, node: addnodes.desc) -> None:
self.desc = None self.descs.pop()
self.ensure_eol() self.ensure_eol()
self.body.append('@end deffn\n') self.body.append('@end deffn\n')
@ -1454,9 +1457,8 @@ class TexinfoTranslator(SphinxTranslator):
# -- instead of -- # -- instead of --
# @deffn {Class} class Foo # @deffn {Class} class Foo
txt = node.astext().strip() txt = node.astext().strip()
if txt == self.desc['desctype'] or \ if ((self.descs and txt == self.descs[-1]['objtype']) or
txt == self.desc['objtype'] or \ (self.desc_type_name and txt in self.desc_type_name.split())):
txt in self.desc_type_name.split():
raise nodes.SkipNode raise nodes.SkipNode
def depart_desc_annotation(self, node: Element) -> None: 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.body.append('\n\n@example\n%s\n@end example\n\n' %
self.escape_arg(node.astext())) self.escape_arg(node.astext()))
raise nodes.SkipNode 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