pytest-dev/pytest · error · UnsupportedOperation
cannot write to stdin
Error message
cannot write to stdin
What it means
Raised by DontReadFromInput.write() (src/_pytest/capture.py:273). Writing to stdin is semantically wrong; the redirected pseudo-file is read-only and writable() at capture.py:279 returns False. pytest raises UnsupportedOperation (lowercase 'cannot') to surface the misuse rather than silently drop data.
Solutions
- Route the write to the correct stream (sys.stdout or sys.stderr) instead of sys.stdin
- Guard with `if sys.stdin.writable():` to short-circuit on the pseudo-file
- Disable capture with -s if the write is intentional in your test harness
- try/except OSError and ignore the dropped write
Example fix
// before
sys.stdin.write('data')
// after
sys.stdout.write('data') Defensive patterns
Strategy: type-guard
Validate before calling
import sys
if not sys.stdin.writable():
raise ValueError('refusing to write to read-only stdin') Type guard
def is_writable(stream) -> bool:
try:
return stream.writable()
except Exception:
return False Try / catch
from io import UnsupportedOperation
try:
sys.stdin.write(data)
except UnsupportedOperation:
# Redirect instead
sys.stdout.write(data) Prevention
- Never write to sys.stdin - it is conceptually read-only
- Stream-multiplexing helpers should check writable() before dispatching writes
- Use sys.stdout/sys.stderr for diagnostic output
When it happens
Trigger: Calling sys.stdin.write(data) in a test while default capture is active. capture.py:273-274 raises unconditionally; writable() returns False at capture.py:279 so callers that probe first are safe.
Common situations: Misimplemented stream multiplexers, mock/patch code that writes to 'all standard streams', or test scaffolding that mistakenly writes to sys.stdin instead of sys.stdout. Less common than read/seek errors.
Related errors
- cannot truncate stdin
- Cannot write to stdin
- redirected stdin is pseudofile, has no seek(int)
- redirected stdin is pseudofile, has no tell()
- pytest: reading from stdin while output is captured! …
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/4ba3d5aac88b9b59.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/capture.py:274
pass
def readable(self) -> bool:
return False
def seek(self, offset: int, whence: int = 0) -> int:
raise UnsupportedOperation("redirected stdin is pseudofile, has no seek(int)")
def seekable(self) -> bool:
return False
def tell(self) -> int:
raise UnsupportedOperation("redirected stdin is pseudofile, has no tell()")
def truncate(self, size: int | None = None) -> int:
raise UnsupportedOperation("cannot truncate stdin")
def write(self, data: str) -> int:
raise UnsupportedOperation("cannot write to stdin")
def writelines(self, lines: Iterable[str]) -> None:
raise UnsupportedOperation("Cannot write to stdin")
def writable(self) -> bool:
return False
def __enter__(self) -> Self:
return self
def __exit__(
self,
type: type[BaseException] | None,
value: BaseException | None,
traceback: TracebackType | None,
) -> None:
pass
View on GitHub (pinned to 0d6fbdeffa)