`redirected stdin is pseudofile, has no fileno()`
paw-lu opened this issue · 3 comments
When trying to test this libary via pytest, an exception is raised: redirected stdin is pseudofile, has no fileno()
. This is due to this line:
terminedia/terminedia/terminal.py
Line 92 in 96f44a6
Minimal reproducible
"""script.py"""
import io
import terminedia
from PIL import Image
def foo():
pil_image = Image.open("image_file.jpeg")
size = terminedia.V2(x=60, y=30)
shape = terminedia.shape(
pil_image,
size=size,
promote=True,
resolution="square",
)
output = io.StringIO()
shape.render(output=output, backend="ANSI")
"""Test script.py"""
import script
def test_foo():
assert script.foo() is None
$ pytest
platform darwin -- Python 3.9.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /Users/pawlu/Documents/scratch/pedia
collected 1 item
test_debug.py F [100%]
======================================================== FAILURES ========================================================
_______________________________________________________ test_doit ________________________________________________________
def test_doit():
> assert draw_debug.doti() is None
test_debug.py:4:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
draw_debug.py:76: in doti
shape.render(output=output, backend="ANSI")
.venv/lib/python3.9/site-packages/terminedia/image.py:645: in render
self._render_using_screen(output, backend)
.venv/lib/python3.9/site-packages/terminedia/image.py:687: in _render_using_screen
sc.commands.replay(output)
.venv/lib/python3.9/site-packages/terminedia/backend_common.py:217: in replay
func(arg, file=file)
.venv/lib/python3.9/site-packages/terminedia/backend_common.py:256: in set_fg_color
super().set_fg_color(color, file=file)
.venv/lib/python3.9/site-packages/terminedia/terminal.py:474: in set_fg_color
self.SGR(38, 2, *Color(color), file=file)
.venv/lib/python3.9/site-packages/terminedia/terminal.py:304: in SGR
self.CSI(*args, "m", file=file)
.venv/lib/python3.9/site-packages/terminedia/terminal.py:293: in CSI
self._print("\x1b[", args, command, file=file)
.venv/lib/python3.9/site-packages/terminedia/terminal.py:157: in _print
with UnblockTTY():
.venv/lib/python3.9/site-packages/terminedia/terminal.py:92: in __enter__
self.fd = sys.stdin.fileno()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_pytest.capture.DontReadFromInput object at 0x10b29e670>
def fileno(self) -> int:
> raise UnsupportedOperation("redirected stdin is pseudofile, has no fileno()")
E io.UnsupportedOperation: redirected stdin is pseudofile, has no fileno()
.venv/lib/python3.9/site-packages/_pytest/capture.py:229: UnsupportedOperation
================================================ short test summary info =================================================
FAILED test_debug.py::test_doit - io.UnsupportedOperation: redirected stdin is pseudofile, has no fileno()
=================================================== 1 failed in 0.51s ====================================================
Thank you for the feedback.
Please, for teh time being use the -s
switch in pytest, which avoids this redirection.
If you notice pytest output, it also extends it with the --DISPLAY
and --DELAY
options: some of the tests do make use of the library itself for a visual on screen output which is displayed with these options.
Please, for teh time being use the -s switch in pytest, which avoids this redirection.
Got it!
In my case I wanted to keep Pytest's capture functionality, and not diable it globally, so I ended up using this pytest fixture to temporarity disable pytest's capturing.
Leaving it here in case it's useful for others.
import pytest
from _pytest.config import _PluggyPlugin
from _pytest.config import Config
@pytest.fixture
def disable_capture(pytestconfig: Config) -> ContextManager[_PluggyPlugin]:
"""Disable pytest's capture."""
# https://github.com/pytest-dev/pytest/issues/
# 1599?utm_source=pocket_mylist#issuecomment-556327594
@contextlib.contextmanager
def _disable_capture() -> Iterator[_PluggyPlugin]:
"""Disable pytest's capture."""
capmanager = pytestconfig.pluginmanager.getplugin("capturemanager")
try:
capmanager.suspend_global_capture(in_=True)
yield capmanager
finally:
capmanager.resume_global_capture()
return _disable_capture()