diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py index a4e6e52bf..f3af5cd47 100644 --- a/sphinx/transforms/__init__.py +++ b/sphinx/transforms/__init__.py @@ -9,8 +9,10 @@ """ import re +from typing import Any, Dict, Generator, List, Tuple from docutils import nodes +from docutils.nodes import Element, Node, Text from docutils.transforms import Transform, Transformer from docutils.transforms.parts import ContentsFilter from docutils.transforms.universal import SmartQuotes @@ -18,6 +20,7 @@ from docutils.utils import normalize_language_tag from docutils.utils.smartquotes import smartchars from sphinx import addnodes +from sphinx.config import Config from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.locale import _, __ from sphinx.util import logging @@ -27,11 +30,9 @@ from sphinx.util.nodes import NodeMatcher, apply_source_workaround, is_smartquot if False: # For type annotation - from typing import Any, Dict, Generator, List, Tuple # NOQA - from sphinx.application import Sphinx # NOQA - from sphinx.config import Config # NOQA - from sphinx.domain.std import StandardDomain # NOQA - from sphinx.environment import BuildEnvironment # NOQA + from sphinx.application import Sphinx + from sphinx.domain.std import StandardDomain + from sphinx.environment import BuildEnvironment logger = logging.getLogger(__name__) @@ -51,20 +52,17 @@ class SphinxTransform(Transform): """ @property - def app(self): - # type: () -> Sphinx + def app(self) -> "Sphinx": """Reference to the :class:`.Sphinx` object.""" return self.env.app @property - def env(self): - # type: () -> BuildEnvironment + def env(self) -> "BuildEnvironment": """Reference to the :class:`.BuildEnvironment` object.""" return self.document.settings.env @property - def config(self): - # type: () -> Config + def config(self) -> Config: """Reference to the :class:`.Config` object.""" return self.env.config @@ -77,12 +75,10 @@ class SphinxTransformer(Transformer): document = None # type: nodes.document env = None # type: BuildEnvironment - def set_environment(self, env): - # type: (BuildEnvironment) -> None + def set_environment(self, env: "BuildEnvironment") -> None: self.env = env - def apply_transforms(self): - # type: () -> None + def apply_transforms(self) -> None: if isinstance(self.document, nodes.document): if not hasattr(self.document.settings, 'env') and self.env: self.document.settings.env = self.env @@ -108,8 +104,7 @@ class DefaultSubstitutions(SphinxTransform): # run before the default Substitutions default_priority = 210 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: # only handle those not otherwise defined in the document to_handle = default_substitutions - set(self.document.substitution_defs) for ref in self.document.traverse(nodes.substitution_reference): @@ -132,8 +127,7 @@ class MoveModuleTargets(SphinxTransform): """ default_priority = 210 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for node in self.document.traverse(nodes.target): if not node['ids']: continue @@ -151,8 +145,7 @@ class HandleCodeBlocks(SphinxTransform): """ default_priority = 210 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: # move doctest blocks out of blockquotes for node in self.document.traverse(nodes.block_quote): if all(isinstance(child, nodes.doctest_block) for child @@ -176,8 +169,7 @@ class AutoNumbering(SphinxTransform): """ default_priority = 210 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: domain = self.env.get_domain('std') # type: StandardDomain for node in self.document.traverse(nodes.Element): @@ -191,8 +183,7 @@ class SortIds(SphinxTransform): """ default_priority = 261 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for node in self.document.traverse(nodes.section): if len(node['ids']) > 1 and node['ids'][0].startswith('id'): node['ids'] = node['ids'][1:] + [node['ids'][0]] @@ -213,9 +204,8 @@ class ApplySourceWorkaround(SphinxTransform): """ default_priority = 10 - def apply(self, **kwargs): - # type: (Any) -> None - for node in self.document.traverse(): # type: nodes.Node + def apply(self, **kwargs) -> None: + for node in self.document.traverse(): # type: Node if isinstance(node, (nodes.TextElement, nodes.image)): apply_source_workaround(node) @@ -226,8 +216,7 @@ class AutoIndexUpgrader(SphinxTransform): """ default_priority = 210 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for node in self.document.traverse(addnodes.index): if 'entries' in node and any(len(entry) == 4 for entry in node['entries']): msg = __('4 column based index found. ' @@ -244,18 +233,16 @@ class ExtraTranslatableNodes(SphinxTransform): """ default_priority = 10 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: targets = self.config.gettext_additional_targets target_nodes = [v for k, v in TRANSLATABLE_NODES.items() if k in targets] if not target_nodes: return - def is_translatable_node(node): - # type: (nodes.Node) -> bool + def is_translatable_node(node: Node) -> bool: return isinstance(node, tuple(target_nodes)) - for node in self.document.traverse(is_translatable_node): # type: nodes.Element + for node in self.document.traverse(is_translatable_node): # type: Element node['translatable'] = True @@ -265,8 +252,7 @@ class UnreferencedFootnotesDetector(SphinxTransform): """ default_priority = 200 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for node in self.document.footnotes: if node['names'] == []: # footnote having duplicated number. It is already warned at parser. @@ -289,10 +275,9 @@ class FigureAligner(SphinxTransform): """ default_priority = 700 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: matcher = NodeMatcher(nodes.table, nodes.figure) - for node in self.document.traverse(matcher): # type: nodes.Element + for node in self.document.traverse(matcher): # type: Element node.setdefault('align', 'default') @@ -300,8 +285,7 @@ class FilterSystemMessages(SphinxTransform): """Filter system messages from a doctree.""" default_priority = 999 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: filterlevel = self.config.keep_warnings and 2 or 5 for node in self.document.traverse(nodes.system_message): if node['level'] < filterlevel: @@ -316,8 +300,7 @@ class SphinxContentsFilter(ContentsFilter): """ visit_pending_xref = ContentsFilter.ignore_node_but_process_children - def visit_image(self, node): - # type: (nodes.image) -> None + def visit_image(self, node: nodes.image) -> None: raise nodes.SkipNode @@ -329,8 +312,7 @@ class SphinxSmartQuotes(SmartQuotes, SphinxTransform): """ default_priority = 750 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: if not self.is_available(): return @@ -339,8 +321,7 @@ class SphinxSmartQuotes(SmartQuotes, SphinxTransform): super().apply() - def is_available(self): - # type: () -> bool + def is_available(self) -> bool: builders = self.config.smartquotes_excludes.get('builders', []) languages = self.config.smartquotes_excludes.get('languages', []) @@ -365,8 +346,7 @@ class SphinxSmartQuotes(SmartQuotes, SphinxTransform): else: return False - def get_tokens(self, txtnodes): - # type: (List[nodes.Text]) -> Generator[Tuple[str, str], None, None] + def get_tokens(self, txtnodes: List[Text]) -> Generator[Tuple[str, str], None, None]: # A generator that yields ``(texttype, nodetext)`` tuples for a list # of "Text" nodes (interface to ``smartquotes.educate_tokens()``). @@ -381,8 +361,7 @@ class DoctreeReadEvent(SphinxTransform): """Emit :event:`doctree-read` event.""" default_priority = 880 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: self.app.emit('doctree-read', self.document) @@ -390,8 +369,7 @@ class ManpageLink(SphinxTransform): """Find manpage section numbers and names""" default_priority = 999 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for node in self.document.traverse(addnodes.manpage): manpage = ' '.join([str(x) for x in node.children if isinstance(x, nodes.Text)]) @@ -417,8 +395,7 @@ deprecated_alias('sphinx.transforms', RemovedInSphinx40Warning) -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: "Sphinx") -> Dict[str, Any]: app.add_transform(ApplySourceWorkaround) app.add_transform(ExtraTranslatableNodes) app.add_transform(DefaultSubstitutions) diff --git a/sphinx/transforms/compact_bullet_list.py b/sphinx/transforms/compact_bullet_list.py index e118e6a84..09274cd5f 100644 --- a/sphinx/transforms/compact_bullet_list.py +++ b/sphinx/transforms/compact_bullet_list.py @@ -8,18 +8,16 @@ :license: BSD, see LICENSE for details. """ +from typing import Any, Dict, List from typing import cast from docutils import nodes +from docutils.nodes import Node from sphinx import addnodes +from sphinx.application import Sphinx from sphinx.transforms import SphinxTransform -if False: - # For type annotation - from typing import Any, Dict, List # NOQA - from sphinx.application import Sphinx # NOQA - class RefOnlyListChecker(nodes.GenericNodeVisitor): """Raise `nodes.NodeFound` if non-simple list item is encountered. @@ -28,17 +26,14 @@ class RefOnlyListChecker(nodes.GenericNodeVisitor): single reference in it. """ - def default_visit(self, node): - # type: (nodes.Node) -> None + def default_visit(self, node: Node) -> None: raise nodes.NodeFound - def visit_bullet_list(self, node): - # type: (nodes.bullet_list) -> None + def visit_bullet_list(self, node: nodes.bullet_list) -> None: pass - def visit_list_item(self, node): - # type: (nodes.list_item) -> None - children = [] # type: List[nodes.Node] + def visit_list_item(self, node: nodes.list_item) -> None: + children = [] # type: List[Node] for child in node.children: if not isinstance(child, nodes.Invisible): children.append(child) @@ -53,8 +48,7 @@ class RefOnlyListChecker(nodes.GenericNodeVisitor): raise nodes.NodeFound raise nodes.SkipChildren - def invisible_visit(self, node): - # type: (nodes.Node) -> None + def invisible_visit(self, node: Node) -> None: """Invisible nodes should be ignored.""" pass @@ -67,13 +61,11 @@ class RefOnlyBulletListTransform(SphinxTransform): """ default_priority = 100 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: if self.config.html_compact_lists: return - def check_refonly_list(node): - # type: (nodes.Node) -> bool + def check_refonly_list(node: Node) -> bool: """Check for list with only references in it.""" visitor = RefOnlyListChecker(self.document) try: @@ -93,8 +85,7 @@ class RefOnlyBulletListTransform(SphinxTransform): item.replace(para, compact_para) -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: Sphinx) -> Dict[str, Any]: app.add_transform(RefOnlyBulletListTransform) return { diff --git a/sphinx/transforms/i18n.py b/sphinx/transforms/i18n.py index d6704347e..d970670a1 100644 --- a/sphinx/transforms/i18n.py +++ b/sphinx/transforms/i18n.py @@ -10,13 +10,15 @@ from os import path from textwrap import indent -from typing import Any, TypeVar +from typing import Any, Dict, List, Tuple, TypeVar from docutils import nodes from docutils.io import StringInput +from docutils.nodes import Element from docutils.utils import relative_path from sphinx import addnodes +from sphinx.config import Config from sphinx.domains.std import make_glossary_term, split_term_classifiers from sphinx.locale import __, init as init_locale from sphinx.transforms import SphinxTransform @@ -29,18 +31,17 @@ from sphinx.util.nodes import ( if False: # For type annotation - from typing import Dict, List, Tuple # NOQA from typing import Type # for python3.5.1 - from sphinx.application import Sphinx # NOQA - from sphinx.config import Config # NOQA + from sphinx.application import Sphinx + logger = logging.getLogger(__name__) N = TypeVar('N', bound=nodes.Node) -def publish_msgstr(app, source, source_path, source_line, config, settings): - # type: (Sphinx, str, str, int, Config, Any) -> nodes.Element +def publish_msgstr(app: "Sphinx", source: str, source_path: str, source_line: int, + config: Config, settings: Any) -> Element: """Publish msgstr (single line) into docutils document :param sphinx.application.Sphinx app: sphinx application @@ -75,8 +76,7 @@ class PreserveTranslatableMessages(SphinxTransform): """ default_priority = 10 # this MUST be invoked before Locale transform - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for node in self.document.traverse(addnodes.translatable): node.preserve_original_messages() @@ -87,8 +87,7 @@ class Locale(SphinxTransform): """ default_priority = 20 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: settings, source = self.document.settings, self.document['source'] msgstr = '' @@ -268,7 +267,7 @@ class Locale(SphinxTransform): unexpected = ( nodes.paragraph, # expected form of translation nodes.title # generated by above "Subelements phase2" - ) # type: Tuple[Type[nodes.Element], ...] + ) # type: Tuple[Type[Element], ...] # following types are expected if # config.gettext_additional_targets is configured @@ -279,8 +278,7 @@ class Locale(SphinxTransform): continue # skip # auto-numbered foot note reference should use original 'ids'. - def list_replace_or_append(lst, old, new): - # type: (List[N], N, N) -> None + def list_replace_or_append(lst: List[N], old: N, new: N) -> None: if old in lst: lst[lst.index(old)] = new else: @@ -406,8 +404,7 @@ class Locale(SphinxTransform): .format(old_xref_rawsources, new_xref_rawsources), location=node) - def get_ref_key(node): - # type: (addnodes.pending_xref) -> Tuple[str, str, str] + def get_ref_key(node: addnodes.pending_xref) -> Tuple[str, str, str]: case = node["refdomain"], node["reftype"] if case == ('std', 'term'): return None @@ -465,7 +462,7 @@ class Locale(SphinxTransform): node['entries'] = new_entries # remove translated attribute that is used for avoiding double translation. - for translated in self.document.traverse(NodeMatcher(translated=Any)): # type: nodes.Element # NOQA + for translated in self.document.traverse(NodeMatcher(translated=Any)): # type: Element # NOQA translated.delattr('translated') @@ -475,8 +472,7 @@ class RemoveTranslatableInline(SphinxTransform): """ default_priority = 999 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: from sphinx.builders.gettext import MessageCatalogBuilder if isinstance(self.app.builder, MessageCatalogBuilder): return @@ -487,8 +483,7 @@ class RemoveTranslatableInline(SphinxTransform): inline.parent += inline.children -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: "Sphinx") -> Dict[str, Any]: app.add_transform(PreserveTranslatableMessages) app.add_transform(Locale) app.add_transform(RemoveTranslatableInline) diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py index 8f64266d0..090ff0084 100644 --- a/sphinx/transforms/post_transforms/__init__.py +++ b/sphinx/transforms/post_transforms/__init__.py @@ -8,23 +8,22 @@ :license: BSD, see LICENSE for details. """ +from typing import Any, Dict, List, Tuple from typing import cast from docutils import nodes +from docutils.nodes import Element from sphinx import addnodes +from sphinx.addnodes import pending_xref +from sphinx.application import Sphinx +from sphinx.domains import Domain from sphinx.errors import NoUri from sphinx.locale import __ from sphinx.transforms import SphinxTransform from sphinx.util import logging from sphinx.util.nodes import process_only_nodes -if False: - # For type annotation - from typing import Any, Dict, List, Tuple # NOQA - from sphinx.application import Sphinx # NOQA - from sphinx.domains import Domain # NOQA - logger = logging.getLogger(__name__) @@ -39,13 +38,11 @@ class SphinxPostTransform(SphinxTransform): builders = () # type: Tuple[str, ...] formats = () # type: Tuple[str, ...] - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: if self.is_supported(): self.run(**kwargs) - def is_supported(self): - # type: () -> bool + def is_supported(self) -> bool: """Check this transform working for current builder.""" if self.builders and self.app.builder.name not in self.builders: return False @@ -54,8 +51,7 @@ class SphinxPostTransform(SphinxTransform): return True - def run(self, **kwargs): - # type: (Any) -> None + def run(self, **kwargs) -> None: """main method of post transforms. Subclasses should override this method instead of ``apply()``. @@ -70,8 +66,7 @@ class ReferencesResolver(SphinxPostTransform): default_priority = 10 - def run(self, **kwargs): - # type: (Any) -> None + def run(self, **kwargs) -> None: for node in self.document.traverse(addnodes.pending_xref): contnode = cast(nodes.TextElement, node[0].deepcopy()) newnode = None @@ -105,12 +100,11 @@ class ReferencesResolver(SphinxPostTransform): newnode = contnode node.replace_self(newnode or contnode) - def resolve_anyref(self, refdoc, node, contnode): - # type: (str, addnodes.pending_xref, nodes.TextElement) -> nodes.Element + def resolve_anyref(self, refdoc: str, node: pending_xref, contnode: Element) -> Element: """Resolve reference generated by the "any" role.""" stddomain = self.env.get_domain('std') target = node['reftarget'] - results = [] # type: List[Tuple[str, nodes.Element]] + results = [] # type: List[Tuple[str, Element]] # first, try resolving as :doc: doc_ref = stddomain.resolve_xref(self.env, refdoc, self.app.builder, 'doc', target, node, contnode) @@ -155,8 +149,8 @@ class ReferencesResolver(SphinxPostTransform): newnode[0]['classes'].append(res_role.replace(':', '-')) return newnode - def warn_missing_reference(self, refdoc, typ, target, node, domain): - # type: (str, str, str, addnodes.pending_xref, Domain) -> None + def warn_missing_reference(self, refdoc: str, typ: str, target: str, + node: pending_xref, domain: Domain) -> None: warn = node.get('refwarn') if self.config.nitpicky: warn = True @@ -184,8 +178,7 @@ class ReferencesResolver(SphinxPostTransform): class OnlyNodeTransform(SphinxPostTransform): default_priority = 50 - def run(self, **kwargs): - # type: (Any) -> None + def run(self, **kwargs) -> None: # A comment on the comment() nodes being inserted: replacing by [] would # result in a "Losing ids" exception if there is a target node before # the only node, so we make sure docutils can transfer the id to @@ -193,8 +186,7 @@ class OnlyNodeTransform(SphinxPostTransform): process_only_nodes(self.document, self.app.builder.tags) -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: Sphinx) -> Dict[str, Any]: app.add_post_transform(ReferencesResolver) app.add_post_transform(OnlyNodeTransform) diff --git a/sphinx/transforms/post_transforms/code.py b/sphinx/transforms/post_transforms/code.py index bae1216bd..0707b85a8 100644 --- a/sphinx/transforms/post_transforms/code.py +++ b/sphinx/transforms/post_transforms/code.py @@ -9,20 +9,17 @@ """ import sys -from typing import NamedTuple, Union +from typing import Any, Dict, List, NamedTuple, Union from docutils import nodes +from docutils.nodes import Node from pygments.lexers import PythonConsoleLexer, guess_lexer from sphinx import addnodes +from sphinx.application import Sphinx from sphinx.ext import doctest from sphinx.transforms import SphinxTransform -if False: - # For type annotation - from typing import Any, Dict, List # NOQA - from sphinx.application import Sphinx # NOQA - HighlightSetting = NamedTuple('HighlightSetting', [('language', str), ('force', bool), @@ -39,8 +36,7 @@ class HighlightLanguageTransform(SphinxTransform): """ default_priority = 400 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: visitor = HighlightLanguageVisitor(self.document, self.config.highlight_language) self.document.walkabout(visitor) @@ -50,44 +46,35 @@ class HighlightLanguageTransform(SphinxTransform): class HighlightLanguageVisitor(nodes.NodeVisitor): - def __init__(self, document, default_language): - # type: (nodes.document, str) -> None + def __init__(self, document: nodes.document, default_language: str) -> None: self.default_setting = HighlightSetting(default_language, False, sys.maxsize) self.settings = [] # type: List[HighlightSetting] super().__init__(document) - def unknown_visit(self, node): - # type: (nodes.Node) -> None + def unknown_visit(self, node: Node) -> None: pass - def unknown_departure(self, node): - # type: (nodes.Node) -> None + def unknown_departure(self, node: Node) -> None: pass - def visit_document(self, node): - # type: (nodes.Node) -> None + def visit_document(self, node: Node) -> None: self.settings.append(self.default_setting) - def depart_document(self, node): - # type: (nodes.Node) -> None + def depart_document(self, node: Node) -> None: self.settings.pop() - def visit_start_of_file(self, node): - # type: (nodes.Node) -> None + def visit_start_of_file(self, node: Node) -> None: self.settings.append(self.default_setting) - def depart_start_of_file(self, node): - # type: (nodes.Node) -> None + def depart_start_of_file(self, node: Node) -> None: self.settings.pop() - def visit_highlightlang(self, node): - # type: (addnodes.highlightlang) -> None + def visit_highlightlang(self, node: addnodes.highlightlang) -> None: self.settings[-1] = HighlightSetting(node['lang'], node['force'], node['linenothreshold']) - def visit_literal_block(self, node): - # type: (nodes.literal_block) -> None + def visit_literal_block(self, node: nodes.literal_block) -> None: setting = self.settings[-1] if 'language' not in node: node['language'] = setting.language @@ -105,8 +92,7 @@ class TrimDoctestFlagsTransform(SphinxTransform): """ default_priority = HighlightLanguageTransform.default_priority + 1 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: if not self.config.trim_doctest_flags: return @@ -118,8 +104,7 @@ class TrimDoctestFlagsTransform(SphinxTransform): self.strip_doctest_flags(dbnode) @staticmethod - def strip_doctest_flags(node): - # type: (Union[nodes.literal_block, nodes.doctest_block]) -> None + def strip_doctest_flags(node: Union[nodes.literal_block, nodes.doctest_block]) -> None: source = node.rawsource source = doctest.blankline_re.sub('', source) source = doctest.doctestopt_re.sub('', source) @@ -127,8 +112,7 @@ class TrimDoctestFlagsTransform(SphinxTransform): node[:] = [nodes.Text(source)] @staticmethod - def is_pyconsole(node): - # type: (nodes.literal_block) -> bool + def is_pyconsole(node: nodes.literal_block) -> bool: if node.rawsource != node.astext(): return False # skip parsed-literal node @@ -147,8 +131,7 @@ class TrimDoctestFlagsTransform(SphinxTransform): return False -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: Sphinx) -> Dict[str, Any]: app.add_post_transform(HighlightLanguageTransform) app.add_post_transform(TrimDoctestFlagsTransform) diff --git a/sphinx/transforms/post_transforms/compat.py b/sphinx/transforms/post_transforms/compat.py index 67b67f8d4..4520cf4fc 100644 --- a/sphinx/transforms/post_transforms/compat.py +++ b/sphinx/transforms/post_transforms/compat.py @@ -9,19 +9,17 @@ """ import warnings +from typing import Any, Dict from docutils import nodes from docutils.writers.docutils_xml import XMLTranslator from sphinx.addnodes import math_block, displaymath +from sphinx.application import Sphinx from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.transforms import SphinxTransform from sphinx.util import logging -if False: - # For type annotation - from typing import Any, Dict # NOQA - from sphinx.application import Sphinx # NOQA logger = logging.getLogger(__name__) @@ -35,8 +33,7 @@ class MathNodeMigrator(SphinxTransform): """ default_priority = 999 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for math_node in self.document.traverse(nodes.math): # case: old styled ``math`` node generated by old extensions if len(math_node) == 0: @@ -79,8 +76,7 @@ class MathNodeMigrator(SphinxTransform): math_block_node += nodes.Text(latex, latex) -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: Sphinx) -> Dict[str, Any]: app.add_post_transform(MathNodeMigrator) return { diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py index 68c0621b0..a8af5dd55 100644 --- a/sphinx/transforms/post_transforms/images.py +++ b/sphinx/transforms/post_transforms/images.py @@ -11,9 +11,11 @@ import os from hashlib import sha1 from math import ceil +from typing import Any, Dict, List, Tuple from docutils import nodes +from sphinx.application import Sphinx from sphinx.locale import __ from sphinx.transforms import SphinxTransform from sphinx.util import epoch_to_rfc1123, rfc1123_to_epoch @@ -21,11 +23,6 @@ from sphinx.util import logging, requests from sphinx.util.images import guess_mimetype, get_image_extension, parse_data_uri from sphinx.util.osutil import ensuredir, movefile -if False: - # For type annotation - from typing import Any, Dict, List, Tuple # NOQA - from sphinx.application import Sphinx # NOQA - logger = logging.getLogger(__name__) @@ -33,31 +30,26 @@ MAX_FILENAME_LEN = 32 class BaseImageConverter(SphinxTransform): - def apply(self, **kwargsj): - # type: (Any) -> None + def apply(self, **kwargs: Any) -> None: for node in self.document.traverse(nodes.image): if self.match(node): self.handle(node) - def match(self, node): - # type: (nodes.image) -> bool + def match(self, node: nodes.image) -> bool: return True - def handle(self, node): - # type: (nodes.image) -> None + def handle(self, node: nodes.image) -> None: pass @property - def imagedir(self): - # type: () -> str + def imagedir(self) -> str: return os.path.join(self.app.doctreedir, 'images') class ImageDownloader(BaseImageConverter): default_priority = 100 - def match(self, node): - # type: (nodes.image) -> bool + def match(self, node: nodes.image) -> bool: if self.app.builder.supported_image_types == []: return False elif self.app.builder.supported_remote_images: @@ -65,8 +57,7 @@ class ImageDownloader(BaseImageConverter): else: return '://' in node['uri'] - def handle(self, node): - # type: (nodes.image) -> None + def handle(self, node: nodes.image) -> None: try: basename = os.path.basename(node['uri']) if '?' in basename: @@ -123,8 +114,7 @@ class ImageDownloader(BaseImageConverter): class DataURIExtractor(BaseImageConverter): default_priority = 150 - def match(self, node): - # type: (nodes.image) -> bool + def match(self, node: nodes.image) -> bool: if self.app.builder.supported_remote_images == []: return False elif self.app.builder.supported_data_uri_images is True: @@ -132,8 +122,7 @@ class DataURIExtractor(BaseImageConverter): else: return 'data:' in node['uri'] - def handle(self, node): - # type: (nodes.image) -> None + def handle(self, node: nodes.image) -> None: image = parse_data_uri(node['uri']) ext = get_image_extension(image.mimetype) if ext is None: @@ -155,8 +144,7 @@ class DataURIExtractor(BaseImageConverter): self.app.env.images.add_file(self.env.docname, path) -def get_filename_for(filename, mimetype): - # type: (str, str) -> str +def get_filename_for(filename: str, mimetype: str) -> str: basename = os.path.basename(filename) return os.path.splitext(basename)[0] + get_image_extension(mimetype) @@ -195,15 +183,13 @@ class ImageConverter(BaseImageConverter): #: ] conversion_rules = [] # type: List[Tuple[str, str]] - def __init__(self, *args, **kwargs): - # type: (Any, Any) -> None + def __init__(self, *args, **kwargs) -> None: self.available = None # type: bool # the converter is available or not. # Will be checked at first conversion super().__init__(*args, **kwargs) - def match(self, node): - # type: (nodes.image) -> bool + def match(self, node: nodes.image) -> bool: if self.available is None: self.available = self.is_available() @@ -219,8 +205,7 @@ class ImageConverter(BaseImageConverter): else: return False - def get_conversion_rule(self, node): - # type: (nodes.image) -> Tuple[str, str] + def get_conversion_rule(self, node: nodes.image) -> Tuple[str, str]: for candidate in self.guess_mimetypes(node): for supported in self.app.builder.supported_image_types: rule = (candidate, supported) @@ -229,13 +214,11 @@ class ImageConverter(BaseImageConverter): return None - def is_available(self): - # type: () -> bool + def is_available(self) -> bool: """Return the image converter is available or not.""" raise NotImplementedError() - def guess_mimetypes(self, node): - # type: (nodes.image) -> List[str] + def guess_mimetypes(self, node: nodes.image) -> List[str]: if '?' in node['candidates']: return [] elif '*' in node['candidates']: @@ -244,8 +227,7 @@ class ImageConverter(BaseImageConverter): else: return node['candidates'].keys() - def handle(self, node): - # type: (nodes.image) -> None + def handle(self, node: nodes.image) -> None: _from, _to = self.get_conversion_rule(node) if _from in node['candidates']: @@ -268,8 +250,7 @@ class ImageConverter(BaseImageConverter): self.env.original_image_uri[destpath] = srcpath self.env.images.add_file(self.env.docname, destpath) - def convert(self, _from, _to): - # type: (str, str) -> bool + def convert(self, _from: str, _to: str) -> bool: """Convert a image file to expected format. *_from* is a path for source image file, and *_to* is a path for @@ -278,8 +259,7 @@ class ImageConverter(BaseImageConverter): raise NotImplementedError() -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: Sphinx) -> Dict[str, Any]: app.add_post_transform(ImageDownloader) app.add_post_transform(DataURIExtractor) diff --git a/sphinx/transforms/references.py b/sphinx/transforms/references.py index 9cdc28c78..79b439f4b 100644 --- a/sphinx/transforms/references.py +++ b/sphinx/transforms/references.py @@ -8,6 +8,8 @@ :license: BSD, see LICENSE for details. """ +from typing import Any, Dict + from docutils import nodes from docutils.transforms.references import DanglingReferences, Substitutions @@ -15,8 +17,7 @@ from sphinx.transforms import SphinxTransform if False: # For type annotation - from typing import Any, Dict # NOQA - from sphinx.application import Sphinx # NOQA + from sphinx.application import Sphinx class SubstitutionDefinitionsRemover(SphinxTransform): @@ -25,8 +26,7 @@ class SubstitutionDefinitionsRemover(SphinxTransform): # should be invoked after Substitutions process default_priority = Substitutions.default_priority + 1 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for node in self.document.traverse(nodes.substitution_definition): node.parent.remove(node) @@ -34,8 +34,7 @@ class SubstitutionDefinitionsRemover(SphinxTransform): class SphinxDanglingReferences(DanglingReferences): """DanglingReferences transform which does not output info messages.""" - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: try: reporter = self.document.reporter report_level = reporter.report_level @@ -51,14 +50,12 @@ class SphinxDomains(SphinxTransform): """Collect objects to Sphinx domains for cross references.""" default_priority = 850 - def apply(self, **kwargs): - # type: (Any) -> None + def apply(self, **kwargs) -> None: for domain in self.env.domains.values(): domain.process_doc(self.env, self.env.docname, self.document) -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: "Sphinx") -> Dict[str, Any]: app.add_transform(SubstitutionDefinitionsRemover) app.add_transform(SphinxDanglingReferences) app.add_transform(SphinxDomains)