Merge pull request #7200 from tk0miya/refactor_type_annotation_testing

refactor: Update type annotations in sphinx.testing.*
This commit is contained in:
Takeshi KOMIYA 2020-02-23 15:39:25 +09:00 committed by GitHub
commit 06d3aa6c3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 46 deletions

View File

@ -9,7 +9,7 @@
"""
import difflib
import pathlib
from typing import List, Union
from typing import Any, List, Union
class PathComparer:
@ -38,13 +38,13 @@ class PathComparer:
"""
self.path = pathlib.Path(path)
def __str__(self):
def __str__(self) -> str:
return self.path.as_posix()
def __repr__(self):
def __repr__(self) -> str:
return "<{0.__class__.__name__}: '{0}'>".format(self)
def __eq__(self, other):
def __eq__(self, other: Union[str, pathlib.Path]) -> bool: # type: ignore
return not bool(self.ldiff(other))
def diff(self, other: Union[str, pathlib.Path]) -> List[str]:
@ -94,8 +94,10 @@ class PathComparer:
return [line.strip() for line in difflib.Differ().compare([s_path], [o_path])]
def pytest_assertrepr_compare(op, left, right):
def pytest_assertrepr_compare(op: str, left: Any, right: Any) -> List[str]:
if isinstance(left, PathComparer) and op == "==":
return ['Comparing path:'] + left.ldiff(right)
if isinstance(right, PathComparer) and op == "==":
elif isinstance(right, PathComparer) and op == "==":
return ['Comparing path:'] + right.rdiff(left)
else:
raise RuntimeError

View File

