pytest-dev/pytest · warning · UnsupportedOperation

redirected stdin is pseudofile, has no seek(int)

Error message

redirected stdin is pseudofile, has no seek(int)

What it means

DontReadFromInput.seek() raises UnsupportedOperation because the captured stdin pseudo-file is a sequential in-memory stream that does not support repositioning. seekable() already returns False.

Source

Thrown at src/_pytest/capture.py:262

        return self

    def fileno(self) -> int:
        raise UnsupportedOperation("redirected stdin is pseudofile, has no fileno()")

    def flush(self) -> None:
        raise UnsupportedOperation("redirected stdin is pseudofile, has no flush()")

    def isatty(self) -> bool:
        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

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Run pytest with -s.
  2. Refactor code to buffer the input itself rather than seeking stdin.
  3. Guard seek calls with a seekable() check before invoking seek.

Example fix

// before
# code: sys.stdin.seek(0)
// after
# code: data = sys.stdin.read()  # buffer once, reparse in memory
#       or check: if sys.stdin.seekable(): sys.stdin.seek(0)
Defensive patterns

Strategy: type-guard

Validate before calling

def safe_seek(stream, offset, whence=0):
    if not getattr(stream, 'seekable', lambda: False)():
        raise UnsupportedOperation('stream is not seekable')
    return stream.seek(offset, whence)

Type guard

def is_seekable(stream) -> bool:
    return bool(getattr(stream, 'seekable', lambda: False)())

Try / catch

from io import UnsupportedOperation
try:
    stream.seek(0)
except (OSError, UnsupportedOperation, ValueError):
    pass  # consume fresh data instead

Prevention

When it happens

Trigger: In a test under default capture, code calls sys.stdin.seek(offset) — typical of parsers that try to rewind a stream.

Common situations: A parser/decoder that rewinds stdin on a lookahead; generic stream-handling utilities that call seek/tell on any file-like object; replay logic that assumes random access.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/419b1850df40473b.json. Report an issue: GitHub.