Fix check_untyped_defs errors in test_pytester

This commit is contained in:
Ran Benita 2019-12-03 14:25:28 +02:00
parent 0c247be769
commit 0b603156b9
1 changed files with 69 additions and 65 deletions

View File

@ -2,6 +2,7 @@ import os
import subprocess import subprocess
import sys import sys
import time import time
from typing import List
import py.path import py.path
@ -9,6 +10,7 @@ import _pytest.pytester as pytester
import pytest import pytest
from _pytest.config import PytestPluginManager from _pytest.config import PytestPluginManager
from _pytest.main import ExitCode from _pytest.main import ExitCode
from _pytest.outcomes import Failed
from _pytest.pytester import CwdSnapshot from _pytest.pytester import CwdSnapshot
from _pytest.pytester import HookRecorder from _pytest.pytester import HookRecorder
from _pytest.pytester import LineMatcher from _pytest.pytester import LineMatcher
@ -16,7 +18,7 @@ from _pytest.pytester import SysModulesSnapshot
from _pytest.pytester import SysPathsSnapshot from _pytest.pytester import SysPathsSnapshot
def test_make_hook_recorder(testdir): def test_make_hook_recorder(testdir) -> None:
item = testdir.getitem("def test_func(): pass") item = testdir.getitem("def test_func(): pass")
recorder = testdir.make_hook_recorder(item.config.pluginmanager) recorder = testdir.make_hook_recorder(item.config.pluginmanager)
assert not recorder.getfailures() assert not recorder.getfailures()
@ -36,23 +38,23 @@ def test_make_hook_recorder(testdir):
failures = recorder.getfailures() failures = recorder.getfailures()
assert failures == [rep] assert failures == [rep]
class rep: class rep2:
excinfo = None excinfo = None
passed = False passed = False
failed = False failed = False
skipped = True skipped = True
when = "call" when = "call"
rep.passed = False rep2.passed = False
rep.skipped = True rep2.skipped = True
recorder.hook.pytest_runtest_logreport(report=rep) recorder.hook.pytest_runtest_logreport(report=rep2)
modcol = testdir.getmodulecol("") modcol = testdir.getmodulecol("")
rep = modcol.config.hook.pytest_make_collect_report(collector=modcol) rep3 = modcol.config.hook.pytest_make_collect_report(collector=modcol)
rep.passed = False rep3.passed = False
rep.failed = True rep3.failed = True
rep.skipped = False rep3.skipped = False
recorder.hook.pytest_collectreport(report=rep) recorder.hook.pytest_collectreport(report=rep3)
passed, skipped, failed = recorder.listoutcomes() passed, skipped, failed = recorder.listoutcomes()
assert not passed and skipped and failed assert not passed and skipped and failed
@ -65,17 +67,17 @@ def test_make_hook_recorder(testdir):
recorder.unregister() recorder.unregister()
recorder.clear() recorder.clear()
recorder.hook.pytest_runtest_logreport(report=rep) recorder.hook.pytest_runtest_logreport(report=rep3)
pytest.raises(ValueError, recorder.getfailures) pytest.raises(ValueError, recorder.getfailures)
def test_parseconfig(testdir): def test_parseconfig(testdir) -> None:
config1 = testdir.parseconfig() config1 = testdir.parseconfig()
config2 = testdir.parseconfig() config2 = testdir.parseconfig()
assert config2 is not config1 assert config2 is not config1
def test_testdir_runs_with_plugin(testdir): def test_testdir_runs_with_plugin(testdir) -> None:
testdir.makepyfile( testdir.makepyfile(
""" """
pytest_plugins = "pytester" pytest_plugins = "pytester"
@ -87,7 +89,7 @@ def test_testdir_runs_with_plugin(testdir):
result.assert_outcomes(passed=1) result.assert_outcomes(passed=1)
def test_runresult_assertion_on_xfail(testdir): def test_runresult_assertion_on_xfail(testdir) -> None:
testdir.makepyfile( testdir.makepyfile(
""" """
import pytest import pytest
@ -104,7 +106,7 @@ def test_runresult_assertion_on_xfail(testdir):
assert result.ret == 0 assert result.ret == 0
def test_runresult_assertion_on_xpassed(testdir): def test_runresult_assertion_on_xpassed(testdir) -> None:
testdir.makepyfile( testdir.makepyfile(
""" """
import pytest import pytest
@ -121,7 +123,7 @@ def test_runresult_assertion_on_xpassed(testdir):
assert result.ret == 0 assert result.ret == 0
def test_xpassed_with_strict_is_considered_a_failure(testdir): def test_xpassed_with_strict_is_considered_a_failure(testdir) -> None:
testdir.makepyfile( testdir.makepyfile(
""" """
import pytest import pytest
@ -154,13 +156,13 @@ def make_holder():
def pytest_xyz_noarg(): def pytest_xyz_noarg():
"x" "x"
apimod.pytest_xyz = pytest_xyz apimod.pytest_xyz = pytest_xyz # type: ignore
apimod.pytest_xyz_noarg = pytest_xyz_noarg apimod.pytest_xyz_noarg = pytest_xyz_noarg # type: ignore
return apiclass, apimod return apiclass, apimod
@pytest.mark.parametrize("holder", make_holder()) @pytest.mark.parametrize("holder", make_holder())
def test_hookrecorder_basic(holder): def test_hookrecorder_basic(holder) -> None:
pm = PytestPluginManager() pm = PytestPluginManager()
pm.add_hookspecs(holder) pm.add_hookspecs(holder)
rec = HookRecorder(pm) rec = HookRecorder(pm)
@ -168,17 +170,17 @@ def test_hookrecorder_basic(holder):
call = rec.popcall("pytest_xyz") call = rec.popcall("pytest_xyz")
assert call.arg == 123 assert call.arg == 123
assert call._name == "pytest_xyz" assert call._name == "pytest_xyz"
pytest.raises(pytest.fail.Exception, rec.popcall, "abc") pytest.raises(Failed, rec.popcall, "abc")
pm.hook.pytest_xyz_noarg() pm.hook.pytest_xyz_noarg()
call = rec.popcall("pytest_xyz_noarg") call = rec.popcall("pytest_xyz_noarg")
assert call._name == "pytest_xyz_noarg" assert call._name == "pytest_xyz_noarg"
def test_makepyfile_unicode(testdir): def test_makepyfile_unicode(testdir) -> None:
testdir.makepyfile(chr(0xFFFD)) testdir.makepyfile(chr(0xFFFD))
def test_makepyfile_utf8(testdir): def test_makepyfile_utf8(testdir) -> None:
"""Ensure makepyfile accepts utf-8 bytes as input (#2738)""" """Ensure makepyfile accepts utf-8 bytes as input (#2738)"""
utf8_contents = """ utf8_contents = """
def setup_function(function): def setup_function(function):
@ -189,7 +191,7 @@ def test_makepyfile_utf8(testdir):
class TestInlineRunModulesCleanup: class TestInlineRunModulesCleanup:
def test_inline_run_test_module_not_cleaned_up(self, testdir): def test_inline_run_test_module_not_cleaned_up(self, testdir) -> None:
test_mod = testdir.makepyfile("def test_foo(): assert True") test_mod = testdir.makepyfile("def test_foo(): assert True")
result = testdir.inline_run(str(test_mod)) result = testdir.inline_run(str(test_mod))
assert result.ret == ExitCode.OK assert result.ret == ExitCode.OK
@ -200,9 +202,9 @@ class TestInlineRunModulesCleanup:
def spy_factory(self): def spy_factory(self):
class SysModulesSnapshotSpy: class SysModulesSnapshotSpy:
instances = [] instances = [] # type: List[SysModulesSnapshotSpy]
def __init__(self, preserve=None): def __init__(self, preserve=None) -> None:
SysModulesSnapshotSpy.instances.append(self) SysModulesSnapshotSpy.instances.append(self)
self._spy_restore_count = 0 self._spy_restore_count = 0
self._spy_preserve = preserve self._spy_preserve = preserve
@ -216,7 +218,7 @@ class TestInlineRunModulesCleanup:
def test_inline_run_taking_and_restoring_a_sys_modules_snapshot( def test_inline_run_taking_and_restoring_a_sys_modules_snapshot(
self, testdir, monkeypatch self, testdir, monkeypatch
): ) -> None:
spy_factory = self.spy_factory() spy_factory = self.spy_factory()
monkeypatch.setattr(pytester, "SysModulesSnapshot", spy_factory) monkeypatch.setattr(pytester, "SysModulesSnapshot", spy_factory)
testdir.syspathinsert() testdir.syspathinsert()
@ -237,7 +239,7 @@ class TestInlineRunModulesCleanup:
def test_inline_run_sys_modules_snapshot_restore_preserving_modules( def test_inline_run_sys_modules_snapshot_restore_preserving_modules(
self, testdir, monkeypatch self, testdir, monkeypatch
): ) -> None:
spy_factory = self.spy_factory() spy_factory = self.spy_factory()
monkeypatch.setattr(pytester, "SysModulesSnapshot", spy_factory) monkeypatch.setattr(pytester, "SysModulesSnapshot", spy_factory)
test_mod = testdir.makepyfile("def test_foo(): pass") test_mod = testdir.makepyfile("def test_foo(): pass")
@ -248,7 +250,7 @@ class TestInlineRunModulesCleanup:
assert spy._spy_preserve("zope.interface") assert spy._spy_preserve("zope.interface")
assert spy._spy_preserve("zopelicious") assert spy._spy_preserve("zopelicious")
def test_external_test_module_imports_not_cleaned_up(self, testdir): def test_external_test_module_imports_not_cleaned_up(self, testdir) -> None:
testdir.syspathinsert() testdir.syspathinsert()
testdir.makepyfile(imported="data = 'you son of a silly person'") testdir.makepyfile(imported="data = 'you son of a silly person'")
import imported import imported
@ -263,7 +265,7 @@ class TestInlineRunModulesCleanup:
assert imported.data == 42 assert imported.data == 42
def test_assert_outcomes_after_pytest_error(testdir): def test_assert_outcomes_after_pytest_error(testdir) -> None:
testdir.makepyfile("def test_foo(): assert True") testdir.makepyfile("def test_foo(): assert True")
result = testdir.runpytest("--unexpected-argument") result = testdir.runpytest("--unexpected-argument")
@ -271,7 +273,7 @@ def test_assert_outcomes_after_pytest_error(testdir):
result.assert_outcomes(passed=0) result.assert_outcomes(passed=0)
def test_cwd_snapshot(tmpdir): def test_cwd_snapshot(tmpdir) -> None:
foo = tmpdir.ensure("foo", dir=1) foo = tmpdir.ensure("foo", dir=1)
bar = tmpdir.ensure("bar", dir=1) bar = tmpdir.ensure("bar", dir=1)
foo.chdir() foo.chdir()
@ -285,16 +287,16 @@ def test_cwd_snapshot(tmpdir):
class TestSysModulesSnapshot: class TestSysModulesSnapshot:
key = "my-test-module" key = "my-test-module"
def test_remove_added(self): def test_remove_added(self) -> None:
original = dict(sys.modules) original = dict(sys.modules)
assert self.key not in sys.modules assert self.key not in sys.modules
snapshot = SysModulesSnapshot() snapshot = SysModulesSnapshot()
sys.modules[self.key] = "something" sys.modules[self.key] = "something" # type: ignore
assert self.key in sys.modules assert self.key in sys.modules
snapshot.restore() snapshot.restore()
assert sys.modules == original assert sys.modules == original
def test_add_removed(self, monkeypatch): def test_add_removed(self, monkeypatch) -> None:
assert self.key not in sys.modules assert self.key not in sys.modules
monkeypatch.setitem(sys.modules, self.key, "something") monkeypatch.setitem(sys.modules, self.key, "something")
assert self.key in sys.modules assert self.key in sys.modules
@ -305,17 +307,17 @@ class TestSysModulesSnapshot:
snapshot.restore() snapshot.restore()
assert sys.modules == original assert sys.modules == original
def test_restore_reloaded(self, monkeypatch): def test_restore_reloaded(self, monkeypatch) -> None:
assert self.key not in sys.modules assert self.key not in sys.modules
monkeypatch.setitem(sys.modules, self.key, "something") monkeypatch.setitem(sys.modules, self.key, "something")
assert self.key in sys.modules assert self.key in sys.modules
original = dict(sys.modules) original = dict(sys.modules)
snapshot = SysModulesSnapshot() snapshot = SysModulesSnapshot()
sys.modules[self.key] = "something else" sys.modules[self.key] = "something else" # type: ignore
snapshot.restore() snapshot.restore()
assert sys.modules == original assert sys.modules == original
def test_preserve_modules(self, monkeypatch): def test_preserve_modules(self, monkeypatch) -> None:
key = [self.key + str(i) for i in range(3)] key = [self.key + str(i) for i in range(3)]
assert not any(k in sys.modules for k in key) assert not any(k in sys.modules for k in key)
for i, k in enumerate(key): for i, k in enumerate(key):
@ -326,17 +328,17 @@ class TestSysModulesSnapshot:
return name in (key[0], key[1], "some-other-key") return name in (key[0], key[1], "some-other-key")
snapshot = SysModulesSnapshot(preserve=preserve) snapshot = SysModulesSnapshot(preserve=preserve)
sys.modules[key[0]] = original[key[0]] = "something else0" sys.modules[key[0]] = original[key[0]] = "something else0" # type: ignore
sys.modules[key[1]] = original[key[1]] = "something else1" sys.modules[key[1]] = original[key[1]] = "something else1" # type: ignore
sys.modules[key[2]] = "something else2" sys.modules[key[2]] = "something else2" # type: ignore
snapshot.restore() snapshot.restore()
assert sys.modules == original assert sys.modules == original
def test_preserve_container(self, monkeypatch): def test_preserve_container(self, monkeypatch) -> None:
original = dict(sys.modules) original = dict(sys.modules)
assert self.key not in original assert self.key not in original
replacement = dict(sys.modules) replacement = dict(sys.modules)
replacement[self.key] = "life of brian" replacement[self.key] = "life of brian" # type: ignore
snapshot = SysModulesSnapshot() snapshot = SysModulesSnapshot()
monkeypatch.setattr(sys, "modules", replacement) monkeypatch.setattr(sys, "modules", replacement)
snapshot.restore() snapshot.restore()
@ -349,10 +351,10 @@ class TestSysPathsSnapshot:
other_path = {"path": "meta_path", "meta_path": "path"} other_path = {"path": "meta_path", "meta_path": "path"}
@staticmethod @staticmethod
def path(n): def path(n: int) -> str:
return "my-dirty-little-secret-" + str(n) return "my-dirty-little-secret-" + str(n)
def test_restore(self, monkeypatch, path_type): def test_restore(self, monkeypatch, path_type) -> None:
other_path_type = self.other_path[path_type] other_path_type = self.other_path[path_type]
for i in range(10): for i in range(10):
assert self.path(i) not in getattr(sys, path_type) assert self.path(i) not in getattr(sys, path_type)
@ -375,12 +377,12 @@ class TestSysPathsSnapshot:
assert getattr(sys, path_type) == original assert getattr(sys, path_type) == original
assert getattr(sys, other_path_type) == original_other assert getattr(sys, other_path_type) == original_other
def test_preserve_container(self, monkeypatch, path_type): def test_preserve_container(self, monkeypatch, path_type) -> None:
other_path_type = self.other_path[path_type] other_path_type = self.other_path[path_type]
original_data = list(getattr(sys, path_type)) original_data = list(getattr(sys, path_type))
original_other = getattr(sys, other_path_type) original_other = getattr(sys, other_path_type)
original_other_data = list(original_other) original_other_data = list(original_other)
new = [] new = [] # type: List[object]
snapshot = SysPathsSnapshot() snapshot = SysPathsSnapshot()
monkeypatch.setattr(sys, path_type, new) monkeypatch.setattr(sys, path_type, new)
snapshot.restore() snapshot.restore()
@ -390,7 +392,7 @@ class TestSysPathsSnapshot:
assert getattr(sys, other_path_type) == original_other_data assert getattr(sys, other_path_type) == original_other_data
def test_testdir_subprocess(testdir): def test_testdir_subprocess(testdir) -> None:
testfile = testdir.makepyfile("def test_one(): pass") testfile = testdir.makepyfile("def test_one(): pass")
assert testdir.runpytest_subprocess(testfile).ret == 0 assert testdir.runpytest_subprocess(testfile).ret == 0
@ -416,17 +418,17 @@ def test_testdir_subprocess_via_runpytest_arg(testdir) -> None:
assert result.ret == 0 assert result.ret == 0
def test_unicode_args(testdir): def test_unicode_args(testdir) -> None:
result = testdir.runpytest("-k", "💩") result = testdir.runpytest("-k", "💩")
assert result.ret == ExitCode.NO_TESTS_COLLECTED assert result.ret == ExitCode.NO_TESTS_COLLECTED
def test_testdir_run_no_timeout(testdir): def test_testdir_run_no_timeout(testdir) -> None:
testfile = testdir.makepyfile("def test_no_timeout(): pass") testfile = testdir.makepyfile("def test_no_timeout(): pass")
assert testdir.runpytest_subprocess(testfile).ret == ExitCode.OK assert testdir.runpytest_subprocess(testfile).ret == ExitCode.OK
def test_testdir_run_with_timeout(testdir): def test_testdir_run_with_timeout(testdir) -> None:
testfile = testdir.makepyfile("def test_no_timeout(): pass") testfile = testdir.makepyfile("def test_no_timeout(): pass")
timeout = 120 timeout = 120
@ -440,7 +442,7 @@ def test_testdir_run_with_timeout(testdir):
assert duration < timeout assert duration < timeout
def test_testdir_run_timeout_expires(testdir): def test_testdir_run_timeout_expires(testdir) -> None:
testfile = testdir.makepyfile( testfile = testdir.makepyfile(
""" """
import time import time
@ -452,7 +454,7 @@ def test_testdir_run_timeout_expires(testdir):
testdir.runpytest_subprocess(testfile, timeout=1) testdir.runpytest_subprocess(testfile, timeout=1)
def test_linematcher_with_nonlist(): def test_linematcher_with_nonlist() -> None:
"""Test LineMatcher with regard to passing in a set (accidentally).""" """Test LineMatcher with regard to passing in a set (accidentally)."""
lm = LineMatcher([]) lm = LineMatcher([])
@ -467,10 +469,11 @@ def test_linematcher_with_nonlist():
assert lm._getlines(set()) == set() assert lm._getlines(set()) == set()
def test_linematcher_match_failure(): def test_linematcher_match_failure() -> None:
lm = LineMatcher(["foo", "foo", "bar"]) lm = LineMatcher(["foo", "foo", "bar"])
with pytest.raises(pytest.fail.Exception) as e: with pytest.raises(Failed) as e:
lm.fnmatch_lines(["foo", "f*", "baz"]) lm.fnmatch_lines(["foo", "f*", "baz"])
assert e.value.msg is not None
assert e.value.msg.splitlines() == [ assert e.value.msg.splitlines() == [
"exact match: 'foo'", "exact match: 'foo'",
"fnmatch: 'f*'", "fnmatch: 'f*'",
@ -481,8 +484,9 @@ def test_linematcher_match_failure():
] ]
lm = LineMatcher(["foo", "foo", "bar"]) lm = LineMatcher(["foo", "foo", "bar"])
with pytest.raises(pytest.fail.Exception) as e: with pytest.raises(Failed) as e:
lm.re_match_lines(["foo", "^f.*", "baz"]) lm.re_match_lines(["foo", "^f.*", "baz"])
assert e.value.msg is not None
assert e.value.msg.splitlines() == [ assert e.value.msg.splitlines() == [
"exact match: 'foo'", "exact match: 'foo'",
"re.match: '^f.*'", "re.match: '^f.*'",
@ -494,7 +498,7 @@ def test_linematcher_match_failure():
@pytest.mark.parametrize("function", ["no_fnmatch_line", "no_re_match_line"]) @pytest.mark.parametrize("function", ["no_fnmatch_line", "no_re_match_line"])
def test_no_matching(function): def test_no_matching(function) -> None:
if function == "no_fnmatch_line": if function == "no_fnmatch_line":
good_pattern = "*.py OK*" good_pattern = "*.py OK*"
bad_pattern = "*X.py OK*" bad_pattern = "*X.py OK*"
@ -515,7 +519,7 @@ def test_no_matching(function):
# check the function twice to ensure we don't accumulate the internal buffer # check the function twice to ensure we don't accumulate the internal buffer
for i in range(2): for i in range(2):
with pytest.raises(pytest.fail.Exception) as e: with pytest.raises(Failed) as e:
func = getattr(lm, function) func = getattr(lm, function)
func(good_pattern) func(good_pattern)
obtained = str(e.value).splitlines() obtained = str(e.value).splitlines()
@ -542,15 +546,15 @@ def test_no_matching(function):
func(bad_pattern) # bad pattern does not match any line: passes func(bad_pattern) # bad pattern does not match any line: passes
def test_no_matching_after_match(): def test_no_matching_after_match() -> None:
lm = LineMatcher(["1", "2", "3"]) lm = LineMatcher(["1", "2", "3"])
lm.fnmatch_lines(["1", "3"]) lm.fnmatch_lines(["1", "3"])
with pytest.raises(pytest.fail.Exception) as e: with pytest.raises(Failed) as e:
lm.no_fnmatch_line("*") lm.no_fnmatch_line("*")
assert str(e.value).splitlines() == ["fnmatch: '*'", " with: '1'"] assert str(e.value).splitlines() == ["fnmatch: '*'", " with: '1'"]
def test_pytester_addopts(request, monkeypatch): def test_pytester_addopts(request, monkeypatch) -> None:
monkeypatch.setenv("PYTEST_ADDOPTS", "--orig-unused") monkeypatch.setenv("PYTEST_ADDOPTS", "--orig-unused")
testdir = request.getfixturevalue("testdir") testdir = request.getfixturevalue("testdir")
@ -563,7 +567,7 @@ def test_pytester_addopts(request, monkeypatch):
assert os.environ["PYTEST_ADDOPTS"] == "--orig-unused" assert os.environ["PYTEST_ADDOPTS"] == "--orig-unused"
def test_run_stdin(testdir): def test_run_stdin(testdir) -> None:
with pytest.raises(testdir.TimeoutExpired): with pytest.raises(testdir.TimeoutExpired):
testdir.run( testdir.run(
sys.executable, sys.executable,
@ -593,7 +597,7 @@ def test_run_stdin(testdir):
assert result.ret == 0 assert result.ret == 0
def test_popen_stdin_pipe(testdir): def test_popen_stdin_pipe(testdir) -> None:
proc = testdir.popen( proc = testdir.popen(
[sys.executable, "-c", "import sys; print(sys.stdin.read())"], [sys.executable, "-c", "import sys; print(sys.stdin.read())"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@ -607,7 +611,7 @@ def test_popen_stdin_pipe(testdir):
assert proc.returncode == 0 assert proc.returncode == 0
def test_popen_stdin_bytes(testdir): def test_popen_stdin_bytes(testdir) -> None:
proc = testdir.popen( proc = testdir.popen(
[sys.executable, "-c", "import sys; print(sys.stdin.read())"], [sys.executable, "-c", "import sys; print(sys.stdin.read())"],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@ -620,7 +624,7 @@ def test_popen_stdin_bytes(testdir):
assert proc.returncode == 0 assert proc.returncode == 0
def test_popen_default_stdin_stderr_and_stdin_None(testdir): def test_popen_default_stdin_stderr_and_stdin_None(testdir) -> None:
# stdout, stderr default to pipes, # stdout, stderr default to pipes,
# stdin can be None to not close the pipe, avoiding # stdin can be None to not close the pipe, avoiding
# "ValueError: flush of closed file" with `communicate()`. # "ValueError: flush of closed file" with `communicate()`.
@ -639,7 +643,7 @@ def test_popen_default_stdin_stderr_and_stdin_None(testdir):
assert proc.returncode == 0 assert proc.returncode == 0
def test_spawn_uses_tmphome(testdir): def test_spawn_uses_tmphome(testdir) -> None:
import os import os
tmphome = str(testdir.tmpdir) tmphome = str(testdir.tmpdir)
@ -665,7 +669,7 @@ def test_spawn_uses_tmphome(testdir):
assert child.wait() == 0, out.decode("utf8") assert child.wait() == 0, out.decode("utf8")
def test_run_result_repr(): def test_run_result_repr() -> None:
outlines = ["some", "normal", "output"] outlines = ["some", "normal", "output"]
errlines = ["some", "nasty", "errors", "happened"] errlines = ["some", "nasty", "errors", "happened"]