@ -14,20 +14,44 @@ import sys
from collections import namedtuple
from io import StringIO
from subprocess import PIPE
from typing import Any, Dict
from typing import Any, Callable, Dict, Generator, Tuple
import pytest
from . import util
from sphinx.testing import util
from sphinx.testing.util import SphinxTestApp, SphinxTestAppWrapperForSkipBuilding
@pytest.fixture(scope='session')
def rootdir() -> None:
def rootdir() -> str:
return None
class SharedResult:
cache = {} # type: Dict[str, Dict[str, str]]
def store(self, key: str, app_: SphinxTestApp) -> Any:
if key in self.cache:
return
data = {
'status': app_._status.getvalue(),
'warning': app_._warning.getvalue(),
}
self.cache[key] = data
def restore(self, key: str) -> Dict[str, StringIO]:
if key not in self.cache:
return {}
data = self.cache[key]
return {
'status': StringIO(data['status']),
'warning': StringIO(data['warning']),
}
@pytest.fixture
def app_params(request, test_params, shared_result, sphinx_test_tempdir, rootdir):
def app_params(request: Any, test_params: Dict, shared_result: SharedResult,
sphinx_test_tempdir: str, rootdir: str) -> Tuple[Dict, Dict]:
"""
parameters that is specified by 'pytest.mark.sphinx' for
sphinx.application.Sphinx initialization
@ -40,7 +64,7 @@ def app_params(request, test_params, shared_result, sphinx_test_tempdir, rootdir
else:
markers = request.node.get_marker("sphinx")
pargs = {}
kwargs = {} # type: Dict[str, str]
kwargs = {} # type: Dict[str, Any]
if markers is not None:
# to avoid stacking positional args
@ -75,7 +99,7 @@ def app_params(request, test_params, shared_result, sphinx_test_tempdir, rootdir
@pytest.fixture
def test_params(request):
def test_params(request: Any) -> Dict:
"""
test parameters that is specified by 'pytest.mark.test_params'
@ -102,7 +126,8 @@ def test_params(request):
@pytest.fixture(scope='function')
def app(test_params, app_params, make_app, shared_result):
def app(test_params: Dict, app_params: Tuple[Dict, Dict], make_app: Callable,
shared_result: SharedResult) -> Generator[SphinxTestApp, None, None]:
"""
provides sphinx.application.Sphinx object
"""
@ -122,7 +147,7 @@ def app(test_params, app_params, make_app, shared_result):
@pytest.fixture(scope='function')
def status(app):
def status(app: SphinxTestApp) -> StringIO:
"""
compat for testing with previous @with_app decorator
"""
@ -130,7 +155,7 @@ def status(app):
@pytest.fixture(scope='function')
def warning(app):
def warning(app: SphinxTestApp) -> StringIO:
"""
compat for testing with previous @with_app decorator
"""
@ -138,7 +163,7 @@ def warning(app):
@pytest.fixture()
def make_app(test_params, monkeypatch):
def make_app(test_params: Dict, monkeypatch: Any) -> Generator[Callable, None, None]:
"""
provides make_app function to initialize SphinxTestApp instance.
if you want to initialize 'app' in your test function. please use this
@ -153,10 +178,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: Any
app_ = SphinxTestApp(*args, **kwargs) # type: Any
apps.append(app_)
if test_params['shared_result']:
app_ = util.SphinxTestAppWrapperForSkipBuilding(app_)
app_ = SphinxTestAppWrapperForSkipBuilding(app_)
return app_
yield make
@ -165,40 +190,18 @@ def make_app(test_params, monkeypatch):
app_.cleanup()
class SharedResult:
cache = {} # type: Dict[str, Dict[str, str]]
def store(self, key, app_):
if key in self.cache:
return
data = {
'status': app_._status.getvalue(),
'warning': app_._warning.getvalue(),
}
self.cache[key] = data
def restore(self, key):
if key not in self.cache:
return {}
data = self.cache[key]
return {
'status': StringIO(data['status']),
'warning': StringIO(data['warning']),
}
@pytest.fixture
def shared_result():
def shared_result() -> SharedResult:
return SharedResult()
@pytest.fixture(scope='module', autouse=True)
def _shared_result_cache():
def _shared_result_cache() -> None:
SharedResult.cache.clear()
@pytest.fixture
def if_graphviz_found(app):
def if_graphviz_found(app: SphinxTestApp) -> None:
"""
The test will be skipped when using 'if_graphviz_found' fixture and graphviz
dot command is not found.
@ -215,7 +218,7 @@ def if_graphviz_found(app):
@pytest.fixture(scope='session')
def sphinx_test_tempdir(tmpdir_factory):
def sphinx_test_tempdir(tmpdir_factory: Any) -> "util.path":
"""
temporary directory that wrapped with `path` class.
"""
@ -227,7 +230,7 @@ def sphinx_test_tempdir(tmpdir_factory):
@pytest.fixture
def tempdir(tmpdir):
def tempdir(tmpdir: str) -> "util.path":
"""
temporary directory that wrapped with `path` class.
this fixture is for compat with old test implementation.

View File

@ -11,10 +11,12 @@ import os
import re
import sys
import warnings
from io import StringIO
from typing import Any, Dict, Generator, IO, List, Pattern
from xml.etree import ElementTree
from docutils import nodes
from docutils.nodes import Node
from docutils.parsers.rst import directives, roles
from sphinx import application, locale
@ -47,7 +49,7 @@ def assert_startswith(thing: str, prefix: str) -> None:
assert False, '%r does not start with %r' % (thing, prefix)
def assert_node(node: nodes.Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> None:
def assert_node(node: Node, cls: Any = None, xpath: str = "", **kwargs: Any) -> None:
if cls:
if isinstance(cls, list):
assert_node(node, cls[0], xpath=xpath, **kwargs)
@ -101,6 +103,8 @@ class SphinxTestApp(application.Sphinx):
A subclass of :class:`Sphinx` that runs on the test root, with some
better default values for the initialization parameters.
"""
_status = None # type: StringIO
_warning = None # type: StringIO
def __init__(self, buildername: str = 'html', srcdir: path = None, freshenv: bool = False,
confoverrides: Dict = None, status: IO = None, warning: IO = None,