diff --git a/Lib/test/test_ctypes/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py index b7df08f6079cd31..64bd0919d193353 100644 --- a/Lib/test/test_ctypes/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -231,6 +231,8 @@ def test_init(self): # probably be changed: self.assertRaises(TypeError, c_int, c_long(42)) + @unittest.skipUnless(hasattr(ctypes, "c_double_complex"), + "requires C11 complex type") def test_float_overflow(self): big_int = int(sys.float_info.max) * 2 for t in float_types + [c_longdouble]: @@ -240,6 +242,21 @@ def test_float_overflow(self): if (hasattr(t, "__ctype_le__")): self.assertRaises(OverflowError, t.__ctype_le__, big_int) + # gh-156865: be silent in overflows of C types + self.assertEqual(ctypes.c_float(3e300).value, float('inf')) + self.assertEqual(ctypes.c_float.__ctype_le__(3e300).value, float('inf')) + self.assertEqual(ctypes.c_float.__ctype_be__(3e300).value, float('inf')) + self.assertEqual(ctypes.c_float_complex(3e300).value, complex('inf')) + self.assertEqual(ctypes.c_float_complex.__ctype_le__(3e300).value, + complex('inf')) + self.assertEqual(ctypes.c_float_complex.__ctype_be__(3e300).value, + complex('inf')) + self.assertEqual(ctypes.c_float_complex(3e300j).value, complex('infj')) + self.assertEqual(ctypes.c_float_complex.__ctype_le__(3e300j).value, + complex('infj')) + self.assertEqual(ctypes.c_float_complex.__ctype_be__(3e300j).value, + complex('infj')) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2026-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst b/Misc/NEWS.d/next/Library/2026-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst new file mode 100644 index 000000000000000..26cdad81424ee7a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-09-04-11-45-08.gh-issue-156865.mrdfKJ.rst @@ -0,0 +1,2 @@ +Don't raise exceptions on overflows in floating-point types of the +:mod:`ctypes`. Patch by Sergey B Kirpichev. diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 00b075bccff6647..193c60a1afee85c 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -865,14 +865,14 @@ Zf_set_sw(void *ptr, PyObject *value, Py_ssize_t size) return NULL; } #ifdef WORDS_BIGENDIAN - if (PyFloat_Pack4(c.real, ptr, 1) - || PyFloat_Pack4(c.imag, ptr + sizeof(float), 1)) + if (PyFloat_Pack4((float)c.real, ptr, 1) + || PyFloat_Pack4((float)c.imag, ptr + sizeof(float), 1)) { return NULL; } #else - if (PyFloat_Pack4(c.real, ptr, 0) - || PyFloat_Pack4(c.imag, ptr + sizeof(float), 0)) + if (PyFloat_Pack4((float)c.real, ptr, 0) + || PyFloat_Pack4((float)c.imag, ptr + sizeof(float), 0)) { return NULL; }