From 5d9d12a6bec2c4b30d456382afe11ad44b203891 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 10 Apr 2019 21:36:42 +0200 Subject: [PATCH 1/3] pytester: improve/fix kwargs validation --- src/_pytest/pytester.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/_pytest/pytester.py b/src/_pytest/pytester.py index 6dc9031df..2c6ff2020 100644 --- a/src/_pytest/pytester.py +++ b/src/_pytest/pytester.py @@ -76,8 +76,11 @@ def pytest_configure(config): def raise_on_kwargs(kwargs): + __tracebackhide__ = True if kwargs: - raise TypeError("Unexpected arguments: {}".format(", ".join(sorted(kwargs)))) + raise TypeError( + "Unexpected keyword arguments: {}".format(", ".join(sorted(kwargs))) + ) class LsofFdLeakChecker(object): @@ -803,12 +806,15 @@ class Testdir(object): :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 :return: a :py:class:`HookRecorder` instance - """ + plugins = kwargs.pop("plugins", []) + no_reraise_ctrlc = kwargs.pop("no_reraise_ctrlc", None) + raise_on_kwargs(kwargs) + finalizers = [] try: # Do not load user config (during runs only). @@ -848,7 +854,6 @@ class Testdir(object): def pytest_configure(x, config): rec.append(self.make_hook_recorder(config.pluginmanager)) - plugins = kwargs.get("plugins") or [] plugins.append(Collect()) ret = pytest.main(list(args), plugins=plugins) if len(rec) == 1: @@ -862,7 +867,7 @@ class Testdir(object): # typically we reraise keyboard interrupts from the child run # 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") if calls and calls[-1].excinfo.type == KeyboardInterrupt: raise KeyboardInterrupt() @@ -874,9 +879,10 @@ class Testdir(object): def runpytest_inprocess(self, *args, **kwargs): """Return result of running pytest in-process, providing a similar interface to what self.runpytest() provides. - """ - if kwargs.get("syspathinsert"): + syspathinsert = kwargs.pop("syspathinsert", False) + + if syspathinsert: self.syspathinsert() now = time.time() capture = MultiCapture(Capture=SysCapture) @@ -1201,9 +1207,10 @@ class Testdir(object): :py:class:`Testdir.TimeoutExpired` Returns a :py:class:`RunResult`. - """ __tracebackhide__ = True + timeout = kwargs.pop("timeout", None) + raise_on_kwargs(kwargs) p = py.path.local.make_numbered_dir( prefix="runpytest-", keep=None, rootdir=self.tmpdir @@ -1213,7 +1220,7 @@ class Testdir(object): if plugins: args = ("-p", plugins[0]) + 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): """Run pytest using pexpect. From 148f2fc72cae5eb4af2e1ecf0ccd95aebec03b33 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 10 Apr 2019 21:56:44 +0200 Subject: [PATCH 2/3] Fix test_error_during_readouterr: syspathinsert is unused --- testing/test_capture.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/test_capture.py b/testing/test_capture.py index 1b34ab583..c3881128f 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -819,15 +819,15 @@ def test_error_during_readouterr(testdir): testdir.makepyfile( pytest_xyz=""" from _pytest.capture import FDCapture + def bad_snap(self): raise Exception('boom') + assert FDCapture.snap FDCapture.snap = bad_snap """ ) - result = testdir.runpytest_subprocess( - "-p", "pytest_xyz", "--version", syspathinsert=True - ) + result = testdir.runpytest_subprocess("-p", "pytest_xyz", "--version") result.stderr.fnmatch_lines( ["*in bad_snap", " raise Exception('boom')", "Exception: boom"] ) From 12133d4eb7480c490b3770988da37bac375633c3 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Wed, 10 Apr 2019 23:15:25 +0200 Subject: [PATCH 3/3] changelog [ci skip] --- changelog/5082.trivial.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/5082.trivial.rst diff --git a/changelog/5082.trivial.rst b/changelog/5082.trivial.rst new file mode 100644 index 000000000..edd23a28f --- /dev/null +++ b/changelog/5082.trivial.rst @@ -0,0 +1 @@ +Improved validation of kwargs for various methods in the pytester plugin.