Migrate to py3 style type annotation: sphinx.writers.manpage

This commit is contained in:
Takeshi KOMIYA 2019-08-21 00:58:20 +09:00
parent ede4182c52
commit d9def51872

View File

@ -9,9 +9,11 @@
""" """
import warnings import warnings
from typing import Iterable, cast from typing import Any, Dict, Iterable
from typing import cast
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node, TextElement
from docutils.writers.manpage import ( from docutils.writers.manpage import (
Writer, Writer,
Translator as BaseTranslator Translator as BaseTranslator
@ -26,21 +28,16 @@ from sphinx.util.docutils import SphinxTranslator
from sphinx.util.i18n import format_date from sphinx.util.i18n import format_date
from sphinx.util.nodes import NodeMatcher from sphinx.util.nodes import NodeMatcher
if False:
# For type annotation
from typing import Any, Dict # NOQA
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class ManualPageWriter(Writer): class ManualPageWriter(Writer):
def __init__(self, builder): def __init__(self, builder: Builder) -> None:
# type: (Builder) -> None
super().__init__() super().__init__()
self.builder = builder self.builder = builder
def translate(self): def translate(self) -> None:
# type: () -> None
transform = NestedInlineTransform(self.document) transform = NestedInlineTransform(self.document)
transform.apply() transform.apply()
visitor = self.builder.create_translator(self.document, self.builder) visitor = self.builder.create_translator(self.document, self.builder)
@ -60,14 +57,12 @@ class NestedInlineTransform:
<strong>foo=</strong><emphasis>var</emphasis> <strong>foo=</strong><emphasis>var</emphasis>
<strong>&bar=</strong><emphasis>2</emphasis> <strong>&bar=</strong><emphasis>2</emphasis>
""" """
def __init__(self, document): def __init__(self, document: nodes.document) -> None:
# type: (nodes.document) -> None
self.document = document self.document = document
def apply(self, **kwargs): def apply(self, **kwargs) -> 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): # type: nodes.TextElement for node in self.document.traverse(matcher): # type: TextElement
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:]):
@ -86,8 +81,7 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
_docinfo = {} # type: Dict[str, Any] _docinfo = {} # type: Dict[str, Any]
def __init__(self, *args): def __init__(self, *args) -> None:
# type: (Any) -> None
if isinstance(args[0], nodes.document) and isinstance(args[1], Builder): if isinstance(args[0], nodes.document) and isinstance(args[1], Builder):
document, builder = args document, builder = args
else: else:
@ -126,153 +120,120 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
self.language.labels[label] = self.deunicode(translation) # type: ignore self.language.labels[label] = self.deunicode(translation) # type: ignore
# overwritten -- added quotes around all .TH arguments # overwritten -- added quotes around all .TH arguments
def header(self): def header(self) -> str:
# type: () -> str
tmpl = (".TH \"%(title_upper)s\" \"%(manual_section)s\"" tmpl = (".TH \"%(title_upper)s\" \"%(manual_section)s\""
" \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n" " \"%(date)s\" \"%(version)s\" \"%(manual_group)s\"\n"
".SH NAME\n" ".SH NAME\n"
"%(title)s \\- %(subtitle)s\n") "%(title)s \\- %(subtitle)s\n")
return tmpl % self._docinfo return tmpl % self._docinfo
def visit_start_of_file(self, node): def visit_start_of_file(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_start_of_file(self, node): def depart_start_of_file(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_desc(self, node): def visit_desc(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.visit_definition_list(node) self.visit_definition_list(node)
def depart_desc(self, node): def depart_desc(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.depart_definition_list(node) self.depart_definition_list(node)
def visit_desc_signature(self, node): def visit_desc_signature(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.visit_definition_list_item(node) self.visit_definition_list_item(node)
self.visit_term(node) self.visit_term(node)
def depart_desc_signature(self, node): def depart_desc_signature(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.depart_term(node) self.depart_term(node)
def visit_desc_signature_line(self, node): def visit_desc_signature_line(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_desc_signature_line(self, node): def depart_desc_signature_line(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append(' ') self.body.append(' ')
def visit_desc_addname(self, node): def visit_desc_addname(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_desc_addname(self, node): def depart_desc_addname(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_desc_type(self, node): def visit_desc_type(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_desc_type(self, node): def depart_desc_type(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_desc_returns(self, node): def visit_desc_returns(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append(' -> ') self.body.append(' -> ')
def depart_desc_returns(self, node): def depart_desc_returns(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_desc_name(self, node): def visit_desc_name(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_desc_name(self, node): def depart_desc_name(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_desc_parameterlist(self, node): def visit_desc_parameterlist(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append('(') self.body.append('(')
self.first_param = 1 self.first_param = 1
def depart_desc_parameterlist(self, node): def depart_desc_parameterlist(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append(')') self.body.append(')')
def visit_desc_parameter(self, node): def visit_desc_parameter(self, node: Element) -> None:
# type: (nodes.Element) -> None
if not self.first_param: if not self.first_param:
self.body.append(', ') self.body.append(', ')
else: else:
self.first_param = 0 self.first_param = 0
def depart_desc_parameter(self, node): def depart_desc_parameter(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_desc_optional(self, node): def visit_desc_optional(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append('[') self.body.append('[')
def depart_desc_optional(self, node): def depart_desc_optional(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append(']') self.body.append(']')
def visit_desc_annotation(self, node): def visit_desc_annotation(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_desc_annotation(self, node): def depart_desc_annotation(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_desc_content(self, node): def visit_desc_content(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.visit_definition(node) self.visit_definition(node)
def depart_desc_content(self, node): def depart_desc_content(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.depart_definition(node) self.depart_definition(node)
def visit_versionmodified(self, node): def visit_versionmodified(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.visit_paragraph(node) self.visit_paragraph(node)
def depart_versionmodified(self, node): def depart_versionmodified(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.depart_paragraph(node) self.depart_paragraph(node)
# overwritten -- don't make whole of term bold if it includes strong node # overwritten -- don't make whole of term bold if it includes strong node
def visit_term(self, node): def visit_term(self, node: Element) -> None:
# type: (nodes.Element) -> None
if node.traverse(nodes.strong): if node.traverse(nodes.strong):
self.body.append('\n') self.body.append('\n')
else: else:
super().visit_term(node) super().visit_term(node)
# overwritten -- we don't want source comments to show up # overwritten -- we don't want source comments to show up
def visit_comment(self, node): # type: ignore def visit_comment(self, node: Element) -> None: # type: ignore
# type: (nodes.Element) -> None
raise nodes.SkipNode raise nodes.SkipNode
# overwritten -- added ensure_eol() # overwritten -- added ensure_eol()
def visit_footnote(self, node): def visit_footnote(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.ensure_eol() self.ensure_eol()
super().visit_footnote(node) super().visit_footnote(node)
# overwritten -- handle footnotes rubric # overwritten -- handle footnotes rubric
def visit_rubric(self, node): def visit_rubric(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.ensure_eol() self.ensure_eol()
if len(node) == 1 and node.astext() in ('Footnotes', _('Footnotes')): if len(node) == 1 and node.astext() in ('Footnotes', _('Footnotes')):
self.body.append('.SH ' + self.deunicode(node.astext()).upper() + '\n') self.body.append('.SH ' + self.deunicode(node.astext()).upper() + '\n')
@ -280,20 +241,16 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
else: else:
self.body.append('.sp\n') self.body.append('.sp\n')
def depart_rubric(self, node): def depart_rubric(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append('\n') self.body.append('\n')
def visit_seealso(self, node): def visit_seealso(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.visit_admonition(node, 'seealso') self.visit_admonition(node, 'seealso')
def depart_seealso(self, node): def depart_seealso(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.depart_admonition(node) self.depart_admonition(node)
def visit_productionlist(self, node): def visit_productionlist(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.ensure_eol() self.ensure_eol()
names = [] names = []
self.in_productionlist += 1 self.in_productionlist += 1
@ -318,25 +275,21 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
self.in_productionlist -= 1 self.in_productionlist -= 1
raise nodes.SkipNode raise nodes.SkipNode
def visit_production(self, node): def visit_production(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_production(self, node): def depart_production(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
# overwritten -- don't emit a warning for images # overwritten -- don't emit a warning for images
def visit_image(self, node): def visit_image(self, node: Element) -> None:
# type: (nodes.Element) -> None
if 'alt' in node.attributes: if 'alt' in node.attributes:
self.body.append(_('[image: %s]') % node['alt'] + '\n') self.body.append(_('[image: %s]') % node['alt'] + '\n')
self.body.append(_('[image]') + '\n') self.body.append(_('[image]') + '\n')
raise nodes.SkipNode raise nodes.SkipNode
# overwritten -- don't visit inner marked up nodes # overwritten -- don't visit inner marked up nodes
def visit_reference(self, node): def visit_reference(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append(self.defs['reference'][0]) self.body.append(self.defs['reference'][0])
# avoid repeating escaping code... fine since # avoid repeating escaping code... fine since
# visit_Text calls astext() and only works on that afterwards # visit_Text calls astext() and only works on that afterwards
@ -357,59 +310,46 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
'>']) '>'])
raise nodes.SkipNode raise nodes.SkipNode
def visit_number_reference(self, node): def visit_number_reference(self, node: Element) -> None:
# type: (nodes.Element) -> None
text = nodes.Text(node.get('title', '#')) text = nodes.Text(node.get('title', '#'))
self.visit_Text(text) self.visit_Text(text)
raise nodes.SkipNode raise nodes.SkipNode
def visit_centered(self, node): def visit_centered(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.ensure_eol() self.ensure_eol()
self.body.append('.sp\n.ce\n') self.body.append('.sp\n.ce\n')
def depart_centered(self, node): def depart_centered(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.body.append('\n.ce 0\n') self.body.append('\n.ce 0\n')
def visit_compact_paragraph(self, node): def visit_compact_paragraph(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_compact_paragraph(self, node): def depart_compact_paragraph(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_download_reference(self, node): def visit_download_reference(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_download_reference(self, node): def depart_download_reference(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_toctree(self, node): def visit_toctree(self, node: Element) -> None:
# type: (nodes.Element) -> None
raise nodes.SkipNode raise nodes.SkipNode
def visit_index(self, node): def visit_index(self, node: Element) -> None:
# type: (nodes.Element) -> None
raise nodes.SkipNode raise nodes.SkipNode
def visit_tabular_col_spec(self, node): def visit_tabular_col_spec(self, node: Element) -> None:
# type: (nodes.Element) -> None
raise nodes.SkipNode raise nodes.SkipNode
def visit_glossary(self, node): def visit_glossary(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_glossary(self, node): def depart_glossary(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_acks(self, node): def visit_acks(self, node: Element) -> None:
# type: (nodes.Element) -> None
bullet_list = cast(nodes.bullet_list, node[0]) bullet_list = cast(nodes.bullet_list, node[0])
list_items = cast(Iterable[nodes.list_item], bullet_list) list_items = cast(Iterable[nodes.list_item], bullet_list)
self.ensure_eol() self.ensure_eol()
@ -419,72 +359,57 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
self.body.append('\n') self.body.append('\n')
raise nodes.SkipNode raise nodes.SkipNode
def visit_hlist(self, node): def visit_hlist(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.visit_bullet_list(node) self.visit_bullet_list(node)
def depart_hlist(self, node): def depart_hlist(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.depart_bullet_list(node) self.depart_bullet_list(node)
def visit_hlistcol(self, node): def visit_hlistcol(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_hlistcol(self, node): def depart_hlistcol(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_literal_emphasis(self, node): def visit_literal_emphasis(self, node: Element) -> None:
# type: (nodes.Element) -> None
return self.visit_emphasis(node) return self.visit_emphasis(node)
def depart_literal_emphasis(self, node): def depart_literal_emphasis(self, node: Element) -> None:
# type: (nodes.Element) -> None
return self.depart_emphasis(node) return self.depart_emphasis(node)
def visit_literal_strong(self, node): def visit_literal_strong(self, node: Element) -> None:
# type: (nodes.Element) -> None
return self.visit_strong(node) return self.visit_strong(node)
def depart_literal_strong(self, node): def depart_literal_strong(self, node: Element) -> None:
# type: (nodes.Element) -> None
return self.depart_strong(node) return self.depart_strong(node)
def visit_abbreviation(self, node): def visit_abbreviation(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_abbreviation(self, node): def depart_abbreviation(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_manpage(self, node): def visit_manpage(self, node: Element) -> None:
# type: (nodes.Element) -> None
return self.visit_strong(node) return self.visit_strong(node)
def depart_manpage(self, node): def depart_manpage(self, node: Element) -> None:
# type: (nodes.Element) -> None
return self.depart_strong(node) return self.depart_strong(node)
# overwritten: handle section titles better than in 0.6 release # overwritten: handle section titles better than in 0.6 release
def visit_caption(self, node): def visit_caption(self, node: Element) -> None:
# type: (nodes.Element) -> None
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'): if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
self.body.append('.sp\n') self.body.append('.sp\n')
else: else:
super().visit_caption(node) super().visit_caption(node)
def depart_caption(self, node): def depart_caption(self, node: Element) -> None:
# type: (nodes.Element) -> None
if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'): if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'):
self.body.append('\n') self.body.append('\n')
else: else:
super().depart_caption(node) super().depart_caption(node)
# overwritten: handle section titles better than in 0.6 release # overwritten: handle section titles better than in 0.6 release
def visit_title(self, node): def visit_title(self, node: Element) -> None:
# type: (nodes.Element) -> None
if isinstance(node.parent, addnodes.seealso): if isinstance(node.parent, addnodes.seealso):
self.body.append('.IP "') self.body.append('.IP "')
return return
@ -498,47 +423,37 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator):
raise nodes.SkipNode raise nodes.SkipNode
return super().visit_title(node) return super().visit_title(node)
def depart_title(self, node): def depart_title(self, node: Element) -> None:
# type: (nodes.Element) -> None
if isinstance(node.parent, addnodes.seealso): if isinstance(node.parent, addnodes.seealso):
self.body.append('"\n') self.body.append('"\n')
return return
return super().depart_title(node) return super().depart_title(node)
def visit_raw(self, node): def visit_raw(self, node: Element) -> None:
# type: (nodes.Element) -> None
if 'manpage' in node.get('format', '').split(): if 'manpage' in node.get('format', '').split():
self.body.append(node.astext()) self.body.append(node.astext())
raise nodes.SkipNode raise nodes.SkipNode
def visit_meta(self, node): def visit_meta(self, node: Element) -> None:
# type: (nodes.Element) -> None
raise nodes.SkipNode raise nodes.SkipNode
def visit_inline(self, node): def visit_inline(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_inline(self, node): def depart_inline(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_math(self, node): def visit_math(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def depart_math(self, node): def depart_math(self, node: Element) -> None:
# type: (nodes.Element) -> None
pass pass
def visit_math_block(self, node): def visit_math_block(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.visit_centered(node) self.visit_centered(node)
def depart_math_block(self, node): def depart_math_block(self, node: Element) -> None:
# type: (nodes.Element) -> None
self.depart_centered(node) self.depart_centered(node)
def unknown_visit(self, node): def unknown_visit(self, node: Node) -> None:
# type: (nodes.Node) -> None
raise NotImplementedError('Unknown node: ' + node.__class__.__name__) raise NotImplementedError('Unknown node: ' + node.__class__.__name__)