RustPython/RustPython · error · UnsupportedOperation

File or stream is not readable.

Error message

File or stream is not readable.

What it means

io.UnsupportedOperation raised via IOBase._checkReadable when a read-family call (read, readline, readlines, peek, read1, readinto) hits a stream whose readable() is False - typically a file opened write-only ('w', 'a', 'x', 'wb', ...). The check runs before any syscall; note the write-only file is still created/truncated by open() itself, only the read is refused.

Source

Thrown at Lib/_pyio.py:448

    def _checkSeekable(self, msg=None):
        """Internal: raise UnsupportedOperation if file is not seekable
        """
        if not self.seekable():
            raise UnsupportedOperation("File or stream is not seekable."
                                       if msg is None else msg)

    def readable(self):
        """Return a bool indicating whether object was opened for reading.

        If False, read() will raise OSError.
        """
        return False

    def _checkReadable(self, msg=None):
        """Internal: raise UnsupportedOperation if file is not readable
        """
        if not self.readable():
            raise UnsupportedOperation("File or stream is not readable."
                                       if msg is None else msg)

    def writable(self):
        """Return a bool indicating whether object was opened for writing.

        If False, write() and truncate() will raise OSError.
        """
        return False

    def _checkWritable(self, msg=None):
        """Internal: raise UnsupportedOperation if file is not writable
        """
        if not self.writable():
            raise UnsupportedOperation("File or stream is not writable."
                                       if msg is None else msg)

    @property
    def closed(self):

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Open with a read-capable mode: 'r' to read, 'r+'/'w+' for both directions
  2. For verification, close and re-open the file in 'rb' after writing
  3. Guard reads with if f.readable(): ...

Example fix

# before
f = open(path, 'w')
f.write(data)
head = f.read(16)            # UnsupportedOperation

# after
with open(path, 'w') as f:
    f.write(data)
with open(path, 'rb') as f:
    head = f.read(16)
Defensive patterns

Strategy: validation

Validate before calling

if f.readable():
    head = f.read(16)
else:
    raise RuntimeError(f'{f!r} not opened for reading')

Type guard

def is_readable(f) -> bool:
    return bool(getattr(f, 'readable', lambda: False)())

Try / catch

import io
try:
    head = f.read(16)
except io.UnsupportedOperation:
    head = None                           # write-only stream; skip verify step

Prevention

When it happens

Trigger: open(path, 'w').read(); f = open(path, 'wb') followed by f.read(4) to 'verify' what was just written; copy-pasted read code inside a writer function; mode passed in from config as 'w' while the code assumes 'r+'.

Common situations: Write-then-verify patterns that should re-open in read mode; mixed read/write code where the mode was meant to be 'r+'/'w+'; test harnesses reusing a single open() for both directions.

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/e1a237ac4b7dfe28. Report an issue: GitHub.