pytest-dev/pytest · warning · UnsupportedOperation

redirected stdin is pseudofile, has no flush()

Error message

redirected stdin is pseudofile, has no flush()

What it means

DontReadFromInput.flush() raises UnsupportedOperation because the captured stdin pseudo-file is read-only and backed by an in-memory buffer; flushing it has no meaning.

Source

Thrown at src/_pytest/capture.py:250

    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()")

    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()")

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Run pytest with -s.
  2. Refactor the code to flush only stdout/stderr, not stdin.
  3. Guard the flush call with a check like getattr(stream, 'writable', lambda: True)() or skip streams where writable() is False.

Example fix

// before
# code: for s in (sys.stdin, sys.stdout, sys.stderr): s.flush()
// after
# code: for s in (sys.stdout, sys.stderr): s.flush()
Defensive patterns

Strategy: try-catch

Validate before calling

def safe_flush(stream):
    if getattr(stream, 'writable', lambda: False)():
        stream.flush()

Type guard

def is_writable(stream) -> bool:
    return bool(getattr(stream, 'writable', lambda: False)())

Try / catch

from io import UnsupportedOperation
try:
    stream.flush()
except (OSError, UnsupportedOperation, ValueError):
    pass

Prevention

When it happens

Trigger: In a test under default capture, code calls sys.stdin.flush() — often libraries that defensively flush all standard streams.

Common situations: A logging or progress-bar library that iterates sys.std{in,out,err} and calls .flush() on each; code copied from a context that mixed up stdin with stdout.

Related errors


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