From 382371397da88d97d185494e14ef97b5408c236b Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Fri, 28 Aug 2026 22:50:22 +0200 Subject: [PATCH 1/2] fix: avoid replaying tee capture output --- CHANGELOG.md | 2 ++ src/_pytask/capture.py | 6 +++++- tests/test_capture.py | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a49fd87d..5f076217 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and ## Unreleased +- 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] ) From 724235ff05023ec03632ae485d9fb51082054953 Mon Sep 17 00:00:00 2001 From: Tobias Raabe Date: Fri, 28 Aug 2026 22:51:09 +0200 Subject: [PATCH 2/2] docs: link tee capture changelog entry --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f076217..5a802bb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,9 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and ## Unreleased -- Prevents tee-sys capture from replaying output that was already displayed when - capture stops before its buffer is read. +- [#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