https://github.com/python/cpython/commit/decb25e8f0051cafcbe7d38171371cf47185165b
commit: decb25e8f0051cafcbe7d38171371cf47185165b
branch: main
author: Priyanshu Singh <[email protected]>
committer: vstinner <[email protected]>
date: 2026-01-26T13:13:49+01:00
summary:

gh-144128: Fix crash in array.fromlist with reentrant __index__ (#144138)

Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Peter Bierma <[email protected]>
Co-authored-by: Victor Stinner <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst
M Lib/test/test_array.py
M Modules/arraymodule.c

diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index 83b3c978da3581..b49df029f0326f 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -67,6 +67,23 @@ def test_empty(self):
         a += a
         self.assertEqual(len(a), 0)
 
+    def test_fromlist_reentrant_index_mutation(self):
+
+        class Evil:
+            def __init__(self, lst):
+                self.lst = lst
+            def __index__(self):
+                self.lst.clear()
+                return "not an int"
+
+        for typecode in ('I', 'L', 'Q'):
+            with self.subTest(typecode=typecode):
+                lst = []
+                lst.append(Evil(lst))
+                a = array.array(typecode)
+                with self.assertRaises(TypeError):
+                    a.fromlist(lst)
+
 
 # Machine format codes.
 #
diff --git 
a/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst 
b/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst
new file mode 100644
index 00000000000000..4010695aec980d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-01-22-10-18-17.gh-issue-144128.akwY06.rst
@@ -0,0 +1,2 @@
+Fix a crash in :meth:`array.array.fromlist` when an element's 
:meth:`~object.__index__` method mutates
+the input list during conversion.
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 729e085c19f006..5769a796b18902 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -408,10 +408,13 @@ II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     int do_decref = 0; /* if nb_int was called */
 
     if (!PyLong_Check(v)) {
-        v = _PyNumber_Index(v);
-        if (NULL == v) {
+        Py_INCREF(v);
+        PyObject *res = _PyNumber_Index(v);
+        Py_DECREF(v);
+        if (NULL == res) {
             return -1;
         }
+        v = res;
         do_decref = 1;
     }
     x = PyLong_AsUnsignedLong(v);
@@ -468,10 +471,13 @@ LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     int do_decref = 0; /* if nb_int was called */
 
     if (!PyLong_Check(v)) {
-        v = _PyNumber_Index(v);
-        if (NULL == v) {
+        Py_INCREF(v);
+        PyObject *res = _PyNumber_Index(v);
+        Py_DECREF(v);
+        if (NULL == res) {
             return -1;
         }
+        v = res;
         do_decref = 1;
     }
     x = PyLong_AsUnsignedLong(v);
@@ -521,10 +527,13 @@ QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
     int do_decref = 0; /* if nb_int was called */
 
     if (!PyLong_Check(v)) {
-        v = _PyNumber_Index(v);
-        if (NULL == v) {
+        Py_INCREF(v);
+        PyObject *res = _PyNumber_Index(v);
+        Py_DECREF(v);
+        if (NULL == res) {
             return -1;
         }
+        v = res;
         do_decref = 1;
     }
     x = PyLong_AsUnsignedLongLong(v);

_______________________________________________
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