pytest-dev/pytest · error · UnsupportedOperation
cannot truncate stdin
Error message
cannot truncate stdin
What it means
Raised by DontReadFromInput.truncate() (src/_pytest/capture.py:270). truncate() is rejected because the pseudo-file backing redirected stdin is read-only and not size-addressable; pytest raises UnsupportedOperation rather than silently no-op. writable() returns False to advertise.
Solutions
- Guard the call: only truncate() on objects whose writable() returns True
- Disable capture with -s so sys.stdin is the real stream
- try/except OSError around the truncate call
- Stop the capture fixture (capsys.stop()) before calling truncate
Example fix
// before
sys.stdin.truncate(0)
// after
if sys.stdin.writable():
sys.stdin.truncate(0) Defensive patterns
Strategy: try-catch
Validate before calling
import sys
if not sys.stdin.writable():
pass Type guard
def can_truncate(stream) -> bool:
try:
return stream.writable()
except Exception:
return False Try / catch
try:
sys.stdin.truncate(size)
except OSError:
pass Prevention
- Guard truncate() with writable() to skip read-only pseudo-files
- Avoid calling truncate() on stdin in any code path - it is rarely meaningful
- Use capsys.stop()/capfd.stop() around code that legitimately needs to mutate stdin
When it happens
Trigger: Invoking sys.stdin.truncate([size]) while capture is on. capture.py:270-271 raises unconditionally with no probe method (truncate has no standard boolean predicate), so the call must be wrapped.
Common situations: Edge case from stream-rewriting helpers, mock libraries that walk file objects, or io.MultiFile-style code that calls truncate() defensively on every handle including stdin.
Related errors
- cannot write to 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/a695831d067973a2.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/capture.py:271
return False
def close(self) -> None:
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,View on GitHub (pinned to 0d6fbdeffa)