diff --git a/_pytest/capture.py b/_pytest/capture.py index 855b99bde..58f9cb525 100644 --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -86,8 +86,10 @@ class CaptureManager: self.deactivate_funcargs() cap = getattr(self, "_capturing", None) if cap is not None: - outerr = cap.readouterr() - cap.suspend_capturing(in_=in_) + try: + outerr = cap.readouterr() + finally: + cap.suspend_capturing(in_=in_) return outerr def activate_funcargs(self, pyfuncitem): diff --git a/testing/test_capture.py b/testing/test_capture.py index b20961c03..81238432a 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -566,6 +566,25 @@ def test_capture_binary_output(testdir): result.assert_outcomes(passed=2) +def test_error_during_readouterr(testdir): + """Make sure we suspend capturing if errors occurr during readouterr""" + 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.stderr.fnmatch_lines([ + "*in bad_snap", + " raise Exception('boom')", + "Exception: boom", + ]) + + class TestTextIO: def test_text(self): f = capture.TextIO()