https://github.com/python/cpython/commit/510ab7d6e1284dd2ac453b780fa19b5627bca0e1
commit: 510ab7d6e1284dd2ac453b780fa19b5627bca0e1
branch: main
author: Cody Maloney <[email protected]>
committer: vstinner <[email protected]>
date: 2026-01-13T10:33:26+01:00
summary:

gh-132108: Add Buffer Protocol support to int.from_bytes to improve performance 
(#132109)

Speed up conversion from `bytes-like` objects like `bytearray` while
keeping conversion from `bytes` stable.

Co-authored-by: Sergey B Kirpichev <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst
M Objects/longobject.c

diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst
new file mode 100644
index 00000000000000..8c2d947954c5bb
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-04-20-38-29.gh-issue-132108.UwZIQy.rst
@@ -0,0 +1,2 @@
+Speed up :meth:`int.from_bytes` when passed object supports :ref:`buffer
+protocol <bufferobjects>`, like :class:`bytearray` by ~1.2x.
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 8ba1fd65078f48..74958cb8b9bbb0 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -6476,14 +6476,33 @@ int_from_bytes_impl(PyTypeObject *type, PyObject 
*bytes_obj,
         return NULL;
     }
 
-    bytes = PyObject_Bytes(bytes_obj);
-    if (bytes == NULL)
-        return NULL;
-
-    long_obj = _PyLong_FromByteArray(
-        (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes),
-        little_endian, is_signed);
-    Py_DECREF(bytes);
+    /* Fast-path exact bytes. */
+    if (PyBytes_CheckExact(bytes_obj)) {
+        long_obj = _PyLong_FromByteArray(
+            (unsigned char *)PyBytes_AS_STRING(bytes_obj), Py_SIZE(bytes_obj),
+            little_endian, is_signed);
+    }
+    /* Use buffer protocol to avoid copies. */
+    else if (PyObject_CheckBuffer(bytes_obj)) {
+        Py_buffer view;
+        if (PyObject_GetBuffer(bytes_obj, &view, PyBUF_SIMPLE) != 0) {
+            return NULL;
+        }
+        long_obj = _PyLong_FromByteArray(view.buf, view.len, little_endian,
+            is_signed);
+        PyBuffer_Release(&view);
+    }
+    else {
+        /* fallback: Construct a bytes then convert. */
+        bytes = PyObject_Bytes(bytes_obj);
+        if (bytes == NULL) {
+            return NULL;
+        }
+        long_obj = _PyLong_FromByteArray(
+            (unsigned char *)PyBytes_AS_STRING(bytes), Py_SIZE(bytes),
+            little_endian, is_signed);
+        Py_DECREF(bytes);
+    }
 
     if (long_obj != NULL && type != &PyLong_Type) {
         Py_SETREF(long_obj, PyObject_CallOneArg((PyObject *)type, long_obj));

_______________________________________________
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]

Reply via email to