gh-153144: Avoid checking `errno` for `atan2` by hpkfft · Pull Request #153148 · python/cpython · GitHub
Skip to content
12 changes: 10 additions & 2 deletions Lib/test/test_cmath.py
2 changes: 0 additions & 2 deletions Lib/test/test_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,6 @@ def testAtanh(self):
self.assertRaises(ValueError, math.atanh, NINF)
self.assertTrue(math.isnan(math.atanh(NAN)))

@unittest.skipIf(sys.platform.startswith("sunos"),
"skipping, see gh-138573")
def testAtan2(self):
self.assertRaises(TypeError, math.atan2)
self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Given a complex number ``z`` for which ``z.imag/z.real`` underflows to zero,
the :func:`cmath.phase` of ``z`` should not raise ``OverflowError``. Also,
given arguments of zero, Python's :func:`math.atan2`, :func:`math.atan2pi`,
and :func:`cmath.phase` should return the values specified by Annex F of the
C standard, not raise ``ValueError``, regardless of whether the platform's
math library sets ``errno`` for ``atan2(0.0, 0.0)``, ``atan2(0.0, -0.0)``, etc.
Contributed by High Performance Kernels LLC.
7 changes: 2 additions & 5 deletions Modules/cmathmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1004,12 +1004,9 @@ cmath_phase_impl(PyObject *module, Py_complex z)
{
double phi;

errno = 0;
phi = atan2(z.imag, z.real); /* should not cause any exception */
Comment thread
hpkfft marked this conversation as resolved.
if (errno != 0)
return math_error();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expected a test_cmath failure when this code path is removed. Is it because glibc math library doesn't errno in this case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. With the exception of the Intel and Solaris math libraries, errno is not set in this case by any math library that Python cares about. I say this because test_phase in Lib/test/test_cmath.py has asserted that return values are correct since Python 3.14, and nobody has complained. If errno were set by the C math library, the unittest would fail with ValueError: math domain error.

🌱 Some math libraries (e.g., musl) don't set errno for anything, so Python cannot rely on errno for detecting overflow or invalid. I would think that errno checking can be removed everywhere....

else
return PyFloat_FromDouble(phi);
/* gh-153144: Ignore atan2() errno on purpose. */
Comment thread
hpkfft marked this conversation as resolved.
return PyFloat_FromDouble(phi);
}

/*[clinic input]
Expand Down
36 changes: 32 additions & 4 deletions Modules/mathmodule.c
Loading