]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-119771: Set errno on overflows in _Py_c_pow() (#120256)
authorSergey B Kirpichev <skirpichev@gmail.com>
Wed, 18 Sep 2024 08:39:11 +0000 (11:39 +0300)
committerGitHub <noreply@github.com>
Wed, 18 Sep 2024 08:39:11 +0000 (10:39 +0200)
Before we did this in complex_pow() and behavior of the public C API
function _Py_c_pow() was different from the pure-python pow().

Doc/c-api/complex.rst
Lib/test/test_capi/test_complex.py
Misc/NEWS.d/next/C API/2024-06-08-08-33-40.gh-issue-119771.Oip2dL.rst [new file with mode: 0644]
Objects/complexobject.c

index 67d0c5f144e07530337677008ca9be8f4c4c8fd2..16bd79475dc1e66ea6fffd3ef3844dd3f1ce1f43 100644 (file)
@@ -79,6 +79,8 @@ pointers.  This is consistent throughout the API.
    If *num* is null and *exp* is not a positive real number,
    this method returns zero and sets :c:data:`errno` to :c:macro:`!EDOM`.
 
+   Set :c:data:`errno` to :c:macro:`!ERANGE` on overflows.
+
 
 Complex Numbers as Python Objects
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index 328ea12f97462c1d5132784ebaca37f784a4f6d0..368edfbf2ce97ee4cc19e42e9a64e36c801bc80f 100644 (file)
@@ -226,7 +226,11 @@ class CAPIComplexTest(unittest.TestCase):
 
         self.assertEqual(_py_c_pow(0j, -1)[1], errno.EDOM)
         self.assertEqual(_py_c_pow(0j, 1j)[1], errno.EDOM)
-        self.assertEqual(_py_c_pow(*[DBL_MAX+1j]*2)[0], complex(*[INF]*2))
+        max_num = DBL_MAX+1j
+        self.assertEqual(_py_c_pow(max_num, max_num),
+                         (complex(INF, INF), errno.ERANGE))
+        self.assertEqual(_py_c_pow(max_num, 2),
+                         (complex(INF, INF), errno.ERANGE))
 
 
     def test_py_c_abs(self):
diff --git a/Misc/NEWS.d/next/C API/2024-06-08-08-33-40.gh-issue-119771.Oip2dL.rst b/Misc/NEWS.d/next/C API/2024-06-08-08-33-40.gh-issue-119771.Oip2dL.rst
new file mode 100644 (file)
index 0000000..6161908
--- /dev/null
@@ -0,0 +1,2 @@
+Set :data:`errno` in :c:func:`_Py_c_pow` on overflows.  Patch by Sergey B
+Kirpichev.
index 4a8dac6c53f52954c286b832d73d89091036ae90..787235c63a6be128adaa1cd2ab2a409f04f85e3b 100644 (file)
@@ -173,6 +173,8 @@ _Py_c_pow(Py_complex a, Py_complex b)
         }
         r.real = len*cos(phase);
         r.imag = len*sin(phase);
+
+        _Py_ADJUST_ERANGE2(r.real, r.imag);
     }
     return r;
 }
@@ -567,12 +569,12 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
     // a faster and more accurate algorithm.
     if (b.imag == 0.0 && b.real == floor(b.real) && fabs(b.real) <= 100.0) {
         p = c_powi(a, (long)b.real);
+        _Py_ADJUST_ERANGE2(p.real, p.imag);
     }
     else {
         p = _Py_c_pow(a, b);
     }
 
-    _Py_ADJUST_ERANGE2(p.real, p.imag);
     if (errno == EDOM) {
         PyErr_SetString(PyExc_ZeroDivisionError,
                         "zero to a negative or complex power");