diff --git a/CHANGELOG.md b/CHANGELOG.md index a49fd87d..5a802bb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and ## Unreleased +- [#970](https://github.com/pytask-dev/pytask/pull/970) prevents tee-sys capture from + replaying output that was already displayed when capture stops before its buffer is + read. - [#968](https://github.com/pytask-dev/pytask/pull/968) improves the performance of file descriptor capture for tasks that produce no output. - Documents the pytest provenance of the adapted debugging, marker, and warning diff --git a/src/_pytask/capture.py b/src/_pytask/capture.py index 300ada5a..291c1f50 100644 --- a/src/_pytask/capture.py +++ b/src/_pytask/capture.py @@ -769,7 +769,11 @@ def start_capturing(self) -> None: def stop_capturing(self) -> None: if self._capturing is not None: - self._capturing.pop_outerr_to_orig() + if self._method == CaptureMethod.TEE_SYS: + # TeeCaptureIO already forwarded the output to the original streams. + self._capturing.readouterr() + else: + self._capturing.pop_outerr_to_orig() self._capturing.stop_capturing() self._capturing = None diff --git a/tests/test_capture.py b/tests/test_capture.py index 35277372..e4828f97 100644 --- a/tests/test_capture.py +++ b/tests/test_capture.py @@ -187,6 +187,28 @@ def TeeStdCapture( # noqa: N802 class TestCaptureManager: + def test_stop_capturing_does_not_replay_tee_output(self, capsys): + capman = CaptureManager(CaptureMethod.TEE_SYS) + capman.start_capturing() + print("stdout") + print("stderr", file=sys.stderr) + + capman.stop_capturing() + + captured = capsys.readouterr() + assert captured == ("stdout\n", "stderr\n") + + def test_stop_capturing_replays_non_tee_output(self, capsys): + capman = CaptureManager(CaptureMethod.SYS) + capman.start_capturing() + print("stdout") + print("stderr", file=sys.stderr) + + capman.stop_capturing() + + captured = capsys.readouterr() + assert captured == ("stdout\n", "stderr\n") + @pytest.mark.parametrize( "method", [CaptureMethod.NO, CaptureMethod.SYS, CaptureMethod.FD] )