Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Lib/_pyio.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,7 @@ def getbuffer(self):

def close(self):
if self._buffer is not None:
self._buffer.clear()
self._buffer = bytearray()
super().close()

def read(self, size=-1):
Expand Down
27 changes: 24 additions & 3 deletions Lib/test/test_io/test_memoryio.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,9 @@ def test_getbuffer(self):
# raises a BufferError.
self.assertRaises(BufferError, memio.write, b'x' * 100)
self.assertRaises(BufferError, memio.truncate)
self.assertRaises(BufferError, memio.close)
# gh-111049: _io.BytesIO detach on close would lead to corruption.
if self.ioclass is io.BytesIO:
self.assertRaises(BufferError, memio.close)
self.assertFalse(memio.closed)
# Mutating the buffer updates the BytesIO
buf[3:6] = b"abc"
Expand All @@ -471,6 +473,23 @@ def test_getbuffer(self):
memio.close()
self.assertRaises(ValueError, memio.getbuffer)

def test_getbuffer_delete(self):
# gh-111330: _pyio .close() works and the buffer stays working
if self.ioclass is io.BytesIO:
# gh-111049: _io.BytesIO detach on close would lead to corruption.
# gh-111331: It would be nice to support this.
self.skipTest("io.BytesIO does not support, gh-111049")

memio = self.ioclass(b"1234567890")
buf = memio.getbuffer()
self.assertEqual(bytes(buf), b"1234567890")
memio.close()
self.assertTrue(memio.closed)
self.assertEqual(bytes(buf), b"1234567890")
buf[3:6] = b"abc"
self.assertEqual(bytes(buf), b"123abc7890")
self.assertRaises(ValueError, memio.getbuffer)

def test_getbuffer_empty(self):
memio = self.ioclass()
buf = memio.getbuffer()
Expand All @@ -493,9 +512,11 @@ def test_getbuffer_gc_collect(self):
# Create a reference loop.
a = [buf]
a.append(a)
# The Python implementation emits an unraisable exception.
with support.catch_unraisable_exception():

# gh-111330: _pyio GC with exports should pass.
with support.catch_unraisable_exception() as cm:
del memio
self.assertIsNone(cm.unraisable)
del buf
del a
# The C implementation emits an unraisable exception.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Update pure-Python :class:`io.BytesIO` to close cleanly when the data has an
export such as a :class:`memoryview`.
Loading