https://github.com/python/cpython/commit/c0bc6fad254479629bbe5cf523a69263cbd28d49
commit: c0bc6fad254479629bbe5cf523a69263cbd28d49
branch: main
author: Sergey B Kirpichev <[email protected]>
committer: vstinner <[email protected]>
date: 2026-09-18T17:16:57+02:00
summary:

gh-156865: Correctly detect overflows for array's "e", "f" and "Zf" type codes 
(#156869)

files:
A Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.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 c931be6df5fdaa..ba9c25c835bc39 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -1607,10 +1607,19 @@ class HalfFloatTest(FPTest, unittest.TestCase):
     typecode = 'e'
     minitemsize = 2
 
+    def test_overflows(self):
+        # Overflows half-float type:
+        self.assertRaises(OverflowError, array.array, self.typecode, [123456])
+        # Overflows also float type:
+        self.assertRaises(OverflowError, array.array, self.typecode, [1e300])
+
 class FloatTest(FPTest, unittest.TestCase):
     typecode = 'f'
     minitemsize = 4
 
+    def test_overflows(self):
+        self.assertRaises(OverflowError, array.array, self.typecode, [1e300])
+
 class DoubleTest(FPTest, unittest.TestCase):
     typecode = 'd'
     minitemsize = 8
@@ -1637,6 +1646,10 @@ class ComplexFloatTest(CFPTest, unittest.TestCase):
     typecode = 'Zf'
     minitemsize = 8
 
+    def test_overflows(self):
+        self.assertRaises(OverflowError, array.array, self.typecode, [1e300])
+        self.assertRaises(OverflowError, array.array, self.typecode, [1e300j])
+
 class ComplexDoubleTest(CFPTest, unittest.TestCase):
     typecode = 'Zd'
     minitemsize = 16
diff --git 
a/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst 
b/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst
new file mode 100644
index 00000000000000..ee89b830d3d486
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-09-03-04-51-46.gh-issue-156864.Pbe7Tl.rst
@@ -0,0 +1,2 @@
+:func:`array.array` setter now correctly detects overflows for the ``'e'``,
+``'f'`` and ``'Zf'`` type codes.  Patch by Sergey B Kirpichev.
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index a0181c083a6036..ef492d143d5644 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -584,8 +584,8 @@ e_getitem(arrayobject *ap, Py_ssize_t i)
 static int
 e_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
 {
-    float x;
-    if (!PyArg_Parse(v, "f;array item must be float", &x)) {
+    double x;
+    if (!PyArg_Parse(v, "d;array item must be float", &x)) {
         return -1;
     }
 
@@ -607,14 +607,16 @@ f_getitem(arrayobject *ap, Py_ssize_t i)
 static int
 f_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
 {
-    float x;
-    if (!PyArg_Parse(v, "f;array item must be float", &x))
+    double x;
+    if (!PyArg_Parse(v, "d;array item must be float", &x))
         return -1;
 
     CHECK_ARRAY_BOUNDS(ap, i);
 
-    if (i >= 0)
-                 ((float *)ap->ob_item)[i] = x;
+    if (i >= 0) {
+        return PyFloat_Pack4(x, ap->ob_item + sizeof(float)*i,
+                             PY_LITTLE_ENDIAN);
+    }
     return 0;
 }
 
@@ -651,7 +653,6 @@ static int
 cf_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
 {
     Py_complex x;
-    float f[2];
 
     if (!PyArg_Parse(v, "D;array item must be complex", &x)) {
         return -1;
@@ -659,10 +660,18 @@ cf_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v)
 
     CHECK_ARRAY_BOUNDS(ap, i);
 
-    f[0] = (float)x.real;
-    f[1] = (float)x.imag;
     if (i >= 0) {
-        memcpy(ap->ob_item + i*sizeof(f), &f, sizeof(f));
+        char f[8];
+        int ret = PyFloat_Pack4(x.real, f, PY_LITTLE_ENDIAN);
+
+        if (ret) {
+            return ret;
+        }
+        ret = PyFloat_Pack4(x.imag, f + sizeof(float), PY_LITTLE_ENDIAN);
+        if (!ret) {
+            memcpy(ap->ob_item + i*sizeof(f), &f, sizeof(f));
+        }
+        return ret;
     }
     return 0;
 }

_______________________________________________
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