Skip to content

Commit 340cfba

Browse files
skirpichevvstinnerhpkfft
authored
[3.15] gh-155526: Don't check errno in abs(complex) (GH-155527) (#157341)
Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: hpkfft.com <paul@hpkfft.com>
1 parent c24b1aa commit 340cfba

4 files changed

Lines changed: 33 additions & 2 deletions

File tree

Lib/test/test_complex.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import errno
12
import unittest
23
import sys
34
from test import support
5+
from test.support import import_helper
46
from test.support.testcase import ComplexesAreIdenticalMixin
57
from test.support.numbers import (
68
VALID_UNDERSCORE_LITERALS,
@@ -9,6 +11,7 @@
911

1012
from random import random
1113
from math import isnan, copysign
14+
import cmath
1215
import operator
1316

1417
INF = float("inf")
@@ -789,8 +792,30 @@ def test_abs(self):
789792
for num in nums:
790793
self.assertAlmostEqual((num.real**2 + num.imag**2) ** 0.5, abs(num))
791794

795+
for x in 0.0, -0.0, INF, -INF, NAN:
796+
for y in 0.0, -0.0, INF, -INF, NAN:
797+
with self.subTest(x=x, y=y):
798+
z = complex(x, y)
799+
r = abs(z)
800+
if cmath.isfinite(z):
801+
self.assertFloatsAreIdentical(r, 0.0)
802+
elif cmath.isinf(z):
803+
self.assertEqual(r, INF)
804+
else:
805+
self.assertTrue(cmath.isnan(z))
806+
self.assertTrue(isnan(r))
807+
792808
self.assertRaises(OverflowError, abs, complex(DBL_MAX, DBL_MAX))
793809

810+
def test_abs_errno_handling(self):
811+
_testcapi = import_helper.import_module('_testcapi')
812+
z = complex('nan')
813+
_testcapi.set_errno(errno.ERANGE)
814+
try:
815+
self.assertTrue(isnan(abs(z)))
816+
finally:
817+
_testcapi.set_errno(0)
818+
794819
def test_repr_str(self):
795820
def test(v, expected, test_fn=self.assertEqual):
796821
test_fn(repr(v), expected)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix spurious :exc:`OverflowError` for ``abs(nanj)`` in case :c:data:`errno` was
2+
previously set to :c:macro:`!ERANGE` by some library call.
3+
Patch by Sergey B Kirpichev.

Modules/cmathmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,8 +1029,8 @@ cmath_polar_impl(PyObject *module, Py_complex z)
10291029
{
10301030
double r, phi;
10311031

1032-
errno = 0;
10331032
phi = atan2(z.imag, z.real); /* should not cause any exception */
1033+
errno = 0;
10341034
r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */
10351035
if (errno != 0)
10361036
return math_error();

Objects/complexobject.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,10 @@ static PyObject *
796796
complex_abs(PyObject *op)
797797
{
798798
PyComplexObject *v = _PyComplexObject_CAST(op);
799-
double result = _Py_c_abs(v->cval);
799+
double result;
800+
801+
errno = 0;
802+
result = _Py_c_abs(v->cval);
800803
if (errno == ERANGE) {
801804
PyErr_SetString(PyExc_OverflowError,
802805
"absolute value too large");

0 commit comments

Comments
 (0)