diff options
Diffstat (limited to 'sphinx/util/nodes.py')
-rw-r--r-- | sphinx/util/nodes.py | 98 |
1 files changed, 38 insertions, 60 deletions
diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index 58c6a6698..e0aaaa14e 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -10,9 +10,14 @@ import re import warnings -from typing import Any, cast +from typing import Any, Callable, Iterable, List, Set, Tuple, Type +from typing import cast from docutils import nodes +from docutils.nodes import Element, Node +from docutils.parsers.rst import Directive +from docutils.parsers.rst.states import Inliner +from docutils.statemachine import StringList from sphinx import addnodes from sphinx.deprecation import RemovedInSphinx40Warning @@ -21,11 +26,8 @@ from sphinx.util import logging if False: # For type annotation - from typing import Callable, Iterable, List, Optional, Set, Tuple, Type # NOQA - from docutils.parsers.rst.states import Inliner # NOQA - from docutils.statemachine import StringList # NOQA - from sphinx.builders import Builder # NOQA - from sphinx.utils.tags import Tags # NOQA + from sphinx.builders import Builder + from sphinx.utils.tags import Tags logger = logging.getLogger(__name__) @@ -57,13 +59,11 @@ class NodeMatcher: # => [<reference ...>, <reference ...>, ...] """ - def __init__(self, *classes, **attrs): - # type: (Type[nodes.Node], Any) -> None + def __init__(self, *classes: Type[Node], **attrs) -> None: self.classes = classes self.attrs = attrs - def match(self, node): - # type: (nodes.Node) -> bool + def match(self, node: Node) -> bool: try: if self.classes and not isinstance(node, self.classes): return False @@ -85,13 +85,11 @@ class NodeMatcher: # for non-Element nodes return False - def __call__(self, node): - # type: (nodes.Node) -> bool + def __call__(self, node: Node) -> bool: return self.match(node) -def get_full_module_name(node): - # type: (nodes.Node) -> str +def get_full_module_name(node: Node) -> str: """ return full module dotted path like: 'docutils.nodes.paragraph' @@ -101,8 +99,7 @@ def get_full_module_name(node): return '{}.{}'.format(node.__module__, node.__class__.__name__) -def repr_domxml(node, length=80): - # type: (nodes.Node, Optional[int]) -> str +def repr_domxml(node: Node, length: int = 80) -> str: """ return DOM XML representation of the specified node like: '<paragraph translatable="False"><inline classes="versionmodified">New in version...' @@ -122,8 +119,7 @@ def repr_domxml(node, length=80): return text -def apply_source_workaround(node): - # type: (nodes.Element) -> None +def apply_source_workaround(node: Element) -> None: # workaround: nodes.term have wrong rawsource if classifier is specified. # The behavior of docutils-0.11, 0.12 is: # * when ``term text : classifier1 : classifier2`` is specified, @@ -186,8 +182,7 @@ IGNORED_NODES = ( ) -def is_pending_meta(node): - # type: (nodes.Node) -> bool +def is_pending_meta(node: Node) -> bool: if (isinstance(node, nodes.pending) and isinstance(node.details.get('nodes', [None])[0], addnodes.meta)): return True @@ -195,8 +190,7 @@ def is_pending_meta(node): return False -def is_translatable(node): - # type: (nodes.Node) -> bool +def is_translatable(node: Node) -> bool: if isinstance(node, addnodes.translatable): return True @@ -251,8 +245,7 @@ META_TYPE_NODES = ( ) -def extract_messages(doctree): - # type: (nodes.Element) -> Iterable[Tuple[nodes.Element, str]] +def extract_messages(doctree: Element) -> Iterable[Tuple[Element, str]]: """Extract translatable messages from a document tree.""" for node in doctree.traverse(is_translatable): # type: nodes.Element if isinstance(node, addnodes.translatable): @@ -279,39 +272,34 @@ def extract_messages(doctree): yield node, msg -def find_source_node(node): - # type: (nodes.Element) -> str +def find_source_node(node: Element) -> str: warnings.warn('find_source_node() is deprecated.', RemovedInSphinx40Warning) return get_node_source(node) -def get_node_source(node): - # type: (nodes.Element) -> str +def get_node_source(node: Element) -> str: for pnode in traverse_parent(node): if pnode.source: return pnode.source return None -def get_node_line(node): - # type: (nodes.Element) -> int +def get_node_line(node: Element) -> int: for pnode in traverse_parent(node): if pnode.line: return pnode.line return None -def traverse_parent(node, cls=None): - # type: (nodes.Element, Any) -> Iterable[nodes.Element] +def traverse_parent(node: Element, cls: Any = None) -> Iterable[Element]: while node: if cls is None or isinstance(node, cls): yield node node = node.parent -def get_prev_node(node): - # type: (nodes.Node) -> nodes.Node +def get_prev_node(node: Node) -> Node: pos = node.parent.index(node) if pos > 0: return node.parent[pos - 1] @@ -319,8 +307,7 @@ def get_prev_node(node): return None -def traverse_translatable_index(doctree): - # type: (nodes.Element) -> Iterable[Tuple[nodes.Element, List[str]]] +def traverse_translatable_index(doctree: Element) -> Iterable[Tuple[Element, List[str]]]: """Traverse translatable index node from a document tree.""" for node in doctree.traverse(NodeMatcher(addnodes.index, inline=False)): # type: addnodes.index # NOQA if 'raw_entries' in node: @@ -330,8 +317,7 @@ def traverse_translatable_index(doctree): yield node, entries -def nested_parse_with_titles(state, content, node): - # type: (Any, StringList, nodes.Node) -> str +def nested_parse_with_titles(state: Any, content: StringList, node: Node) -> str: """Version of state.nested_parse() that allows titles and does not require titles to have the same decoration as the calling document. @@ -350,8 +336,7 @@ def nested_parse_with_titles(state, content, node): state.memo.section_level = surrounding_section_level -def clean_astext(node): - # type: (nodes.Element) -> str +def clean_astext(node: Element) -> str: """Like node.astext(), but ignore images.""" node = node.deepcopy() for img in node.traverse(nodes.image): @@ -361,8 +346,7 @@ def clean_astext(node): return node.astext() -def split_explicit_title(text): - # type: (str) -> Tuple[bool, str, str] +def split_explicit_title(text: str) -> Tuple[bool, str, str]: """Split role content into title and target, if given.""" match = explicit_title_re.match(text) if match: @@ -375,8 +359,7 @@ indextypes = [ ] -def process_index_entry(entry, targetid): - # type: (str, str) -> List[Tuple[str, str, str, str, str]] +def process_index_entry(entry: str, targetid: str) -> List[Tuple[str, str, str, str, str]]: from sphinx.domains.python import pairindextypes indexentries = [] # type: List[Tuple[str, str, str, str, str]] @@ -414,8 +397,9 @@ def process_index_entry(entry, targetid): return indexentries -def inline_all_toctrees(builder, docnameset, docname, tree, colorfunc, traversed): - # type: (Builder, Set[str], str, nodes.document, Callable, List[str]) -> nodes.document +def inline_all_toctrees(builder: "Builder", docnameset: Set[str], docname: str, + tree: nodes.document, colorfunc: Callable, traversed: List[str] + ) -> nodes.document: """Inline all toctrees in the *tree*. Record all docnames in *docnameset*, and output docnames with *colorfunc*. @@ -447,8 +431,8 @@ def inline_all_toctrees(builder, docnameset, docname, tree, colorfunc, traversed return tree -def make_refnode(builder, fromdocname, todocname, targetid, child, title=None): - # type: (Builder, str, str, str, nodes.Node, str) -> nodes.reference +def make_refnode(builder: "Builder", fromdocname: str, todocname: str, targetid: str, + child: Node, title: str = None) -> nodes.reference: """Shortcut to create a reference node.""" node = nodes.reference('', '', internal=True) if fromdocname == todocname and targetid: @@ -465,19 +449,16 @@ def make_refnode(builder, fromdocname, todocname, targetid, child, title=None): return node -def set_source_info(directive, node): - # type: (Any, nodes.Node) -> None +def set_source_info(directive: Directive, node: Node) -> None: node.source, node.line = \ directive.state_machine.get_source_and_line(directive.lineno) -def set_role_source_info(inliner, lineno, node): - # type: (Inliner, int, nodes.Node) -> None +def set_role_source_info(inliner: Inliner, lineno: int, node: Node) -> None: node.source, node.line = inliner.reporter.get_source_and_line(lineno) # type: ignore -def copy_source_info(src, dst): - # type: (nodes.Element, nodes.Element) -> None +def copy_source_info(src: Element, dst: Element) -> None: dst.source = get_node_source(src) dst.line = get_node_line(src) @@ -493,8 +474,7 @@ NON_SMARTQUOTABLE_PARENT_NODES = ( ) -def is_smartquotable(node): - # type: (nodes.Node) -> bool +def is_smartquotable(node: Node) -> bool: """Check the node is smart-quotable or not.""" if isinstance(node.parent, NON_SMARTQUOTABLE_PARENT_NODES): return False @@ -506,8 +486,7 @@ def is_smartquotable(node): return True -def process_only_nodes(document, tags): - # type: (nodes.Node, Tags) -> None +def process_only_nodes(document: Node, tags: "Tags") -> None: """Filter ``only`` nodes which does not match *tags*.""" for node in document.traverse(addnodes.only): try: @@ -530,8 +509,7 @@ def process_only_nodes(document, tags): # monkey-patch Element.copy to copy the rawsource and line # for docutils-0.14 or older versions. -def _new_copy(self): - # type: (nodes.Element) -> nodes.Element +def _new_copy(self: Element) -> Element: newnode = self.__class__(self.rawsource, **self.attributes) if isinstance(self, nodes.Element): newnode.source = self.source |