Merge pull request #5704 from tk0miya/fix_typehints_nits

Fix annotations (minor fixes)
This commit is contained in:
Takeshi KOMIYA 2018-12-03 01:46:33 +09:00 committed by GitHub
commit 21b689aae2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 88 additions and 76 deletions

View File

@ -107,6 +107,7 @@ class desc_signature_line(nodes.Part, nodes.Inline, nodes.FixedTextElement):
It should only be used in a ``desc_signature`` with ``is_multiline`` set. It should only be used in a ``desc_signature`` with ``is_multiline`` set.
Set ``add_permalink = True`` for the line that should get the permalink. Set ``add_permalink = True`` for the line that should get the permalink.
""" """
sphinx_cpp_tagname = ''
# nodes to use within a desc_signature or desc_signature_line # nodes to use within a desc_signature or desc_signature_line

View File

@ -317,7 +317,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
return footnote return footnote
def footnote_spot(tree): def footnote_spot(tree):
# type: (nodes.document) -> Tuple[nodes.document, int] # type: (nodes.document) -> Tuple[nodes.Element, int]
"""Find or create a spot to place footnotes. """Find or create a spot to place footnotes.
The function returns the tuple (parent, index).""" The function returns the tuple (parent, index)."""

View File

@ -144,9 +144,8 @@ class I18nBuilder(Builder):
return return
def write_doc(self, docname, doctree): def write_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None # type: (unicode, nodes.document) -> None
catalog = self.catalogs[find_catalog(docname, catalog = self.catalogs[find_catalog(docname, self.config.gettext_compact)]
self.config.gettext_compact)]
for node, msg in extract_messages(doctree): for node, msg in extract_messages(doctree):
catalog.add(msg, node) catalog.add(msg, node)

View File

