pytest-dev/pytest · warning · UnsupportedOperation

redirected stdin is pseudofile, has no tell()

Error message

redirected stdin is pseudofile, has no tell()

What it means

DontReadFromInput.tell() raises UnsupportedOperation because the captured stdin pseudo-file does not track a meaningful position. seekable()/readable() both return False.

Source

Thrown at src/_pytest/capture.py:268

        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

    def __enter__(self) -> Self:
        return self

    def __exit__(
        self,

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Run pytest with -s.
  2. Refactor to read the whole stream into a buffer and track position yourself.
  3. Guard tell() with a seekable() check.

Example fix

// before
# code: pos = sys.stdin.tell()
// after
# code: data = sys.stdin.read()  # manage offset in your own buffer
Defensive patterns

Strategy: type-guard

Validate before calling

def safe_tell(stream):
    if not getattr(stream, 'seekable', lambda: False)():
        raise UnsupportedOperation('stream does not support tell')
    return stream.tell()

Type guard

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

Try / catch

from io import UnsupportedOperation
try:
    pos = stream.tell()
except (OSError, UnsupportedOperation, ValueError):
    pos = -1

Prevention

When it happens

Trigger: In a test under default capture, code calls sys.stdin.tell() — usually paired with seek for save/restore of stream position.

Common situations: Stream utilities that record position before parsing to restore later; logging libraries that report positions; copy-pasted file-handling code that treats stdin like a regular file.

Related errors


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