https://github.com/python/cpython/commit/13aa41f4e253f23c8a2adb5565996cc9227d596e
commit: 13aa41f4e253f23c8a2adb5565996cc9227d596e
branch: main
author: Vyron Vasileiadis <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-16T10:51:56+03:00
summary:
gh-155389: Return bytes from _pyio.BytesIO.peek() (GH-155390)
peek() returned a slice of the internal bytearray, where read() converts with
take_bytes(). It also did not coerce its size through __index__ and did not
hold the lock while slicing, both of which read() and the C implementation do.
files:
M Lib/_pyio.py
M Lib/test/test_io/test_memoryio.py
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index ac301180d284fa9..cf4ef04f37d26cc 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -1003,9 +1003,19 @@ def tell(self):
def peek(self, size=0):
if self.closed:
raise ValueError("peek on closed file")
+ try:
+ size_index = size.__index__
+ except AttributeError:
+ raise TypeError(f"{size!r} is not an integer")
+ else:
+ size = size_index()
+
if size < 1:
- return self._buffer[self._pos:self._pos + io.DEFAULT_BUFFER_SIZE]
- return self._buffer[self._pos:self._pos + size]
+ size = io.DEFAULT_BUFFER_SIZE
+
+ with self._lock:
+ b = self._buffer[self._pos:self._pos + size]
+ return b.take_bytes()
def truncate(self, pos=None):
if self.closed:
diff --git a/Lib/test/test_io/test_memoryio.py
b/Lib/test/test_io/test_memoryio.py
index 0037fdc2fd67c1a..e934e3fb2bdf124 100644
--- a/Lib/test/test_io/test_memoryio.py
+++ b/Lib/test/test_io/test_memoryio.py
@@ -596,6 +596,11 @@ def test_peek(self):
buf = self.buftype("1234567890")
with self.ioclass(buf) as memio:
self.assertEqual(memio.tell(), 0)
+ # bytearray(b'1') == b'1', so the type has to be asserted
separately.
+ self.assertIsInstance(memio.peek(), bytes)
+ self.assertIsInstance(memio.peek(1), bytes)
+ self.assertEqual(memio.peek(IntLike(3)), buf[:3])
+ self.assertRaises(TypeError, memio.peek, 1.5)
self.assertEqual(memio.peek(1), buf[:1])
self.assertEqual(memio.peek(1), buf[:1])
self.assertEqual(memio.peek(), buf)
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]