Issue #24489: ensure a previously set C errno doesn't disturb cmath.polar().
This commit is contained in:
commit
d6362db83d
|
@ -1,4 +1,4 @@
|
|||
from test.support import requires_IEEE_754
|
||||
from test.support import requires_IEEE_754, cpython_only
|
||||
from test.test_math import parse_testfile, test_file
|
||||
import test.test_math as test_math
|
||||
import unittest
|
||||
|
@ -382,17 +382,48 @@ class CMathTests(unittest.TestCase):
|
|||
self.rAssertAlmostEqual(expected.imag, actual.imag,
|
||||
msg=error_message)
|
||||
|
||||
def assertCISEqual(self, a, b):
|
||||
eps = 1E-7
|
||||
if abs(a[0] - b[0]) > eps or abs(a[1] - b[1]) > eps:
|
||||
self.fail((a ,b))
|
||||
def check_polar(self, func):
|
||||
def check(arg, expected):
|
||||
got = func(arg)
|
||||
for e, g in zip(expected, got):
|
||||
self.rAssertAlmostEqual(e, g)
|
||||
check(0, (0., 0.))
|
||||
check(1, (1., 0.))
|
||||
check(-1, (1., pi))
|
||||
check(1j, (1., pi / 2))
|
||||
check(-3j, (3., -pi / 2))
|
||||
inf = float('inf')
|
||||
check(complex(inf, 0), (inf, 0.))
|
||||
check(complex(-inf, 0), (inf, pi))
|
||||
check(complex(3, inf), (inf, pi / 2))
|
||||
check(complex(5, -inf), (inf, -pi / 2))
|
||||
check(complex(inf, inf), (inf, pi / 4))
|
||||
check(complex(inf, -inf), (inf, -pi / 4))
|
||||
check(complex(-inf, inf), (inf, 3 * pi / 4))
|
||||
check(complex(-inf, -inf), (inf, -3 * pi / 4))
|
||||
nan = float('nan')
|
||||
check(complex(nan, 0), (nan, nan))
|
||||
check(complex(0, nan), (nan, nan))
|
||||
check(complex(nan, nan), (nan, nan))
|
||||
check(complex(inf, nan), (inf, nan))
|
||||
check(complex(-inf, nan), (inf, nan))
|
||||
check(complex(nan, inf), (inf, nan))
|
||||
check(complex(nan, -inf), (inf, nan))
|
||||
|
||||
def test_polar(self):
|
||||
self.assertCISEqual(polar(0), (0., 0.))
|
||||
self.assertCISEqual(polar(1.), (1., 0.))
|
||||
self.assertCISEqual(polar(-1.), (1., pi))
|
||||
self.assertCISEqual(polar(1j), (1., pi/2))
|
||||
self.assertCISEqual(polar(-1j), (1., -pi/2))
|
||||
self.check_polar(polar)
|
||||
|
||||
@cpython_only
|
||||
def test_polar_errno(self):
|
||||
# Issue #24489: check a previously set C errno doesn't disturb polar()
|
||||
from _testcapi import set_errno
|
||||
def polar_with_errno_set(z):
|
||||
set_errno(11)
|
||||
try:
|
||||
return polar(z)
|
||||
finally:
|
||||
set_errno(0)
|
||||
self.check_polar(polar_with_errno_set)
|
||||
|
||||
def test_phase(self):
|
||||
self.assertAlmostEqual(phase(0), 0.)
|
||||
|
|
|
@ -46,6 +46,8 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #24489: ensure a previously set C errno doesn't disturb cmath.polar().
|
||||
|
||||
- Issue #24408: Fixed AttributeError in measure() and metrics() methods of
|
||||
tkinter.Font.
|
||||
|
||||
|
|
|
@ -1795,6 +1795,18 @@ raise_exception(PyObject *self, PyObject *args)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
set_errno(PyObject *self, PyObject *args)
|
||||
{
|
||||
int new_errno;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i:set_errno", &new_errno))
|
||||
return NULL;
|
||||
|
||||
errno = new_errno;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
test_set_exc_info(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -3510,6 +3522,7 @@ test_PyTime_AsMicroseconds(PyObject *self, PyObject *args)
|
|||
static PyMethodDef TestMethods[] = {
|
||||
{"raise_exception", raise_exception, METH_VARARGS},
|
||||
{"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS},
|
||||
{"set_errno", set_errno, METH_VARARGS},
|
||||
{"test_config", (PyCFunction)test_config, METH_NOARGS},
|
||||
{"test_sizeof_c_types", (PyCFunction)test_sizeof_c_types, METH_NOARGS},
|
||||
{"test_datetime_capi", test_datetime_capi, METH_NOARGS},
|
||||
|
|
|
@ -986,9 +986,10 @@ cmath_polar_impl(PyModuleDef *module, Py_complex z)
|
|||
{
|
||||
double r, phi;
|
||||
|
||||
errno = 0;
|
||||
PyFPE_START_PROTECT("polar function", return 0)
|
||||
phi = c_atan2(z); /* should not cause any exception */
|
||||
r = _Py_c_abs(z); /* sets errno to ERANGE on overflow; otherwise 0 */
|
||||
r = _Py_c_abs(z); /* sets errno to ERANGE on overflow */
|
||||
PyFPE_END_PROTECT(r)
|
||||
if (errno != 0)
|
||||
return math_error();
|
||||
|
|
Loading…
Reference in New Issue