Skip to content

Commit 6438cd6

Browse files
committed
NamedTextIOWrapper: stop closing buffer
The NamedTextIOWrapper is closing the buffers that are owned by the StreamMixer, so implement a close() method that prevents it from doing that. Refs #824 Refs #2993
1 parent ea70da4 commit 6438cd6

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

src/click/testing.py

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,6 @@ def __init__(self) -> None:
9898
self.stdout: io.BytesIO = BytesIOCopy(copy_to=self.output)
9999
self.stderr: io.BytesIO = BytesIOCopy(copy_to=self.output)
100100

101-
def __del__(self) -> None:
102-
"""
103-
Guarantee that embedded file-like objects are closed in a
104-
predictable order, protecting against races between
105-
self.output being closed and other streams being flushed on close
106-
107-
.. versionadded:: 8.2.2
108-
"""
109-
self.stderr.close()
110-
self.stdout.close()
111-
self.output.close()
112-
113101

114102
class _NamedTextIOWrapper(io.TextIOWrapper):
115103
def __init__(
@@ -119,6 +107,15 @@ def __init__(
119107
self._name = name
120108
self._mode = mode
121109

110+
def close(self) -> None:
111+
"""
112+
The buffer this object contains belongs to some other object, so
113+
prevent the default __del__ implementation from closing that buffer.
114+
115+
.. versionadded:: 8.3.2
116+
"""
117+
...
118+
122119
@property
123120
def name(self) -> str:
124121
return self._name

tests/test_testing_logging.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import logging
2+
3+
import click
4+
from click.testing import CliRunner
5+
6+
7+
# Minimized version of:
8+
# https://github.com/pallets/click/issues/824#issuecomment-3027263262
9+
#
10+
# Test needs to be run as "pytest --log-cli-level 30 tests/test_testing_logging.py"
11+
# to test the intended functionality.
12+
def test_runner_logger():
13+
logger = logging.getLogger(__name__)
14+
15+
@click.command()
16+
@click.option("--name", prompt="Your name", help="The person to greet.")
17+
def hello(name):
18+
logger.warning("Greeting user now...")
19+
click.echo(f"Hello, {name}!")
20+
21+
runner = CliRunner()
22+
result = runner.invoke(hello, input="Peter")
23+
assert result.exit_code == 0
24+
# FIXME: second half of the output is missing.
25+
assert result.output == "Your name: Peter\n"
26+
# assert result.output == "Your name: Peter\nHello, Peter!\n"

0 commit comments

Comments
 (0)