prompt-toolkit / prompt-toolkit/python-prompt-toolkit
Incompatibility with pytest capsys
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 10.6k
- Forks
- 815
- PR merge metrics
- No merged PRs in 30d
Description
Hi,
Here is something i have noticed while testing the project i manage.
Sounds like print_formatted_text and capsys does not interoperate together.
Do you have any idea how to deal with that problem?
Does it make sense to patch one or the other project?
Test
from prompt_toolkit import print_formatted_text
def test_1(capsys):
print_formatted_text("1")
def test_2(capsys):
print_formatted_text("2")
Result
test_pt.py::test_1 PASSED [ 50%]
test_pt.py::test_2 FAILED [100%]
========================================================================== FAILURES ==========================================================================
___________________________________________________________________________ test_2 ___________________________________________________________________________
capsys = <_pytest.capture.CaptureFixture object at 0x7fbc1f55df10>
def test_2(capsys):
> print_formatted_text("2")
test_pt.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../Software/miniconda3/envs/blissdev/lib/python3.9/site-packages/prompt_toolkit/shortcuts/utils.py:163: in print_formatted_text
render()
../../Software/miniconda3/envs/blissdev/lib/python3.9/site-packages/prompt_toolkit/shortcuts/utils.py:138: in render
renderer_print_formatted_text(
../../Software/miniconda3/envs/blissdev/lib/python3.9/site-packages/prompt_toolkit/renderer.py:813: in print_formatted_text
output.flush()
../../Software/miniconda3/envs/blissdev/lib/python3.9/site-packages/prompt_toolkit/output/plain_text.py:57: in flush
flush_stdout(self.stdout, data)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
stdout = <_io.TextIOWrapper encoding='UTF-8'>, data = '2\r\n'
def flush_stdout(stdout: TextIO, data: str) -> None:
# If the IO object has an `encoding` and `buffer` attribute, it means that
# we can access the underlying BinaryIO object and write into it in binary
# mode. This is preferred if possible.
# NOTE: When used in a Jupyter notebook, don't write binary.
# `ipykernel.iostream.OutStream` has an `encoding` attribute, but not
# a `buffer` attribute, so we can't write binary in it.
has_binary_io = hasattr(stdout, "encoding") and hasattr(stdout, "buffer")
try:
# Ensure that `stdout` is made blocking when writing into it.
# Otherwise, when uvloop is activated (which makes stdout
# non-blocking), and we write big amounts of text, then we get a
# `BlockingIOError` here.
with _blocking_io(stdout):
# (We try to encode ourself, because that way we can replace
# characters that don't exist in the character set, avoiding
# UnicodeEncodeError crashes. E.g. u'\xb7' does not appear in 'ascii'.)
# My Arch Linux installation of july 2015 reported 'ANSI_X3.4-1968'
# for sys.stdout.encoding in xterm.
out: IO[bytes]
if has_binary_io:
> stdout.buffer.write(data.encode(stdout.encoding or "utf-8", "replace"))
E ValueError: I/O operation on closed file.
../../Software/miniconda3/envs/blissdev/lib/python3.9/site-packages/prompt_toolkit/output/flush_stdout.py:32: ValueError
================================================================== short test summary info ===================================================================
FAILED test_pt.py::test_2 - ValueError: I/O operation on closed file.
My env
pytest 7.2.0
pytest-cov 4.0.0
pytest-mock 3.10.0
pytest-profiling 1.7.0
pytest-redis 3.0.2
pytest-rerunfailures 10.3
pytest-xvfb 2.0.0
prompt-toolkit 3.0.33
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the two-test reproducer with pytest and capsys, then trace the failure through shortcuts/utils.py, renderer.py, output/plain_text.py, and output/flush_stdout.py. Done means both tests pass without the I/O operation on closed file error while preserving the reported print_formatted_text behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100