diff options
author | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2019-07-03 02:01:42 +0900 |
---|---|---|
committer | Takeshi KOMIYA <i.tkomiya@gmail.com> | 2019-07-04 11:49:09 +0900 |
commit | dcff6d7cbceea55f681284c327b24169f4285ae2 (patch) | |
tree | 972b4aa06e67ae713c9ebaf3bf955d24857dd7b5 /sphinx/ext/doctest.py | |
parent | f82d6c429b6379663b71cba783e780535d73343b (diff) | |
download | sphinx-git-dcff6d7cbceea55f681284c327b24169f4285ae2.tar.gz |
Migrate to py3 style type annotation: sphinx.ext.doctest
Diffstat (limited to 'sphinx/ext/doctest.py')
-rw-r--r-- | sphinx/ext/doctest.py | 99 |
1 files changed, 38 insertions, 61 deletions
diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 01ab38efe..68df253d5 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -16,8 +16,10 @@ import time import warnings from io import StringIO from os import path +from typing import Any, Callable, Dict, Iterable, List, Sequence, Set, Tuple, Type from docutils import nodes +from docutils.nodes import Element, Node, TextElement from docutils.parsers.rst import directives from packaging.specifiers import SpecifierSet, InvalidSpecifier from packaging.version import Version @@ -33,8 +35,8 @@ from sphinx.util.osutil import relpath if False: # For type annotation - from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Set, Tuple, Type # NOQA - from sphinx.application import Sphinx # NOQA + from sphinx.application import Sphinx + logger = logging.getLogger(__name__) @@ -42,15 +44,13 @@ blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE) doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE) -def doctest_encode(text, encoding): - # type: (str, str) -> str +def doctest_encode(text: str, encoding: str) -> str: warnings.warn('doctest_encode() is deprecated.', RemovedInSphinx40Warning) return text -def is_allowed_version(spec, version): - # type: (str, str) -> bool +def is_allowed_version(spec: str, version: str) -> bool: """Check `spec` satisfies `version` or not. This obeys PEP-440 specifiers: @@ -80,8 +80,7 @@ class TestDirective(SphinxDirective): optional_arguments = 1 final_argument_whitespace = True - def run(self): - # type: () -> List[nodes.Node] + def run(self) -> List[Node]: # use ordinary docutils nodes for test code: they get special attributes # so that our builder recognizes them, and the other builders are happy. code = '\n'.join(self.content) @@ -95,7 +94,7 @@ class TestDirective(SphinxDirective): if not test: test = code code = doctestopt_re.sub('', code) - nodetype = nodes.literal_block # type: Type[nodes.TextElement] + nodetype = nodes.literal_block # type: Type[TextElement] if self.name in ('testsetup', 'testcleanup') or 'hide' in self.options: nodetype = nodes.comment if self.arguments: @@ -194,15 +193,13 @@ parser = doctest.DocTestParser() # helper classes class TestGroup: - def __init__(self, name): - # type: (str) -> None + def __init__(self, name: str) -> None: self.name = name self.setup = [] # type: List[TestCode] self.tests = [] # type: List[List[TestCode]] self.cleanup = [] # type: List[TestCode] - def add_code(self, code, prepend=False): - # type: (TestCode, bool) -> None + def add_code(self, code: "TestCode", prepend: bool = False) -> None: if code.type == 'testsetup': if prepend: self.setup.insert(0, code) @@ -220,30 +217,28 @@ class TestGroup: else: raise RuntimeError(__('invalid TestCode type')) - def __repr__(self): - # type: () -> str + def __repr__(self) -> str: return 'TestGroup(name=%r, setup=%r, cleanup=%r, tests=%r)' % ( self.name, self.setup, self.cleanup, self.tests) class TestCode: - def __init__(self, code, type, filename, lineno, options=None): - # type: (str, str, Optional[str], int, Optional[Dict]) -> None + def __init__(self, code: str, type: str, filename: str, + lineno: int, options: Dict = None) -> None: self.code = code self.type = type self.filename = filename self.lineno = lineno self.options = options or {} - def __repr__(self): - # type: () -> str + def __repr__(self) -> str: return 'TestCode(%r, %r, filename=%r, lineno=%r, options=%r)' % ( self.code, self.type, self.filename, self.lineno, self.options) class SphinxDocTestRunner(doctest.DocTestRunner): - def summarize(self, out, verbose=None): # type: ignore - # type: (Callable, bool) -> Tuple[int, int] + def summarize(self, out: Callable, verbose: bool = None # type: ignore + ) -> Tuple[int, int]: string_io = StringIO() old_stdout = sys.stdout sys.stdout = string_io @@ -254,9 +249,8 @@ class SphinxDocTestRunner(doctest.DocTestRunner): out(string_io.getvalue()) return res - def _DocTestRunner__patched_linecache_getlines(self, filename, - module_globals=None): - # type: (str, Any) -> Any + def _DocTestRunner__patched_linecache_getlines(self, filename: str, + module_globals: Any = None) -> Any: # this is overridden from DocTestRunner adding the try-except below m = self._DocTestRunner__LINECACHE_FILENAME_RE.match(filename) # type: ignore if m and m.group('name') == self.test.name: @@ -282,8 +276,7 @@ class DocTestBuilder(Builder): epilog = __('Testing of doctests in the sources finished, look at the ' 'results in %(outdir)s/output.txt.') - def init(self): - # type: () -> None + def init(self) -> None: # default options self.opt = self.config.doctest_default_flags @@ -312,32 +305,26 @@ class DocTestBuilder(Builder): '==================================%s\n') % (date, '=' * len(date))) - def _out(self, text): - # type: (str) -> None + def _out(self, text: str) -> None: logger.info(text, nonl=True) self.outfile.write(text) - def _warn_out(self, text): - # type: (str) -> None + def _warn_out(self, text: str) -> None: if self.app.quiet or self.app.warningiserror: logger.warning(text) else: logger.info(text, nonl=True) self.outfile.write(text) - def get_target_uri(self, docname, typ=None): - # type: (str, str) -> str + def get_target_uri(self, docname: str, typ: str = None) -> str: return '' - def get_outdated_docs(self): - # type: () -> Set[str] + def get_outdated_docs(self) -> Set[str]: return self.env.found_docs - def finish(self): - # type: () -> None + def finish(self) -> None: # write executive summary - def s(v): - # type: (int) -> str + def s(v: int) -> str: return v != 1 and 's' or '' repl = (self.total_tries, s(self.total_tries), self.total_failures, s(self.total_failures), @@ -356,8 +343,8 @@ Doctest summary if self.total_failures or self.setup_failures or self.cleanup_failures: self.app.statuscode = 1 - def write(self, build_docnames, updated_docnames, method='update'): - # type: (Iterable[str], Sequence[str], str) -> None + def write(self, build_docnames: Iterable[str], updated_docnames: Sequence[str], + method: str = 'update') -> None: if build_docnames is None: build_docnames = sorted(self.env.all_docs) @@ -367,8 +354,7 @@ Doctest summary doctree = self.env.get_doctree(docname) self.test_doc(docname, doctree) - def get_filename_for_node(self, node, docname): - # type: (nodes.Node, str) -> str + def get_filename_for_node(self, node: Node, docname: str) -> str: """Try to get the file which actually contains the doctest, not the filename of the document it's included in.""" try: @@ -379,8 +365,7 @@ Doctest summary return filename @staticmethod - def get_line_number(node): - # type: (nodes.Node) -> Optional[int] + def get_line_number(node: Node) -> int: """Get the real line number or admit we don't know.""" # TODO: Work out how to store or calculate real (file-relative) # line numbers for doctest blocks in docstrings. @@ -395,8 +380,7 @@ Doctest summary return node.line - 1 return None - def skipped(self, node): - # type: (nodes.Element) -> bool + def skipped(self, node: Element) -> bool: if 'skipif' not in node: return False else: @@ -409,8 +393,7 @@ Doctest summary exec(self.config.doctest_global_cleanup, context) return should_skip - def test_doc(self, docname, doctree): - # type: (str, nodes.Node) -> None + def test_doc(self, docname: str, doctree: Node) -> None: groups = {} # type: Dict[str, TestGroup] add_to_all_groups = [] self.setup_runner = SphinxDocTestRunner(verbose=False, @@ -424,17 +407,15 @@ Doctest summary self.cleanup_runner._fakeout = self.setup_runner._fakeout # type: ignore if self.config.doctest_test_doctest_blocks: - def condition(node): - # type: (nodes.Node) -> bool + def condition(node: Node) -> bool: return (isinstance(node, (nodes.literal_block, nodes.comment)) and 'testnodetype' in node) or \ isinstance(node, nodes.doctest_block) else: - def condition(node): - # type: (nodes.Node) -> bool + def condition(node: Node) -> bool: return isinstance(node, (nodes.literal_block, nodes.comment)) \ and 'testnodetype' in node - for node in doctree.traverse(condition): # type: nodes.Element + for node in doctree.traverse(condition): # type: Element if self.skipped(node): continue @@ -490,16 +471,13 @@ Doctest summary self.cleanup_failures += res_f self.cleanup_tries += res_t - def compile(self, code, name, type, flags, dont_inherit): - # type: (str, str, str, Any, bool) -> Any + def compile(self, code: str, name: str, type: str, flags: Any, dont_inherit: bool) -> Any: return compile(code, name, self.type, flags, dont_inherit) - def test_group(self, group): - # type: (TestGroup) -> None + def test_group(self, group: TestGroup) -> None: ns = {} # type: Dict - def run_setup_cleanup(runner, testcodes, what): - # type: (Any, List[TestCode], Any) -> bool + def run_setup_cleanup(runner: Any, testcodes: List[TestCode], what: Any) -> bool: examples = [] for testcode in testcodes: example = doctest.Example(testcode.code, '', lineno=testcode.lineno) @@ -568,8 +546,7 @@ Doctest summary run_setup_cleanup(self.cleanup_runner, group.cleanup, 'cleanup') -def setup(app): - # type: (Sphinx) -> Dict[str, Any] +def setup(app: "Sphinx") -> Dict[str, Any]: app.add_directive('testsetup', TestsetupDirective) app.add_directive('testcleanup', TestcleanupDirective) app.add_directive('doctest', DoctestDirective) |