@ -84,6 +84,11 @@ class ManualPageBuilder(Builder):
else: else:
authors = [] authors = []
docsettings.title = name
docsettings.subtitle = description
docsettings.authors = authors
docsettings.section = section
targetname = '%s.%s' % (name, section) targetname = '%s.%s' % (name, section)
logger.info(darkgreen(targetname) + ' { ', nonl=True) logger.info(darkgreen(targetname) + ' { ', nonl=True)
destination = FileOutput( destination = FileOutput(
@ -94,18 +99,13 @@ class ManualPageBuilder(Builder):
docnames = set() # type: Set[unicode] docnames = set() # type: Set[unicode]
largetree = inline_all_toctrees(self, docnames, docname, tree, largetree = inline_all_toctrees(self, docnames, docname, tree,
darkgreen, [docname]) darkgreen, [docname])
largetree.settings = docsettings
logger.info('} ', nonl=True) logger.info('} ', nonl=True)
self.env.resolve_references(largetree, docname, self) self.env.resolve_references(largetree, docname, self)
# remove pending_xref nodes # remove pending_xref nodes
for pendingnode in largetree.traverse(addnodes.pending_xref): for pendingnode in largetree.traverse(addnodes.pending_xref):
pendingnode.replace_self(pendingnode.children) pendingnode.replace_self(pendingnode.children)
largetree.settings = docsettings
largetree.settings.title = name
largetree.settings.subtitle = description
largetree.settings.authors = authors
largetree.settings.section = section
docwriter.write(largetree, destination) docwriter.write(largetree, destination)
logger.info('') logger.info('')

View File

@ -129,7 +129,7 @@ class MathDirective(SphinxDirective):
if self.arguments and self.arguments[0]: if self.arguments and self.arguments[0]:
latex = self.arguments[0] + '\n\n' + latex latex = self.arguments[0] + '\n\n' + latex
node = nodes.math_block(latex, latex, node = nodes.math_block(latex, latex,
docname=self.state.document.settings.env.docname, docname=self.env.docname,
number=self.options.get('name'), number=self.options.get('name'),
label=self.options.get('label'), label=self.options.get('label'),
nowrap='nowrap' in self.options) nowrap='nowrap' in self.options)

View File

@ -2145,7 +2145,7 @@ class ASTNestedName(ASTBase):
# else append directly to signode. # else append directly to signode.
# NOTE: Breathe relies on the prefix being in the desc_addname node, # NOTE: Breathe relies on the prefix being in the desc_addname node,
# so it can remove it in inner declarations. # so it can remove it in inner declarations.
dest = signode dest = signode # type: nodes.Element
if mode == 'lastIsName': if mode == 'lastIsName':
dest = addnodes.desc_addname() dest = addnodes.desc_addname()
for i in range(len(names)): for i in range(len(names)):

View File

@ -129,7 +129,7 @@ class Target(SphinxDirective):
targetname = '%s-%s' % (self.name, fullname) targetname = '%s-%s' % (self.name, fullname)
node = nodes.target('', '', ids=[targetname]) node = nodes.target('', '', ids=[targetname])
self.state.document.note_explicit_target(node) self.state.document.note_explicit_target(node)
ret = [node] ret = [node] # type: List[nodes.Node]
if self.indextemplate: if self.indextemplate:
indexentry = self.indextemplate % (fullname,) indexentry = self.indextemplate % (fullname,)
indextype = 'single' indextype = 'single'
@ -303,7 +303,7 @@ class Glossary(SphinxDirective):
entries = [] # type: List[Tuple[List[Tuple[unicode, unicode, int]], StringList]] entries = [] # type: List[Tuple[List[Tuple[unicode, unicode, int]], StringList]]
in_definition = True in_definition = True
was_empty = True was_empty = True
messages = [] messages = [] # type: List[nodes.Node]
for line, (source, lineno) in zip(self.content, self.content.items): for line, (source, lineno) in zip(self.content, self.content.items):
# empty line -> add to last definition # empty line -> add to last definition
if not line: if not line:

View File

@ -555,7 +555,7 @@ class BuildEnvironment:
def get_and_resolve_doctree(self, docname, builder, doctree=None, def get_and_resolve_doctree(self, docname, builder, doctree=None,
prune_toctrees=True, includehidden=False): prune_toctrees=True, includehidden=False):
# type: (unicode, Builder, nodes.Node, bool, bool) -> nodes.document # type: (unicode, Builder, nodes.document, bool, bool) -> nodes.document
"""Read the doctree from the pickle, resolve cross-references and """Read the doctree from the pickle, resolve cross-references and
toctrees and return it. toctrees and return it.
""" """
@ -600,7 +600,7 @@ class BuildEnvironment:
self.apply_post_transforms(doctree, fromdocname) self.apply_post_transforms(doctree, fromdocname)
def apply_post_transforms(self, doctree, docname): def apply_post_transforms(self, doctree, docname):
# type: (nodes.Node, unicode) -> None # type: (nodes.document, unicode) -> None
"""Apply all post-transforms.""" """Apply all post-transforms."""
try: try:
# set env.docname during applying post-transforms # set env.docname during applying post-transforms
@ -700,7 +700,7 @@ class BuildEnvironment:
self.app.builder.read_doc(docname) self.app.builder.read_doc(docname)
def write_doctree(self, docname, doctree): def write_doctree(self, docname, doctree):
# type: (unicode, nodes.Node) -> None # type: (unicode, nodes.document) -> None
warnings.warn('env.write_doctree() is deprecated. ' warnings.warn('env.write_doctree() is deprecated. '
'Please use builder.write_doctree() instead.', 'Please use builder.write_doctree() instead.',
RemovedInSphinx30Warning, stacklevel=2) RemovedInSphinx30Warning, stacklevel=2)
@ -759,7 +759,7 @@ class BuildEnvironment:
@classmethod @classmethod
def dumps(cls, env): def dumps(cls, env):
# type: (BuildEnvironment) -> unicode # type: (BuildEnvironment) -> bytes
warnings.warn('BuildEnvironment.dumps() is deprecated. ' warnings.warn('BuildEnvironment.dumps() is deprecated. '
'Please use pickle.dumps() instead.', 'Please use pickle.dumps() instead.',
RemovedInSphinx30Warning, stacklevel=2) RemovedInSphinx30Warning, stacklevel=2)
@ -784,7 +784,7 @@ class BuildEnvironment:
return self.domaindata['changeset']['changes'] return self.domaindata['changeset']['changes']
def note_versionchange(self, type, version, node, lineno): def note_versionchange(self, type, version, node, lineno):
# type: (unicode, unicode, nodes.Node, int) -> None # type: (unicode, unicode, addnodes.versionmodified, int) -> None
warnings.warn('env.note_versionchange() is deprecated. ' warnings.warn('env.note_versionchange() is deprecated. '
'Please use ChangeSetDomain.note_changeset() instead.', 'Please use ChangeSetDomain.note_changeset() instead.',
RemovedInSphinx30Warning, stacklevel=2) RemovedInSphinx30Warning, stacklevel=2)

View File

@ -40,12 +40,12 @@ def register_sections_as_label(app, document):
labelid = node['ids'][0] labelid = node['ids'][0]
docname = app.env.docname docname = app.env.docname
title = cast(nodes.title, node[0]) title = cast(nodes.title, node[0])
ref_name = getattr(node[0], 'rawsource', title.astext()) ref_name = getattr(title, 'rawsource', title.astext())
if app.config.autosectionlabel_prefix_document: if app.config.autosectionlabel_prefix_document:
name = nodes.fully_normalize_name(docname + ':' + ref_name) name = nodes.fully_normalize_name(docname + ':' + ref_name)
else: else:
name = nodes.fully_normalize_name(ref_name) name = nodes.fully_normalize_name(ref_name)
sectname = clean_astext(node[0]) sectname = clean_astext(title)
if name in labels: if name in labels:
logger.warning(__('duplicate label %s, other instance in %s'), logger.warning(__('duplicate label %s, other instance in %s'),

View File

@ -83,7 +83,7 @@ from sphinx.util.matching import Matcher
if False: if False:
# For type annotation # For type annotation
from typing import Any, Dict, Tuple, Type, Union # NOQA from typing import Any, Dict, Tuple, Type # NOQA
from docutils.parsers.rst.states import Inliner # NOQA from docutils.parsers.rst.states import Inliner # NOQA
from sphinx.application import Sphinx # NOQA from sphinx.application import Sphinx # NOQA
from sphinx.environment import BuildEnvironment # NOQA from sphinx.environment import BuildEnvironment # NOQA
@ -274,8 +274,7 @@ class Autosummary(SphinxDirective):
tocnode['maxdepth'] = -1 tocnode['maxdepth'] = -1
tocnode['glob'] = None tocnode['glob'] = None
tocnode = autosummary_toc('', '', tocnode) nodes.append(autosummary_toc('', '', tocnode))
nodes.append(tocnode)
return self.warnings + nodes return self.warnings + nodes
@ -354,7 +353,7 @@ class Autosummary(SphinxDirective):
return items return items
def get_table(self, items): def get_table(self, items):
# type: (List[Tuple[unicode, unicode, unicode, unicode]]) -> List[Union[addnodes.tabular_col_spec, autosummary_table]] # NOQA # type: (List[Tuple[unicode, unicode, unicode, unicode]]) -> List[nodes.Node]
"""Generate a proper list of table nodes for autosummary:: directive. """Generate a proper list of table nodes for autosummary:: directive.
*items* is a list produced by :meth:`get_items`. *items* is a list produced by :meth:`get_items`.

View File

@ -46,7 +46,7 @@ class MathExtError(SphinxError):
category = 'Math extension error' category = 'Math extension error'
def __init__(self, msg, stderr=None, stdout=None): def __init__(self, msg, stderr=None, stdout=None):
# type: (unicode, unicode, unicode) -> None # type: (unicode, bytes, bytes) -> None
if stderr: if stderr:
msg += '\n[stderr]\n' + stderr.decode(sys_encoding, 'replace') msg += '\n[stderr]\n' + stderr.decode(sys_encoding, 'replace')
if stdout: if stdout:

View File

@ -71,10 +71,9 @@ def doctree_read(app, doctree):
continue continue
uris.add(uri) uris.add(uri)
inline = nodes.inline('', _('[source]'), classes=['viewcode-link'])
onlynode = addnodes.only(expr='html') onlynode = addnodes.only(expr='html')
onlynode += nodes.reference('', '', internal=False, refuri=uri) onlynode += nodes.reference('', '', inline, internal=False, refuri=uri)
onlynode[0] += nodes.inline('', _('[source]'),
classes=['viewcode-link'])
signode += onlynode signode += onlynode

View File

@ -63,7 +63,7 @@ def wrap_displaymath(text, label, numbering):
def is_in_section_title(node): def is_in_section_title(node):
# type: (nodes.Node) -> bool # type: (nodes.Element) -> bool
"""Determine whether the node is in a section title""" """Determine whether the node is in a section title"""
from sphinx.util.nodes import traverse_parent from sphinx.util.nodes import traverse_parent

View File

@ -126,7 +126,7 @@ class TodoList(SphinxDirective):
option_spec = {} # type: Dict option_spec = {} # type: Dict
def run(self): def run(self):
# type: () -> List[todolist] # type: () -> List[nodes.Node]
# Simply insert an empty todolist node which will be replaced later # Simply insert an empty todolist node which will be replaced later
# when process_todo_nodes is called # when process_todo_nodes is called
return [todolist('')] return [todolist('')]

View File

@ -121,13 +121,11 @@ def doctree_read(app, doctree):
continue continue
names.add(fullname) names.add(fullname)
pagename = '_modules/' + modname.replace('.', '/') pagename = '_modules/' + modname.replace('.', '/')
inline = nodes.inline('', _('[source]'), classes=['viewcode-link'])
onlynode = addnodes.only(expr='html') onlynode = addnodes.only(expr='html')
onlynode += addnodes.pending_xref( onlynode += addnodes.pending_xref('', inline, reftype='viewcode', refdomain='std',
'', reftype='viewcode', refdomain='std', refexplicit=False, refexplicit=False, reftarget=pagename,
reftarget=pagename, refid=fullname, refid=fullname, refdoc=env.docname)
refdoc=env.docname)
onlynode[0] += nodes.inline('', _('[source]'),
classes=['viewcode-link'])
signode += onlynode signode += onlynode

View File

@ -14,6 +14,7 @@ from six import text_type
if False: if False:
# For type annotation # For type annotation
import builtins # NOQA
from typing import Any, Callable, IO, List # NOQA from typing import Any, Callable, IO, List # NOQA
from sphinx.util.typing import unicode # NOQA from sphinx.util.typing import unicode # NOQA
@ -166,7 +167,7 @@ class path(text_type):
return f.read() return f.read()
def bytes(self): def bytes(self):
# type: () -> str # type: () -> builtins.bytes
""" """
Returns the bytes in the file. Returns the bytes in the file.
""" """

View File

@ -56,7 +56,7 @@ class SphinxTransform(Transform):
def app(self): def app(self):
# type: () -> Sphinx # type: () -> Sphinx
"""Reference to the :class:`.Sphinx` object.""" """Reference to the :class:`.Sphinx` object."""
return self.document.settings.env.app return self.env.app
@property @property
def env(self): def env(self):
@ -68,7 +68,7 @@ class SphinxTransform(Transform):
def config(self): def config(self):
# type: () -> Config # type: () -> Config
"""Reference to the :class:`.Config` object.""" """Reference to the :class:`.Config` object."""
return self.document.settings.env.config return self.env.config
class SphinxTransformer(Transformer): class SphinxTransformer(Transformer):

View File

@ -58,13 +58,13 @@ class MathNodeMigrator(SphinxTransform):
warnings.warn("Translator for %s does not support math_block node'. " warnings.warn("Translator for %s does not support math_block node'. "
"Please update your extension." % translator, "Please update your extension." % translator,
RemovedInSphinx30Warning) RemovedInSphinx30Warning)
for math_block_node in self.document.traverse(math_block): for old_math_block_node in self.document.traverse(math_block):
alt = displaymath(latex=math_block_node.astext(), alt = displaymath(latex=old_math_block_node.astext(),
number=math_block_node.get('number'), number=old_math_block_node.get('number'),
label=math_block_node.get('label'), label=old_math_block_node.get('label'),
nowrap=math_block_node.get('nowrap'), nowrap=old_math_block_node.get('nowrap'),
docname=math_block_node.get('docname')) docname=old_math_block_node.get('docname'))
math_block_node.replace(alt) old_math_block_node.replace_self(alt)
elif getattr(self.app.builder, 'math_renderer_name', None) == 'unknown': elif getattr(self.app.builder, 'math_renderer_name', None) == 'unknown':
# case: math extension provides old styled math renderer # case: math extension provides old styled math renderer
for math_block_node in self.document.traverse(nodes.math_block): for math_block_node in self.document.traverse(nodes.math_block):

View File

@ -14,6 +14,7 @@ import os
import posixpath import posixpath
import sys import sys
import warnings import warnings
from typing import Iterable, cast
from docutils import nodes from docutils import nodes
from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator
@ -53,17 +54,17 @@ class HTMLWriter(Writer):
def translate(self): def translate(self):
# type: () -> None # type: () -> None
# sadly, this is mostly copied from parent class # sadly, this is mostly copied from parent class
self.visitor = visitor = self.builder.create_translator(self.builder, visitor = self.builder.create_translator(self.builder, self.document)
self.document) self.visitor = cast(HTMLTranslator, visitor)
self.document.walkabout(visitor) self.document.walkabout(visitor)
self.output = visitor.astext() self.output = self.visitor.astext()
for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix', for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix',
'body_pre_docinfo', 'docinfo', 'body', 'fragment', 'body_pre_docinfo', 'docinfo', 'body', 'fragment',
'body_suffix', 'meta', 'title', 'subtitle', 'header', 'body_suffix', 'meta', 'title', 'subtitle', 'header',
'footer', 'html_prolog', 'html_head', 'html_title', 'footer', 'html_prolog', 'html_head', 'html_title',
'html_subtitle', 'html_body', ): 'html_subtitle', 'html_body', ):
setattr(self, attr, getattr(visitor, attr, None)) setattr(self, attr, getattr(visitor, attr, None))
self.clean_meta = ''.join(visitor.meta[2:]) self.clean_meta = ''.join(self.visitor.meta[2:])
class HTMLTranslator(BaseTranslator): class HTMLTranslator(BaseTranslator):
@ -252,7 +253,7 @@ class HTMLTranslator(BaseTranslator):
if self.settings.cloak_email_addresses and \ if self.settings.cloak_email_addresses and \
atts['href'].startswith('mailto:'): atts['href'].startswith('mailto:'):
atts['href'] = self.cloak_mailto(atts['href']) atts['href'] = self.cloak_mailto(atts['href'])
self.in_mailto = 1 self.in_mailto = True
else: else:
assert 'refid' in node, \ assert 'refid' in node, \
'References must have "refuri" or "refid" attribute.' 'References must have "refuri" or "refid" attribute.'
@ -505,11 +506,12 @@ class HTMLTranslator(BaseTranslator):
# type: (addnodes.productionlist) -> None # type: (addnodes.productionlist) -> None
self.body.append(self.starttag(node, 'pre')) self.body.append(self.starttag(node, 'pre'))
names = [] names = []
for production in node: productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname']) names.append(production['tokenname'])
maxlen = max(len(name) for name in names) maxlen = max(len(name) for name in names)
lastname = None lastname = None
for production in node: for production in productionlist:
if production['tokenname']: if production['tokenname']:
lastname = production['tokenname'].ljust(maxlen) lastname = production['tokenname'].ljust(maxlen)
self.body.append(self.starttag(production, 'strong', '')) self.body.append(self.starttag(production, 'strong', ''))

View File

@ -13,6 +13,7 @@ import os
import posixpath import posixpath
import sys import sys
import warnings import warnings
from typing import Iterable, cast
from docutils import nodes from docutils import nodes
from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator
@ -451,11 +452,12 @@ class HTML5Translator(BaseTranslator):
# type: (addnodes.productionlist) -> None # type: (addnodes.productionlist) -> None
self.body.append(self.starttag(node, 'pre')) self.body.append(self.starttag(node, 'pre'))
names = [] names = []
for production in node: productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname']) names.append(production['tokenname'])
maxlen = max(len(name) for name in names) maxlen = max(len(name) for name in names)
lastname = None lastname = None
for production in node: for production in productionlist:
if production['tokenname']: if production['tokenname']:
lastname = production['tokenname'].ljust(maxlen) lastname = production['tokenname'].ljust(maxlen)
self.body.append(self.starttag(production, 'strong', '')) self.body.append(self.starttag(production, 'strong', ''))
@ -754,7 +756,7 @@ class HTML5Translator(BaseTranslator):
# type: (addnodes.manpage) -> None # type: (addnodes.manpage) -> None
self.visit_literal_emphasis(node) self.visit_literal_emphasis(node)
if self.manpages_url: if self.manpages_url:
node['refuri'] = self.manpages_url.format(**dict(node)) node['refuri'] = self.manpages_url.format(**node.attributes)
self.visit_reference(node) self.visit_reference(node)
def depart_manpage(self, node): def depart_manpage(self, node):

View File

@ -9,6 +9,8 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from typing import Iterable, cast
from docutils import nodes from docutils import nodes
from docutils.writers.manpage import ( from docutils.writers.manpage import (
Writer, Writer,
@ -41,9 +43,9 @@ class ManualPageWriter(Writer):
transform = NestedInlineTransform(self.document) transform = NestedInlineTransform(self.document)
transform.apply() transform.apply()
visitor = self.builder.create_translator(self.builder, self.document) visitor = self.builder.create_translator(self.builder, self.document)
self.visitor = visitor self.visitor = cast(ManualPageTranslator, visitor)
self.document.walkabout(visitor) self.document.walkabout(visitor)
self.output = visitor.astext() self.output = self.visitor.astext()
class NestedInlineTransform: class NestedInlineTransform:
@ -64,7 +66,7 @@ class NestedInlineTransform:
def apply(self, **kwargs): def apply(self, **kwargs):
# type: (Any) -> None # type: (Any) -> None
matcher = NodeMatcher(nodes.literal, nodes.emphasis, nodes.strong) matcher = NodeMatcher(nodes.literal, nodes.emphasis, nodes.strong)
for node in self.document.traverse(matcher): for node in self.document.traverse(matcher): # type: nodes.Element
if any(matcher(subnode) for subnode in node): if any(matcher(subnode) for subnode in node):
pos = node.parent.index(node) pos = node.parent.index(node)
for subnode in reversed(node[1:]): for subnode in reversed(node[1:]):
@ -292,11 +294,12 @@ class ManualPageTranslator(BaseTranslator):
names = [] names = []
self.in_productionlist += 1 self.in_productionlist += 1
self.body.append('.sp\n.nf\n') self.body.append('.sp\n.nf\n')
for production in node: productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname']) names.append(production['tokenname'])
maxlen = max(len(name) for name in names) maxlen = max(len(name) for name in names)
lastname = None lastname = None
for production in node: for production in productionlist:
if production['tokenname']: if production['tokenname']:
lastname = production['tokenname'].ljust(maxlen) lastname = production['tokenname'].ljust(maxlen)
self.body.append(self.defs['strong'][0]) self.body.append(self.defs['strong'][0])
@ -403,9 +406,10 @@ class ManualPageTranslator(BaseTranslator):
def visit_acks(self, node): def visit_acks(self, node):
# type: (addnodes.acks) -> None # type: (addnodes.acks) -> None
bullet_list = cast(nodes.bullet_list, node[0])
list_items = cast(Iterable[nodes.list_item], bullet_list)
self.ensure_eol() self.ensure_eol()
self.body.append(', '.join(n.astext() self.body.append(', '.join(n.astext() for n in list_items) + '.')
for n in node.children[0].children) + '.')
self.body.append('\n') self.body.append('\n')
raise nodes.SkipNode raise nodes.SkipNode

View File

@ -12,6 +12,7 @@
import re import re
import textwrap import textwrap
from os import path from os import path
from typing import Iterable, cast
from docutils import nodes, writers from docutils import nodes, writers
@ -135,11 +136,12 @@ class TexinfoWriter(writers.Writer):
def translate(self): def translate(self):
# type: () -> None # type: () -> None
self.visitor = visitor = self.builder.create_translator(self.document, self.builder) visitor = self.builder.create_translator(self.document, self.builder)
self.visitor = cast(TexinfoTranslator, visitor)
self.document.walkabout(visitor) self.document.walkabout(visitor)
visitor.finish() self.visitor.finish()
for attr in self.visitor_attributes: for attr in self.visitor_attributes:
setattr(self, attr, getattr(visitor, attr)) setattr(self, attr, getattr(self.visitor, attr))
class TexinfoTranslator(nodes.NodeVisitor): class TexinfoTranslator(nodes.NodeVisitor):
@ -1431,10 +1433,11 @@ class TexinfoTranslator(nodes.NodeVisitor):
# type: (addnodes.productionlist) -> None # type: (addnodes.productionlist) -> None
self.visit_literal_block(None) self.visit_literal_block(None)
names = [] names = []
for production in node: productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname']) names.append(production['tokenname'])
maxlen = max(len(name) for name in names) maxlen = max(len(name) for name in names)
for production in node: for production in productionlist:
if production['tokenname']: if production['tokenname']:
for id in production.get('ids'): for id in production.get('ids'):
self.add_anchor(id, production) self.add_anchor(id, production)
@ -1531,9 +1534,10 @@ class TexinfoTranslator(nodes.NodeVisitor):
def visit_acks(self, node): def visit_acks(self, node):
# type: (addnodes.acks) -> None # type: (addnodes.acks) -> None
bullet_list = cast(nodes.bullet_list, node[0])
list_items = cast(Iterable[nodes.list_item], bullet_list)
self.body.append('\n\n') self.body.append('\n\n')
self.body.append(', '.join(n.astext() self.body.append(', '.join(n.astext() for n in list_items) + '.')
for n in node.children[0].children) + '.')
self.body.append('\n\n') self.body.append('\n\n')
raise nodes.SkipNode raise nodes.SkipNode

View File

@ -13,6 +13,7 @@ import os
import re import re
import textwrap import textwrap
from itertools import groupby, chain from itertools import groupby, chain
from typing import Iterable, cast
from docutils import nodes, writers from docutils import nodes, writers
from docutils.utils import column_width from docutils.utils import column_width
@ -387,7 +388,7 @@ class TextWriter(writers.Writer):
# type: () -> None # type: () -> None
visitor = self.builder.create_translator(self.document, self.builder) visitor = self.builder.create_translator(self.document, self.builder)
self.document.walkabout(visitor) self.document.walkabout(visitor)
self.output = visitor.body self.output = cast(TextTranslator, visitor).body
class TextTranslator(nodes.NodeVisitor): class TextTranslator(nodes.NodeVisitor):
@ -691,11 +692,12 @@ class TextTranslator(nodes.NodeVisitor):
# type: (addnodes.productionlist) -> None # type: (addnodes.productionlist) -> None
self.new_state() self.new_state()
names = [] names = []
for production in node: productionlist = cast(Iterable[addnodes.production], node)
for production in productionlist:
names.append(production['tokenname']) names.append(production['tokenname'])
maxlen = max(len(name) for name in names) maxlen = max(len(name) for name in names)
lastname = None lastname = None
for production in node: for production in productionlist:
if production['tokenname']: if production['tokenname']:
self.add_text(production['tokenname'].ljust(maxlen) + ' ::=') self.add_text(production['tokenname'].ljust(maxlen) + ' ::=')
lastname = production['tokenname'] lastname = production['tokenname']
@ -871,9 +873,10 @@ class TextTranslator(nodes.NodeVisitor):
def visit_acks(self, node): def visit_acks(self, node):
# type: (addnodes.acks) -> None # type: (addnodes.acks) -> None
bullet_list = cast(nodes.bullet_list, node[0])
list_items = cast(Iterable[nodes.list_item], bullet_list)
self.new_state(0) self.new_state(0)
self.add_text(', '.join(n.astext() for n in node.children[0].children) + self.add_text(', '.join(n.astext() for n in list_items) + '.')
'.')
self.end_state() self.end_state()
raise nodes.SkipNode raise nodes.SkipNode