From d9a44098ce0d5195ecd5f4278c718d6f34f504ef Mon Sep 17 00:00:00 2001 From: holger krekel Date: Thu, 7 May 2015 11:02:55 +0200 Subject: [PATCH] use new pluggy api (now at 0.3.0) for adding hookcall monitoring and reraise real keyboard interrupts during inline pytest runs to allow for better stopping of the pytest tests. --HG-- branch : plug30 --- _pytest/__init__.py | 2 +- _pytest/pytester.py | 22 +++++++++++++++------- setup.py | 2 +- testing/test_terminal.py | 10 +++++----- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/_pytest/__init__.py b/_pytest/__init__.py index e731c2e3a..5b3715e54 100644 --- a/_pytest/__init__.py +++ b/_pytest/__init__.py @@ -1,2 +1,2 @@ # -__version__ = '2.8.0.dev3' +__version__ = '2.8.0.dev4' diff --git a/_pytest/pytester.py b/_pytest/pytester.py index 4032ff04d..938607b65 100644 --- a/_pytest/pytester.py +++ b/_pytest/pytester.py @@ -13,7 +13,6 @@ import subprocess import py import pytest from py.builtin import print_ -from pluggy import _TracedHookExecution from _pytest.main import Session, EXIT_OK @@ -194,12 +193,13 @@ class HookRecorder: self._pluginmanager = pluginmanager self.calls = [] - def before(hook, method, kwargs): - self.calls.append(ParsedCall(hook.name, kwargs)) - def after(outcome, hook, method, kwargs): + def before(hook_name, hook_impls, kwargs): + self.calls.append(ParsedCall(hook_name, kwargs)) + + def after(outcome, hook_name, hook_impls, kwargs): pass - executor = _TracedHookExecution(pluginmanager, before, after) - self._undo_wrapping = executor.undo + + self._undo_wrapping = pluginmanager.add_hookcall_monitoring(before, after) def finish_recording(self): self._undo_wrapping() @@ -667,6 +667,7 @@ class Testdir: class Collect: 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) @@ -677,6 +678,13 @@ class Testdir: class reprec: pass reprec.ret = ret + + # typically we reraise keyboard interrupts from the child run + # because it's our user requesting interruption of the testing + if ret == 2 and not kwargs.get("no_reraise_ctrlc"): + calls = reprec.getcalls("pytest_keyboard_interrupt") + if calls and calls[-1].excinfo.type == KeyboardInterrupt: + raise KeyboardInterrupt() return reprec def runpytest_inprocess(self, *args, **kwargs): @@ -688,7 +696,7 @@ class Testdir: capture = py.io.StdCapture() try: try: - reprec = self.inline_run(*args) + reprec = self.inline_run(*args, **kwargs) except SystemExit as e: class reprec: ret = e.args[0] diff --git a/setup.py b/setup.py index 0cd643a36..96b861145 100644 --- a/setup.py +++ b/setup.py @@ -48,7 +48,7 @@ def has_environment_marker_support(): def main(): - install_requires = ['py>=1.4.27.dev2', 'pluggy>=0.2.0,<0.3.0'] + install_requires = ['py>=1.4.27.dev2', 'pluggy>=0.3.0,<0.4.0'] extras_require = {} if has_environment_marker_support(): extras_require[':python_version=="2.6" or python_version=="3.0" or python_version=="3.1"'] = ['argparse'] diff --git a/testing/test_terminal.py b/testing/test_terminal.py index cf2a69cb9..fba3021e0 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -132,8 +132,8 @@ class TestTerminal: ]) def test_itemreport_directclasses_not_shown_as_subclasses(self, testdir): - a = testdir.mkpydir("a") - a.join("test_hello.py").write(py.code.Source(""" + a = testdir.mkpydir("a123") + a.join("test_hello123.py").write(py.code.Source(""" class TestClass: def test_method(self): pass @@ -141,7 +141,7 @@ class TestTerminal: result = testdir.runpytest("-v") assert result.ret == 0 result.stdout.fnmatch_lines([ - "*a/test_hello.py*PASS*", + "*a123/test_hello123.py*PASS*", ]) assert " <- " not in result.stdout.str() @@ -155,7 +155,7 @@ class TestTerminal: raise KeyboardInterrupt # simulating the user """) - result = testdir.runpytest(*option.args) + result = testdir.runpytest(*option.args, no_reraise_ctrlc=True) result.stdout.fnmatch_lines([ " def test_foobar():", "> assert 0", @@ -178,7 +178,7 @@ class TestTerminal: pass """) - result = testdir.runpytest() + result = testdir.runpytest(no_reraise_ctrlc=True) assert result.ret == 2 result.stdout.fnmatch_lines(['*KeyboardInterrupt*'])