pytest-dev/pytest · error · OSError
pytest: reading from stdin while output is captured! Consid
Error message
pytest: reading from stdin while output is captured! Consider using `-s`.
What it means
DontReadFromInput.read raises OSError because pytest replaces sys.stdin with a pseudo-file while output capturing is active (default). Reading from stdin in a test would hang waiting for input that never comes, so pytest forbids it.
Source
Thrown at src/_pytest/capture.py:229
class TeeCaptureIO(CaptureIO):
def __init__(self, other: TextIO) -> None:
self._other = other
super().__init__()
def write(self, s: str) -> int:
super().write(s)
return self._other.write(s)
class DontReadFromInput(TextIO):
@property
def encoding(self) -> str:
assert sys.__stdin__ is not None
return sys.__stdin__.encoding
def read(self, size: int = -1) -> str:
raise OSError(
"pytest: reading from stdin while output is captured! Consider using `-s`."
)
readline = read
def __next__(self) -> str:
return self.readline()
def readlines(self, hint: int | None = -1) -> list[str]:
raise OSError(
"pytest: reading from stdin while output is captured! Consider using `-s`."
)
def __iter__(self) -> Iterator[str]:
return self
def fileno(self) -> int:
raise UnsupportedOperation("redirected stdin is pseudofile, has no fileno()")View on GitHub (pinned to 98b357f69e)
Solutions
- Run pytest with -s (or --capture=no) to disable stdin replacement so real stdin is used.
- Refactor the code under test to accept input via a parameter or an injected file object instead of reading stdin directly.
- Use monkeypatch.setattr('sys.stdin', io.StringIO('data')) to feed deterministic input.
- Use the capsys/capfd monkeypatching patterns or pytest's monkeypatch to inject a fake stdin.
Example fix
// before
# test calls code that does: data = sys.stdin.read()
// after
$ pytest -s
# or in the test:
monkeypatch.setattr('sys.stdin', io.StringIO('hello')) Defensive patterns
Strategy: validation
Validate before calling
import sys
def safe_read_stdin():
if not sys.stdin.isatty() and 'DontReadFromInput' in type(sys.stdin).__name__:
raise RuntimeError('stdin is captured; run pytest with -s or inject input')
return sys.stdin.read() Type guard
def is_captured_stdin(stream) -> bool:
return type(stream).__name__ == 'DontReadFromInput' Try / catch
try:
data = sys.stdin.read()
except OSError as e:
if 'reading from stdin' in str(e):
# fall back: no input available under capture
data = ''
else:
raise Prevention
- Inject input via monkeypatch.setattr('sys.stdin', io.StringIO(...)) in tests rather than reading real stdin.
- Run pytest with -s for any test that legitimately needs interactive stdin.
- Refactor production code to accept an input stream as a parameter.
When it happens
Trigger: In a test (or fixture) under default capture mode, call sys.stdin.read() or input() (which uses stdin.readline). The DontReadFromInput proxy raises OSError.
Common situations: Code under test calls input() to prompt a user; a CLI function reads stdin unconditionally; a library probes sys.stdin.read() at import time.
Related errors
- redirected stdin is pseudofile, has no fileno()
- redirected stdin is pseudofile, has no flush()
- redirected stdin is pseudofile, has no seek(int)
- redirected stdin is pseudofile, has no tell()
- cannot truncate stdin
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/e4a93de36eaa66d5.json.
Report an issue: GitHub.