Merge pull request #5082 from blueyed/pytester-raise_on_kwargs
pytester: improve/fix kwargs validation
This commit is contained in:
commit
b3759372ad
|
@ -0,0 +1 @@
|
||||||
|
Improved validation of kwargs for various methods in the pytester plugin.
|
|
@ -76,8 +76,11 @@ def pytest_configure(config):
|
||||||
|
|
||||||
|
|
||||||
def raise_on_kwargs(kwargs):
|
def raise_on_kwargs(kwargs):
|
||||||
|
__tracebackhide__ = True
|
||||||
if kwargs:
|
if kwargs:
|
||||||
raise TypeError("Unexpected arguments: {}".format(", ".join(sorted(kwargs))))
|
raise TypeError(
|
||||||
|
"Unexpected keyword arguments: {}".format(", ".join(sorted(kwargs)))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LsofFdLeakChecker(object):
|
class LsofFdLeakChecker(object):
|
||||||
|
@ -803,12 +806,15 @@ class Testdir(object):
|
||||||
|
|
||||||
:param args: command line arguments to pass to :py:func:`pytest.main`
|
:param args: command line arguments to pass to :py:func:`pytest.main`
|
||||||
|
|
||||||
:param plugin: (keyword-only) extra plugin instances the
|
:param plugins: (keyword-only) extra plugin instances the
|
||||||
``pytest.main()`` instance should use
|
``pytest.main()`` instance should use
|
||||||
|
|
||||||
:return: a :py:class:`HookRecorder` instance
|
:return: a :py:class:`HookRecorder` instance
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
plugins = kwargs.pop("plugins", [])
|
||||||
|
no_reraise_ctrlc = kwargs.pop("no_reraise_ctrlc", None)
|
||||||
|
raise_on_kwargs(kwargs)
|
||||||
|
|
||||||
finalizers = []
|
finalizers = []
|
||||||
try:
|
try:
|
||||||
# Do not load user config (during runs only).
|
# Do not load user config (during runs only).
|
||||||
|
@ -848,7 +854,6 @@ class Testdir(object):
|
||||||
def pytest_configure(x, config):
|
def pytest_configure(x, config):
|
||||||
rec.append(self.make_hook_recorder(config.pluginmanager))
|
rec.append(self.make_hook_recorder(config.pluginmanager))
|
||||||
|
|
||||||
plugins = kwargs.get("plugins") or []
|
|
||||||
plugins.append(Collect())
|
plugins.append(Collect())
|
||||||
ret = pytest.main(list(args), plugins=plugins)
|
ret = pytest.main(list(args), plugins=plugins)
|
||||||
if len(rec) == 1:
|
if len(rec) == 1:
|
||||||
|
@ -862,7 +867,7 @@ class Testdir(object):
|
||||||
|
|
||||||
# typically we reraise keyboard interrupts from the child run
|
# typically we reraise keyboard interrupts from the child run
|
||||||
# because it's our user requesting interruption of the testing
|
# because it's our user requesting interruption of the testing
|
||||||
if ret == EXIT_INTERRUPTED and not kwargs.get("no_reraise_ctrlc"):
|
if ret == EXIT_INTERRUPTED and not no_reraise_ctrlc:
|
||||||
calls = reprec.getcalls("pytest_keyboard_interrupt")
|
calls = reprec.getcalls("pytest_keyboard_interrupt")
|
||||||
if calls and calls[-1].excinfo.type == KeyboardInterrupt:
|
if calls and calls[-1].excinfo.type == KeyboardInterrupt:
|
||||||
raise KeyboardInterrupt()
|
raise KeyboardInterrupt()
|
||||||
|
@ -874,9 +879,10 @@ class Testdir(object):
|
||||||
def runpytest_inprocess(self, *args, **kwargs):
|
def runpytest_inprocess(self, *args, **kwargs):
|
||||||
"""Return result of running pytest in-process, providing a similar
|
"""Return result of running pytest in-process, providing a similar
|
||||||
interface to what self.runpytest() provides.
|
interface to what self.runpytest() provides.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if kwargs.get("syspathinsert"):
|
syspathinsert = kwargs.pop("syspathinsert", False)
|
||||||
|
|
||||||
|
if syspathinsert:
|
||||||
self.syspathinsert()
|
self.syspathinsert()
|
||||||
now = time.time()
|
now = time.time()
|
||||||
capture = MultiCapture(Capture=SysCapture)
|
capture = MultiCapture(Capture=SysCapture)
|
||||||
|
@ -1201,9 +1207,10 @@ class Testdir(object):
|
||||||
:py:class:`Testdir.TimeoutExpired`
|
:py:class:`Testdir.TimeoutExpired`
|
||||||
|
|
||||||
Returns a :py:class:`RunResult`.
|
Returns a :py:class:`RunResult`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
|
timeout = kwargs.pop("timeout", None)
|
||||||
|
raise_on_kwargs(kwargs)
|
||||||
|
|
||||||
p = py.path.local.make_numbered_dir(
|
p = py.path.local.make_numbered_dir(
|
||||||
prefix="runpytest-", keep=None, rootdir=self.tmpdir
|
prefix="runpytest-", keep=None, rootdir=self.tmpdir
|
||||||
|
@ -1213,7 +1220,7 @@ class Testdir(object):
|
||||||
if plugins:
|
if plugins:
|
||||||
args = ("-p", plugins[0]) + args
|
args = ("-p", plugins[0]) + args
|
||||||
args = self._getpytestargs() + args
|
args = self._getpytestargs() + args
|
||||||
return self.run(*args, timeout=kwargs.get("timeout"))
|
return self.run(*args, timeout=timeout)
|
||||||
|
|
||||||
def spawn_pytest(self, string, expect_timeout=10.0):
|
def spawn_pytest(self, string, expect_timeout=10.0):
|
||||||
"""Run pytest using pexpect.
|
"""Run pytest using pexpect.
|
||||||
|
|
|
@ -819,15 +819,15 @@ def test_error_during_readouterr(testdir):
|
||||||
testdir.makepyfile(
|
testdir.makepyfile(
|
||||||
pytest_xyz="""
|
pytest_xyz="""
|
||||||
from _pytest.capture import FDCapture
|
from _pytest.capture import FDCapture
|
||||||
|
|
||||||
def bad_snap(self):
|
def bad_snap(self):
|
||||||
raise Exception('boom')
|
raise Exception('boom')
|
||||||
|
|
||||||
assert FDCapture.snap
|
assert FDCapture.snap
|
||||||
FDCapture.snap = bad_snap
|
FDCapture.snap = bad_snap
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
result = testdir.runpytest_subprocess(
|
result = testdir.runpytest_subprocess("-p", "pytest_xyz", "--version")
|
||||||
"-p", "pytest_xyz", "--version", syspathinsert=True
|
|
||||||
)
|
|
||||||
result.stderr.fnmatch_lines(
|
result.stderr.fnmatch_lines(
|
||||||
["*in bad_snap", " raise Exception('boom')", "Exception: boom"]
|
["*in bad_snap", " raise Exception('boom')", "Exception: boom"]
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue