diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2015-06-23 12:38:13 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2015-06-23 12:38:13 (GMT) |
commit | a72f0cdaea847228aceb5b56fbd28b77ef4809c4 (patch) | |
tree | ae80fc12096a3e2dd5989b74a2916e7c856ede58 | |
parent | 5376ba9630e45ad177150ae68c9712640330a2fc (diff) | |
parent | 6bc217dd3d43763e62b413e75ddaeb7d30e1b451 (diff) | |
download | cpython-a72f0cdaea847228aceb5b56fbd28b77ef4809c4.zip cpython-a72f0cdaea847228aceb5b56fbd28b77ef4809c4.tar.gz cpython-a72f0cdaea847228aceb5b56fbd28b77ef4809c4.tar.bz2 |
Issue #24489: ensure a previously set C errno doesn't disturb cmath.polar().
-rw-r--r-- | Lib/test/test_cmath.py | 51 | ||||
-rw-r--r-- | Misc/NEWS | 2 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 13 | ||||
-rw-r--r-- | Modules/cmathmodule.c | 3 |
4 files changed, 58 insertions, 11 deletions
diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index 25ab7c1..1f884e5 100644 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -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.) @@ -24,6 +24,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. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 2697ac2..ba0a24b 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1796,6 +1796,18 @@ raise_exception(PyObject *self, PyObject *args) } 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) { PyObject *orig_exc; @@ -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}, diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index d12e4c5..7f6c2c9 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -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(); |