From afac1f002109e71a0b492d5aba44c30bfdaec89d Mon Sep 17 00:00:00 2001 From: Philipp Loose Date: Fri, 18 Oct 2019 23:11:41 +0200 Subject: [PATCH 1/6] Remove unreachable code from config._prepareconfig The code that could trigger the execution of the removed lines was removed with a7e4016. --- src/_pytest/config/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 39c8d2cdf..1bab9877c 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -195,7 +195,6 @@ def get_plugin_manager(): def _prepareconfig(args=None, plugins=None): - warning = None if args is None: args = sys.argv[1:] elif isinstance(args, py.path.local): @@ -213,10 +212,6 @@ def _prepareconfig(args=None, plugins=None): pluginmanager.consider_pluginarg(plugin) else: pluginmanager.register(plugin) - if warning: - from _pytest.warnings import _issue_warning_captured - - _issue_warning_captured(warning, hook=config.hook, stacklevel=4) return pluginmanager.hook.pytest_cmdline_parse( pluginmanager=pluginmanager, args=args ) From 18786992bb0b77496d45ed998fb922c50309a0d1 Mon Sep 17 00:00:00 2001 From: Albert Tugushev Date: Sat, 19 Oct 2019 14:50:01 +0700 Subject: [PATCH 2/6] Update doc to use contextlib2.nullcontext nullcontext has been backported in contextlib2==0.6.0 --- doc/en/example/parametrize.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/example/parametrize.rst b/doc/en/example/parametrize.rst index 0b94e425c..1220cfb4d 100644 --- a/doc/en/example/parametrize.rst +++ b/doc/en/example/parametrize.rst @@ -678,4 +678,4 @@ Or, if desired, you can ``pip install contextlib2`` and use: .. code-block:: python - from contextlib2 import ExitStack as does_not_raise + from contextlib2 import nullcontext as does_not_raise From e05b33ed162fd9da8f9c44c9de035a0fa14631ec Mon Sep 17 00:00:00 2001 From: Yoav Caspi Date: Sat, 19 Oct 2019 22:28:06 +0300 Subject: [PATCH 3/6] setuponly: remove printing out/err from capman --- AUTHORS | 1 + changelog/5906.bugfix.rst | 1 + src/_pytest/setuponly.py | 5 ----- testing/python/setup_only.py | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 changelog/5906.bugfix.rst diff --git a/AUTHORS b/AUTHORS index 9f6ee048d..e11400c1f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -267,5 +267,6 @@ Wouter van Ackooy Xixi Zhao Xuan Luong Xuecong Liao +Yoav Caspi Zac Hatfield-Dodds Zoltán Máté diff --git a/changelog/5906.bugfix.rst b/changelog/5906.bugfix.rst new file mode 100644 index 000000000..f5ded6cd2 --- /dev/null +++ b/changelog/5906.bugfix.rst @@ -0,0 +1 @@ +Fix crash with ``KeyboardInterrupt`` during ``--setup-show``. diff --git a/src/_pytest/setuponly.py b/src/_pytest/setuponly.py index 70d6ed12f..639349748 100644 --- a/src/_pytest/setuponly.py +++ b/src/_pytest/setuponly.py @@ -1,5 +1,3 @@ -import sys - import pytest @@ -51,7 +49,6 @@ def _show_fixture_action(fixturedef, msg): capman = config.pluginmanager.getplugin("capturemanager") if capman: capman.suspend_global_capture() - out, err = capman.read_global_capture() tw = config.get_terminal_writer() tw.line() @@ -74,8 +71,6 @@ def _show_fixture_action(fixturedef, msg): if capman: capman.resume_global_capture() - sys.stdout.write(out) - sys.stderr.write(err) @pytest.hookimpl(tryfirst=True) diff --git a/testing/python/setup_only.py b/testing/python/setup_only.py index 7c871a9ee..1c3a1d368 100644 --- a/testing/python/setup_only.py +++ b/testing/python/setup_only.py @@ -267,3 +267,39 @@ def test_show_fixtures_and_execute_test(testdir): result.stdout.fnmatch_lines( ["*SETUP F arg*", "*test_arg (fixtures used: arg)F*", "*TEARDOWN F arg*"] ) + + +def test_setup_show_with_KeyboardInterrupt_in_test(testdir): + """ Verifies that setups are shown and tests are executed even if there was a KeyboardInterrupt in a test. """ + p = testdir.makepyfile( + """ + import pytest + @pytest.fixture + def arg(): + assert True + def test_arg(arg): + raise KeyboardInterrupt() + """ + ) + result = testdir.runpytest("--setup-show", p, no_reraise_ctrlc=True) + assert result.ret == 2 + result.stdout.fnmatch_lines( + ["*SETUP F arg*", "*test_arg (fixtures used: arg)*", "*TEARDOWN F arg*"] + ) + + +def test_setup_show_with_KeyboardInterrupt_in_fixture(testdir): + """ Verifies that setups are shown and tests are executed even if there was a KeyboardInterrupt in a fixture. """ + p = testdir.makepyfile( + """ + import pytest + @pytest.fixture + def arg(): + raise KeyboardInterrupt() + def test_arg(arg): + assert True + """ + ) + result = testdir.runpytest("--setup-show", p, no_reraise_ctrlc=True) + assert result.ret == 2 + result.stdout.fnmatch_lines(["*SETUP F arg*", "*KeyboardInterrupt*"]) From 3a402811de5227dd46d3a9ab75a9e75d3ef3097e Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 19 Oct 2019 13:45:15 -0700 Subject: [PATCH 4/6] Ensure .pytest_cache file has a newline at the end --- src/_pytest/cacheprovider.py | 2 +- testing/test_cacheprovider.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 496931e0f..7a5deaa39 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -135,7 +135,7 @@ class Cache: readme_path.write_text(README_CONTENT) gitignore_path = self._cachedir.joinpath(".gitignore") - msg = "# Created by pytest automatically.\n*" + msg = "# Created by pytest automatically.\n*\n" gitignore_path.write_text(msg, encoding="UTF-8") cachedir_tag_path = self._cachedir.joinpath("CACHEDIR.TAG") diff --git a/testing/test_cacheprovider.py b/testing/test_cacheprovider.py index cbba27e5f..038c11826 100644 --- a/testing/test_cacheprovider.py +++ b/testing/test_cacheprovider.py @@ -1029,7 +1029,7 @@ def test_gitignore(testdir): config = testdir.parseconfig() cache = Cache.for_config(config) cache.set("foo", "bar") - msg = "# Created by pytest automatically.\n*" + msg = "# Created by pytest automatically.\n*\n" gitignore_path = cache._cachedir.joinpath(".gitignore") assert gitignore_path.read_text(encoding="UTF-8") == msg From 5624e366c1c812e200231e70c6ba2f15dc04a323 Mon Sep 17 00:00:00 2001 From: Yoav Caspi Date: Sun, 20 Oct 2019 09:54:23 +0300 Subject: [PATCH 5/6] add more indications to the result of the tests --- testing/python/setup_only.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/testing/python/setup_only.py b/testing/python/setup_only.py index 1c3a1d368..8e4e3ace8 100644 --- a/testing/python/setup_only.py +++ b/testing/python/setup_only.py @@ -284,7 +284,13 @@ def test_setup_show_with_KeyboardInterrupt_in_test(testdir): result = testdir.runpytest("--setup-show", p, no_reraise_ctrlc=True) assert result.ret == 2 result.stdout.fnmatch_lines( - ["*SETUP F arg*", "*test_arg (fixtures used: arg)*", "*TEARDOWN F arg*"] + [ + "*SETUP F arg*", + "*test_arg (fixtures used: arg)*", + "*TEARDOWN F arg*", + "*! KeyboardInterrupt !*", + "*= no tests ran in *", + ] ) @@ -302,4 +308,6 @@ def test_setup_show_with_KeyboardInterrupt_in_fixture(testdir): ) result = testdir.runpytest("--setup-show", p, no_reraise_ctrlc=True) assert result.ret == 2 - result.stdout.fnmatch_lines(["*SETUP F arg*", "*KeyboardInterrupt*"]) + result.stdout.fnmatch_lines( + ["*SETUP F arg*", "*! KeyboardInterrupt !*", "*= no tests ran in *"] + ) From 0123b29ed754afd77b737845e5a205cc2404afbe Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 20 Oct 2019 20:39:56 +0200 Subject: [PATCH 6/6] tests: remove unnecessary test, clarify Follow-up to https://github.com/pytest-dev/pytest/pull/6009. --- testing/python/setup_only.py | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/testing/python/setup_only.py b/testing/python/setup_only.py index 8e4e3ace8..02bc65fac 100644 --- a/testing/python/setup_only.py +++ b/testing/python/setup_only.py @@ -1,4 +1,5 @@ import pytest +from _pytest.main import ExitCode @pytest.fixture(params=["--setup-only", "--setup-plan", "--setup-show"], scope="module") @@ -270,19 +271,17 @@ def test_show_fixtures_and_execute_test(testdir): def test_setup_show_with_KeyboardInterrupt_in_test(testdir): - """ Verifies that setups are shown and tests are executed even if there was a KeyboardInterrupt in a test. """ p = testdir.makepyfile( """ import pytest @pytest.fixture def arg(): - assert True + pass def test_arg(arg): raise KeyboardInterrupt() """ ) result = testdir.runpytest("--setup-show", p, no_reraise_ctrlc=True) - assert result.ret == 2 result.stdout.fnmatch_lines( [ "*SETUP F arg*", @@ -292,22 +291,4 @@ def test_setup_show_with_KeyboardInterrupt_in_test(testdir): "*= no tests ran in *", ] ) - - -def test_setup_show_with_KeyboardInterrupt_in_fixture(testdir): - """ Verifies that setups are shown and tests are executed even if there was a KeyboardInterrupt in a fixture. """ - p = testdir.makepyfile( - """ - import pytest - @pytest.fixture - def arg(): - raise KeyboardInterrupt() - def test_arg(arg): - assert True - """ - ) - result = testdir.runpytest("--setup-show", p, no_reraise_ctrlc=True) - assert result.ret == 2 - result.stdout.fnmatch_lines( - ["*SETUP F arg*", "*! KeyboardInterrupt !*", "*= no tests ran in *"] - ) + assert result.ret == ExitCode.INTERRUPTED