RustPython/RustPython · error · UnsupportedOperation
File or stream is not seekable.
Error message
File or stream is not seekable.
What it means
io.UnsupportedOperation raised through IOBase._checkSeekable when a positioning operation (seek, tell, truncate) is attempted on a stream whose seekable() returns False. Seekability is a property of the underlying channel - pipes, sockets, and some wrapped streams are not seekable, while regular files and BytesIO are. The optional msg parameter lets subclasses customize the text; the default message is shown here.
Source
Thrown at Lib/_pyio.py:434
# If close() fails, the caller logs the exception with
# sys.unraisablehook. close() must be called at the end at __del__().
self.close()
### Inquiries ###
def seekable(self):
"""Return a bool indicating whether object supports random access.
If False, seek(), tell() and truncate() will raise OSError.
This method may need to do a test seek().
"""
return False
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.View on GitHub (pinned to aaeab4f754)
Solutions
- Branch on the capability: if f.seekable(): f.seek(0) else re-read from the source
- Buffer the stream first: data = f.read(), then work on io.BytesIO(data), which is seekable
- For sockets/pipes, design a streaming parse that never rewinds
Example fix
# before f.seek(0) # dies when f is a pipe header = f.read(16) # after from io import BytesIO data = f.read() buf = BytesIO(data) # seekable in-memory copy header = buf.read(16)
Defensive patterns
Strategy: validation
Validate before calling
if f.seekable():
f.seek(0)
header = f.read(16)
else: # pipe/socket: buffer it instead
data = f.read()
header = data[:16] Type guard
def is_seekable(f) -> bool:
return bool(getattr(f, 'seekable', lambda: False)()) Try / catch
import io
try:
f.seek(0)
except io.UnsupportedOperation:
data = f.read() # stream once, buffer locally Prevention
- Branch on f.seekable() before seek/tell/truncate
- Design parsers to stream forward-only when the source may be a pipe
- Wrap non-seekable sources in BytesIO when re-reads are needed
When it happens
Trigger: f.seek(0) on sys.stdin/sys.stdout when they are pipes; seek()/tell() on a socket file object from sock.makefile(); seeking a subprocess stdout pipe; a custom stream subclass that left seekable() returning the IOBase default False.
Common situations: Code tested against real files but run with piped stdin (curl ... | script); seek(0) to rewind for a second parse pass; serialization helpers that tell() to record offsets; multipart parsers that need lookahead.
Related errors
- %s.%s() not supported
- File or stream is not readable.
- File or stream is not writable.
- Unexpected node inside JoinedStr, {node!r}
- seek() returned an invalid position
AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17).
Data as JSON: /api/errors/737e567a6cac1515.
Report an issue: GitHub.