From 6d8dac78d75e7d4d20760ad677025c0259d4c1ce Mon Sep 17 00:00:00 2001 From: getzze Date: Wed, 12 Nov 2025 22:50:25 +0000 Subject: [PATCH 1/3] fix CliRunner error with logging message --- src/click/testing.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/click/testing.py b/src/click/testing.py index f6f60b809..1c97e480e 100644 --- a/src/click/testing.py +++ b/src/click/testing.py @@ -77,8 +77,8 @@ def __init__(self, copy_to: io.BytesIO) -> None: self.copy_to = copy_to def flush(self) -> None: - super().flush() self.copy_to.flush() + super().flush() def write(self, b: ReadableBuffer) -> int: self.copy_to.write(b) @@ -106,9 +106,9 @@ def __del__(self) -> None: .. versionadded:: 8.2.2 """ - self.stderr.close() - self.stdout.close() - self.output.close() + del self.stdout + del self.stderr + del self.output class _NamedTextIOWrapper(io.TextIOWrapper): From d71fa4186267b3d524bea5184250a432dc2cae83 Mon Sep 17 00:00:00 2001 From: getzze Date: Thu, 13 Nov 2025 13:27:32 +0000 Subject: [PATCH 2/3] deal with copy_to stream being closed --- src/click/testing.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/click/testing.py b/src/click/testing.py index 1c97e480e..e734ddd08 100644 --- a/src/click/testing.py +++ b/src/click/testing.py @@ -72,16 +72,20 @@ class BytesIOCopy(io.BytesIO): .. versionadded:: 8.2 """ + copy_to: io.BytesIO + def __init__(self, copy_to: io.BytesIO) -> None: super().__init__() self.copy_to = copy_to def flush(self) -> None: - self.copy_to.flush() + if not self.copy_to.closed: + self.copy_to.flush() super().flush() def write(self, b: ReadableBuffer) -> int: - self.copy_to.write(b) + if not self.copy_to.closed: + self.copy_to.write(b) return super().write(b) @@ -100,9 +104,9 @@ def __init__(self) -> None: def __del__(self) -> None: """ - Guarantee that embedded file-like objects are closed in a + Guarantee that embedded file-like objects are deleted in a predictable order, protecting against races between - self.output being closed and other streams being flushed on close + self.output being deleted and other streams being flushed on deletion. .. versionadded:: 8.2.2 """ From 59ed11763ba9c895cb85e305365a80ddbd7cdfc3 Mon Sep 17 00:00:00 2001 From: getzze Date: Thu, 13 Nov 2025 13:27:47 +0000 Subject: [PATCH 3/3] add description in CHANGES.rst --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index 493cf2d88..cfc786ad8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,6 +15,8 @@ Unreleased empty. :issue:`3019` :pr:`3021` - When ``Sentinel.UNSET`` is found during parsing, it will skip calls to ``type_cast_value``. :issue:`3069` :pr:`3090` +- Fix regression related to ``click.testing.StreamMixer`` finalization in ``CliRunner`` + that introduced a race condition. :issue:`3110` :pr:`3140` Version 8.3.0 --------------