From 32fa96d46d7383c83128f516d684bfaa8a54f821 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 3 Jul 2019 23:48:01 +0900 Subject: [PATCH 1/4] Migrate to py3 style type annotation: sphinx.testing.util --- sphinx/testing/util.py | 54 ++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/sphinx/testing/util.py b/sphinx/testing/util.py index 7b73059e9..1ba3237c4 100644 --- a/sphinx/testing/util.py +++ b/sphinx/testing/util.py @@ -11,6 +11,7 @@ import os import re import sys import warnings +from typing import Any, Dict, Generator, IO, List, Pattern from xml.etree import ElementTree from docutils import nodes @@ -23,10 +24,6 @@ from sphinx.pycode import ModuleAnalyzer from sphinx.testing.path import path from sphinx.util.osutil import relpath -if False: - # For type annotation - from typing import Any, Dict, Generator, IO, List, Pattern # NOQA - __all__ = [ 'Struct', @@ -35,26 +32,22 @@ __all__ = [ ] -def assert_re_search(regex, text, flags=0): - # type: (Pattern, str, int) -> None +def assert_re_search(regex: Pattern, text: str, flags: int = 0) -> None: if not re.search(regex, text, flags): assert False, '%r did not match %r' % (regex, text) -def assert_not_re_search(regex, text, flags=0): - # type: (Pattern, str, int) -> None +def assert_not_re_search(regex: Pattern, text: str, flags: int = 0) -> None: if re.search(regex, text, flags): assert False, '%r did match %r' % (regex, text) -def assert_startswith(thing, prefix): - # type: (str, str) -> None +def assert_startswith(thing: str, prefix: str) -> None: if not thing.startswith(prefix): assert False, '%r does not start with %r' % (thing, prefix) -def assert_node(node, cls=None, xpath="", **kwargs): - # type: (nodes.Node, Any, str, Any) -> None +def assert_node(node: nodes.Node, cls: Any = None, xpath: str = "", **kwargs) -> None: if cls: if isinstance(cls, list): assert_node(node, cls[0], xpath=xpath, **kwargs) @@ -92,16 +85,14 @@ def assert_node(node, cls=None, xpath="", **kwargs): 'The node%s[%s] is not %r: %r' % (xpath, key, value, node[key]) -def etree_parse(path): - # type: (str) -> Any +def etree_parse(path: str) -> Any: with warnings.catch_warnings(record=False): warnings.filterwarnings("ignore", category=DeprecationWarning) return ElementTree.parse(path) class Struct: - def __init__(self, **kwds): - # type: (Any) -> None + def __init__(self, **kwds) -> None: self.__dict__.update(kwds) @@ -111,10 +102,9 @@ class SphinxTestApp(application.Sphinx): better default values for the initialization parameters. """ - def __init__(self, buildername='html', srcdir=None, - freshenv=False, confoverrides=None, status=None, warning=None, - tags=None, docutilsconf=None): - # type: (str, path, bool, Dict, IO, IO, List[str], str) -> None + def __init__(self, buildername: str = 'html', srcdir: path = None, freshenv: bool = False, + confoverrides: Dict = None, status: IO = None, warning: IO = None, + tags: List[str] = None, docutilsconf: str = None) -> None: if docutilsconf is not None: (srcdir / 'docutils.conf').write_text(docutilsconf) @@ -144,8 +134,7 @@ class SphinxTestApp(application.Sphinx): self.cleanup() raise - def cleanup(self, doctrees=False): - # type: (bool) -> None + def cleanup(self, doctrees: bool = False) -> None: ModuleAnalyzer.cache.clear() LaTeXBuilder.usepackages = [] locale.translators.clear() @@ -159,8 +148,7 @@ class SphinxTestApp(application.Sphinx): delattr(nodes.GenericNodeVisitor, 'visit_' + method[6:]) delattr(nodes.GenericNodeVisitor, 'depart_' + method[6:]) - def __repr__(self): - # type: () -> str + def __repr__(self) -> str: return '<%s buildername=%r>' % (self.__class__.__name__, self.builder.name) @@ -171,16 +159,13 @@ class SphinxTestAppWrapperForSkipBuilding: file. """ - def __init__(self, app_): - # type: (SphinxTestApp) -> None + def __init__(self, app_: SphinxTestApp) -> None: self.app = app_ - def __getattr__(self, name): - # type: (str) -> Any + def __getattr__(self, name: str) -> Any: return getattr(self.app, name) - def build(self, *args, **kw): - # type: (Any, Any) -> None + def build(self, *args, **kw) -> None: if not self.app.outdir.listdir(): # type: ignore # if listdir is empty, do build. self.app.build(*args, **kw) @@ -190,15 +175,13 @@ class SphinxTestAppWrapperForSkipBuilding: _unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')') -def remove_unicode_literals(s): - # type: (str) -> str +def remove_unicode_literals(s: str) -> str: warnings.warn('remove_unicode_literals() is deprecated.', RemovedInSphinx40Warning, stacklevel=2) return _unicode_literals_re.sub(lambda x: x.group(1) or x.group(2), s) -def find_files(root, suffix=None): - # type: (str, bool) -> Generator +def find_files(root: str, suffix: bool = None) -> Generator[str, None, None]: for dirpath, dirs, files in os.walk(root, followlinks=True): dirpath = path(dirpath) for f in [f for f in files if not suffix or f.endswith(suffix)]: # type: ignore @@ -206,6 +189,5 @@ def find_files(root, suffix=None): yield relpath(fpath, root) -def strip_escseq(text): - # type: (str) -> str +def strip_escseq(text: str) -> str: return re.sub('\x1b.*?m', '', text) From 05f75b7c9427c0354f63639178676da0d67f938f Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 4 Jul 2019 01:31:40 +0900 Subject: [PATCH 2/4] Migrate to py3 style type annotation: sphinx.testing.path --- sphinx/testing/path.py | 83 ++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 55 deletions(-) diff --git a/sphinx/testing/path.py b/sphinx/testing/path.py index f71bf509b..d2fc4f31e 100644 --- a/sphinx/testing/path.py +++ b/sphinx/testing/path.py @@ -5,14 +5,12 @@ :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ + +import builtins import os import shutil import sys - -if False: - # For type annotation - import builtins # NOQA - from typing import Any, Callable, IO, List # NOQA +from typing import Any, Callable, IO, List FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding() @@ -24,61 +22,52 @@ class path(str): """ @property - def parent(self): - # type: () -> path + def parent(self) -> "path": """ The name of the directory the file or directory is in. """ return self.__class__(os.path.dirname(self)) - def basename(self): - # type: () -> str + def basename(self) -> str: return os.path.basename(self) - def abspath(self): - # type: () -> path + def abspath(self) -> "path": """ Returns the absolute path. """ return self.__class__(os.path.abspath(self)) - def isabs(self): - # type: () -> bool + def isabs(self) -> bool: """ Returns ``True`` if the path is absolute. """ return os.path.isabs(self) - def isdir(self): - # type: () -> bool + def isdir(self) -> bool: """ Returns ``True`` if the path is a directory. """ return os.path.isdir(self) - def isfile(self): - # type: () -> bool + def isfile(self) -> bool: """ Returns ``True`` if the path is a file. """ return os.path.isfile(self) - def islink(self): - # type: () -> bool + def islink(self) -> bool: """ Returns ``True`` if the path is a symbolic link. """ return os.path.islink(self) - def ismount(self): - # type: () -> bool + def ismount(self) -> bool: """ Returns ``True`` if the path is a mount point. """ return os.path.ismount(self) - def rmtree(self, ignore_errors=False, onerror=None): - # type: (bool, Callable) -> None + def rmtree(self, ignore_errors: bool = False, onerror: Callable = None) -> None: """ Removes the file or directory and any files or directories it may contain. @@ -96,8 +85,7 @@ class path(str): """ shutil.rmtree(self, ignore_errors=ignore_errors, onerror=onerror) - def copytree(self, destination, symlinks=False): - # type: (str, bool) -> None + def copytree(self, destination: str, symlinks: bool = False) -> None: """ Recursively copy a directory to the given `destination`. If the given `destination` does not exist it will be created. @@ -109,8 +97,7 @@ class path(str): """ shutil.copytree(self, destination, symlinks=symlinks) - def movetree(self, destination): - # type: (str) -> None + def movetree(self, destination: str) -> None: """ Recursively move the file or directory to the given `destination` similar to the Unix "mv" command. @@ -122,54 +109,46 @@ class path(str): move = movetree - def unlink(self): - # type: () -> None + def unlink(self) -> None: """ Removes a file. """ os.unlink(self) - def stat(self): - # type: () -> Any + def stat(self) -> Any: """ Returns a stat of the file. """ return os.stat(self) - def utime(self, arg): - # type: (Any) -> None + def utime(self, arg: Any) -> None: os.utime(self, arg) - def open(self, mode='r', **kwargs): - # type: (str, Any) -> IO + def open(self, mode: str = 'r', **kwargs) -> IO: return open(self, mode, **kwargs) - def write_text(self, text, encoding='utf-8', **kwargs): - # type: (str, str, Any) -> None + def write_text(self, text: str, encoding: str = 'utf-8', **kwargs) -> None: """ Writes the given `text` to the file. """ with open(self, 'w', encoding=encoding, **kwargs) as f: f.write(text) - def text(self, encoding='utf-8', **kwargs): - # type: (str, Any) -> str + def text(self, encoding: str = 'utf-8', **kwargs) -> str: """ Returns the text in the file. """ with open(self, encoding=encoding, **kwargs) as f: return f.read() - def bytes(self): - # type: () -> builtins.bytes + def bytes(self) -> builtins.bytes: """ Returns the bytes in the file. """ with open(self, mode='rb') as f: return f.read() - def write_bytes(self, bytes, append=False): - # type: (str, bool) -> None + def write_bytes(self, bytes: str, append: bool = False) -> None: """ Writes the given `bytes` to the file. @@ -183,41 +162,35 @@ class path(str): with open(self, mode=mode) as f: f.write(bytes) - def exists(self): - # type: () -> bool + def exists(self) -> bool: """ Returns ``True`` if the path exist. """ return os.path.exists(self) - def lexists(self): - # type: () -> bool + def lexists(self) -> bool: """ Returns ``True`` if the path exists unless it is a broken symbolic link. """ return os.path.lexists(self) - def makedirs(self, mode=0o777, exist_ok=False): - # type: (int, bool) -> None + def makedirs(self, mode: int = 0o777, exist_ok: bool = False) -> None: """ Recursively create directories. """ os.makedirs(self, mode, exist_ok=exist_ok) - def joinpath(self, *args): - # type: (Any) -> path + def joinpath(self, *args) -> "path": """ Joins the path with the argument given and returns the result. """ return self.__class__(os.path.join(self, *map(self.__class__, args))) - def listdir(self): - # type: () -> List[str] + def listdir(self) -> List[str]: return os.listdir(self) __div__ = __truediv__ = joinpath - def __repr__(self): - # type: () -> str + def __repr__(self) -> str: return '%s(%s)' % (self.__class__.__name__, super().__repr__()) From 3f6565df6323534e69d797003d8cb20e99c2c255 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 4 Jul 2019 01:36:40 +0900 Subject: [PATCH 3/4] Migrate to py3 style type annotation: sphinx.testing.fixtures --- sphinx/testing/fixtures.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index 93195fc40..443a7dd5c 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -14,25 +14,20 @@ import sys from collections import namedtuple from io import StringIO from subprocess import PIPE +from typing import Any, Dict import pytest from . import util -if False: - # For type annotation - from typing import Any, Dict, Union # NOQA - @pytest.fixture(scope='session') -def rootdir(): - # type: () -> None +def rootdir() -> None: return None @pytest.fixture def app_params(request, test_params, shared_result, sphinx_test_tempdir, rootdir): - # type: (Any, Any, Any, Any, Any) -> None """ parameters that is specified by 'pytest.mark.sphinx' for sphinx.application.Sphinx initialization @@ -158,10 +153,10 @@ def make_app(test_params, monkeypatch): status, warning = StringIO(), StringIO() kwargs.setdefault('status', status) kwargs.setdefault('warning', warning) - app_ = util.SphinxTestApp(*args, **kwargs) # type: Union[util.SphinxTestApp, util.SphinxTestAppWrapperForSkipBuilding] # NOQA + app_ = util.SphinxTestApp(*args, **kwargs) # type: Any apps.append(app_) if test_params['shared_result']: - app_ = util.SphinxTestAppWrapperForSkipBuilding(app_) # type: ignore + app_ = util.SphinxTestAppWrapperForSkipBuilding(app_) return app_ yield make From 1c6a279fa81f27bcc469f988bcc20323e120e295 Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Thu, 4 Jul 2019 01:29:24 +0900 Subject: [PATCH 4/4] Migrate to py3 style type annotation: sphinx.testing.restructuredtext --- sphinx/testing/restructuredtext.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sphinx/testing/restructuredtext.py b/sphinx/testing/restructuredtext.py index 8bf1c041e..1da8d9a60 100644 --- a/sphinx/testing/restructuredtext.py +++ b/sphinx/testing/restructuredtext.py @@ -8,21 +8,16 @@ from os import path +from docutils import nodes from docutils.core import publish_doctree +from sphinx.application import Sphinx from sphinx.io import SphinxStandaloneReader from sphinx.parsers import RSTParser from sphinx.util.docutils import sphinx_domains -if False: - # For type annotation - from docutils import nodes # NOQA - from sphinx.application import Sphinx # NOQA - - -def parse(app, text, docname='index'): - # type: (Sphinx, str, str) -> nodes.document +def parse(app: Sphinx, text: str, docname: str = 'index') -> nodes.document: """Parse a string as reStructuredText with Sphinx application.""" try: app.env.temp_data['docname'] = docname