{"record":{"id":"20cf499037fb0b24","repo":"RustPython/RustPython","slug":"getbuffer-on-closed-file","errorCode":null,"errorMessage":"getbuffer on closed file","messagePattern":"getbuffer on closed file","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_pyio.py","lineNumber":907,"sourceCode":"        self._pos = 0\n\n    def __getstate__(self):\n        if self.closed:\n            raise ValueError(\"__getstate__ on closed file\")\n        return self.__dict__.copy()\n\n    def getvalue(self):\n        \"\"\"Return the bytes value (contents) of the buffer\n        \"\"\"\n        if self.closed:\n            raise ValueError(\"getvalue on closed file\")\n        return bytes(self._buffer)\n\n    def getbuffer(self):\n        \"\"\"Return a readable and writable view of the buffer.\n        \"\"\"\n        if self.closed:\n            raise ValueError(\"getbuffer on closed file\")\n        return memoryview(self._buffer)\n\n    def close(self):\n        if self._buffer is not None:\n            self._buffer.clear()\n        super().close()\n\n    def read(self, size=-1):\n        if self.closed:\n            raise ValueError(\"read from closed file\")\n        if size is None:\n            size = -1\n        else:\n            try:\n                size_index = size.__index__\n            except AttributeError:\n                raise TypeError(f\"{size!r} is not an integer\")\n            else:","sourceCodeStart":889,"sourceCodeEnd":925,"githubUrl":"https://github.com/RustPython/RustPython/blob/aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd/Lib/_pyio.py#L889-L925","documentation":"BytesIO.getbuffer (Lib/_pyio.py:907) raises ValueError('getbuffer on closed file') when called after close(). The method returns a writable memoryview over the internal bytearray; once close() has cleared that bytearray the view is impossible to produce, so the guard fires instead of returning an empty view. Unlike getvalue(), a successfully obtained buffer is also invalidated once the BytesIO closes.","triggerScenarios":"buf.close() followed by buf.getbuffer(); taking the memoryview inside a with-block but dereferencing/slicing it after exit; resize helpers that grab getbuffer() after cleanup closed the buffer.","commonSituations":"Zero-copy handoff of in-memory payloads to numpy or C extensions; slicing the buffer view in later processing stages after the owning BytesIO was closed; test teardown closing fixtures while views are still used.","solutions":["Obtain the memoryview while the BytesIO is open and finish using it before close()","If you only need the bytes, use getvalue() before closing and keep the bytes object","Don't close the BytesIO while any memoryview from getbuffer() is still alive"],"exampleFix":"// before\nbuf = io.BytesIO(b\"abc\")\nbuf.close()\nview = buf.getbuffer()  # ValueError: getbuffer on closed file\n\n// after\nbuf = io.BytesIO(b\"abc\")\nview = buf.getbuffer()\ndata = bytes(view)  # consume while open\nbuf.close()","handlingStrategy":"validation","validationCode":"view = buf.getbuffer() if not buf.closed else memoryview(b\"\")","typeGuard":null,"tryCatchPattern":"try:\n    view = buf.getbuffer()\nexcept ValueError as e:\n    if \"getbuffer on closed file\" in str(e):\n        view = memoryview(b\"\")\n    else:\n        raise","preventionTips":["Take the memoryview while the BytesIO is open and release it before close","Don't hold getbuffer() views across a later close of the owning buffer","Snapshot with bytes(view) if the view must outlive the buffer"],"tags":["python","io","bytesio","getbuffer","memoryview","closed-file"],"backgroundTag":"io-operation-on-closed-file","analyzedSha":"aaeab4f754b4f40efc0c8ab39cf7c4a3c35a8cfd","analyzedAt":"2026-08-17T00:37:52.100Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}