]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-129005: Avoid copy in _pyio.FileIO.readinto() (#129324)
authorCody Maloney <cmaloney@users.noreply.github.com>
Tue, 28 Jan 2025 11:40:44 +0000 (03:40 -0800)
committerGitHub <noreply@github.com>
Tue, 28 Jan 2025 11:40:44 +0000 (12:40 +0100)
`os.read()` allocated and filled a buffer by calling `read(2)`, than that
data was copied into the user provied buffer. Read directly into the
caller's buffer instead by using `os.readinto()`.

`os.readinto()` uses `PyObject_GetBuffer()` to make sure the passed
in buffer is writeable and bytes-like, drop the manual check.

Lib/_pyio.py
Misc/NEWS.d/next/Library/2025-01-26-10-01-21.gh-issue-129005.ncpLvw.rst [new file with mode: 0644]

index 14961c39d3541d743cb795185b36ffd8cc2c2e16..023478aa78c6a04b2320f3a360fe1be9e020bf6d 100644 (file)
@@ -1692,13 +1692,14 @@ class FileIO(RawIOBase):
 
         return bytes(result)
 
-    def readinto(self, b):
+    def readinto(self, buffer):
         """Same as RawIOBase.readinto()."""
-        m = memoryview(b).cast('B')
-        data = self.read(len(m))
-        n = len(data)
-        m[:n] = data
-        return n
+        self._checkClosed()
+        self._checkReadable()
+        try:
+            return os.readinto(self._fd, buffer)
+        except BlockingIOError:
+            return None
 
     def write(self, b):
         """Write bytes b to file, return number written.
diff --git a/Misc/NEWS.d/next/Library/2025-01-26-10-01-21.gh-issue-129005.ncpLvw.rst b/Misc/NEWS.d/next/Library/2025-01-26-10-01-21.gh-issue-129005.ncpLvw.rst
new file mode 100644 (file)
index 0000000..a825e9d
--- /dev/null
@@ -0,0 +1 @@
+Optimize ``_pyio.FileIO.readinto`` by avoiding unnecessary objects and copies using :func:`os.readinto`.