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
|
from test.test_math import parse_testfile, test_file
|
||||||
import test.test_math as test_math
|
import test.test_math as test_math
|
||||||
import unittest
|
import unittest
|
||||||
|
@ -382,17 +382,48 @@ class CMathTests(unittest.TestCase):
|
||||||
self.rAssertAlmostEqual(expected.imag, actual.imag,
|
self.rAssertAlmostEqual(expected.imag, actual.imag,
|
||||||
msg=error_message)
|
msg=error_message)
|
||||||
|
|
||||||
def assertCISEqual(self, a, b):
|
def check_polar(self, func):
|
||||||
eps = 1E-7
|
def check(arg, expected):
|
||||||
if abs(a[0] - b[0]) > eps or abs(a[1] - b[1]) > eps:
|
got = func(arg)
|
||||||
self.fail((a ,b))
|
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):
|
def test_polar(self):
|
||||||
self.assertCISEqual(polar(0), (0., 0.))
|
self.check_polar(polar)
|
||||||
self.assertCISEqual(polar(1.), (1., 0.))
|
|
||||||
self.assertCISEqual(polar(-1.), (1., pi))
|
@cpython_only
|
||||||
self.assertCISEqual(polar(1j), (1., pi/2))
|
def test_polar_errno(self):
|
||||||
self.assertCISEqual(polar(-1j), (1., -pi/2))
|
# 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):
|
def test_phase(self):
|
||||||
self.assertAlmostEqual(phase(0), 0.)
|
self.assertAlmostEqual(phase(0), 0.)
|
||||||
|
|
|
@ -46,6 +46,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #24489: ensure a previously set C errno doesn't disturb cmath.polar().
|
||||||
|
|
||||||
- Issue #24408: Fixed AttributeError in measure() and metrics() methods of
|
- Issue #24408: Fixed AttributeError in measure() and metrics() methods of
|
||||||
tkinter.Font.
|
tkinter.Font.
|
||||||
|
|
||||||
|
|
|
@ -1795,6 +1795,18 @@ raise_exception(PyObject *self, PyObject *args)
|
||||||
return NULL;
|
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 *
|
static PyObject *
|
||||||
test_set_exc_info(PyObject *self, PyObject *args)
|
test_set_exc_info(PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -3510,6 +3522,7 @@ test_PyTime_AsMicroseconds(PyObject *self, PyObject *args)
|
||||||
static PyMethodDef TestMethods[] = {
|
static PyMethodDef TestMethods[] = {
|
||||||
{"raise_exception", raise_exception, METH_VARARGS},
|
{"raise_exception", raise_exception, METH_VARARGS},
|
||||||
{"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS},
|
{"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS},
|
||||||
|
{"set_errno", set_errno, METH_VARARGS},
|
||||||
{"test_config", (PyCFunction)test_config, METH_NOARGS},
|
{"test_config", (PyCFunction)test_config, METH_NOARGS},
|
||||||
{"test_sizeof_c_types", (PyCFunction)test_sizeof_c_types, METH_NOARGS},
|
{"test_sizeof_c_types", (PyCFunction)test_sizeof_c_types, METH_NOARGS},
|
||||||
{"test_datetime_capi", test_datetime_capi, 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;
|
double r, phi;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
PyFPE_START_PROTECT("polar function", return 0)
|
PyFPE_START_PROTECT("polar function", return 0)
|
||||||
phi = c_atan2(z); /* should not cause any exception */
|
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)
|
PyFPE_END_PROTECT(r)
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
return math_error();
|
return math_error();
|
||||||
|
|
Loading…
Reference in New Issue