{"record":{"id":"eb8d59767217958e","repo":"Textualize/rich","slug":"writelines","errorCode":null,"errorMessage":"writelines","messagePattern":"writelines","errorType":"exception","errorClass":"UnsupportedOperation","httpStatus":null,"severity":"error","filePath":"rich/progress.py","lineNumber":282,"sourceCode":"\n    def close(self) -> None:\n        if self.close_handle:\n            self.handle.close()\n        self._closed = True\n\n    def seek(self, offset: int, whence: int = 0) -> int:\n        pos = self.handle.seek(offset, whence)\n        self.progress.update(self.task, completed=pos)\n        return pos\n\n    def tell(self) -> int:\n        return self.handle.tell()\n\n    def write(self, s: Any) -> int:\n        raise UnsupportedOperation(\"write\")\n\n    def writelines(self, lines: Iterable[Any]) -> None:\n        raise UnsupportedOperation(\"writelines\")\n\n\nclass _ReadContext(ContextManager[_I], Generic[_I]):\n    \"\"\"A utility class to handle a context for both a reader and a progress.\"\"\"\n\n    def __init__(self, progress: \"Progress\", reader: _I) -> None:\n        self.progress = progress\n        self.reader: _I = reader\n\n    def __enter__(self) -> _I:\n        self.progress.start()\n        return self.reader.__enter__()\n\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_val: Optional[BaseException],\n        exc_tb: Optional[TracebackType],","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/Textualize/rich/blob/9d8f9a372cc5916fd4781fec207ced7ddac2f08f/rich/progress.py#L264-L300","documentation":"The _Reader object returned by Progress.wrap_file() is a read-only progress-tracking file wrapper. .writelines() is explicitly stubbed to raise io.UnsupportedOperation('writelines') because the class only supports read operations that advance the progress bar; it is not a writable stream.","triggerScenarios":"Calling wrapped.writelines(lines) on the return value of Progress.wrap_file(...) or Progress.open(...). Commonly hit when the wrapper is passed to a generic serialization routine (csv.writer(...).writerows on a wrapped handle, json.dump into the wrapper) that calls writelines internally.","commonSituations":"Using Progress.open() while building an output file with a library that writes via writelines; confusing the download-progress wrapper for a read/write stream; copying code that used open() directly into a Progress.open() context.","solutions":["Perform writelines on the underlying raw file object; use the wrapper only for reads.","For write progress, wrap manually: open the file normally, write, then progress.update(task, completed=f.tell()) after each chunk.","Verify the direction of your transfer: wrap_file/Progress.open are for reading (downloads); there is no built-in write wrapper in this API."],"exampleFix":"# before\nwith progress.open('out.txt', 'rb', total=n) as p:\n    p.writelines(lines)  # UnsupportedOperation\n\n# after\nwith open('out.txt', 'wb') as f:\n    f.writelines(lines)\n    progress.update(task, completed=f.tell())","handlingStrategy":"type-guard","validationCode":"# writelines only on real writable streams\nimport io\nassert isinstance(f, io.IOBase) and f.writable(), 'need a writable raw handle'","typeGuard":"def is_writable_stream(obj: object) -> bool:\n    return isinstance(obj, io.IOBase) and not isinstance(getattr(obj, 'handle', obj), type(None)) and getattr(obj, 'writable', lambda: False)()","tryCatchPattern":null,"preventionTips":["Never pass rich _Reader wrappers as the destination of writelines/copyfileobj.","Write to the raw file object; update the progress bar manually."],"tags":["rich","io","progress","read-only","unsupported-operation"],"backgroundTag":null,"analyzedSha":"9d8f9a372cc5916fd4781fec207ced7ddac2f08f","analyzedAt":"2026-08-15T03:30:11.781Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}