bpo-39871: Fix possible SystemError in atan2, copysign and remainder (GH-18806)
In math_2(), the first PyFloat_AsDouble() call should be checked for failure before the second call. Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
This commit is contained in:
parent
3a8c56295d
commit
5208b4b379
|
@ -1992,6 +1992,22 @@ class MathTests(unittest.TestCase):
|
||||||
with self.subTest(x=x):
|
with self.subTest(x=x):
|
||||||
self.assertEqual(math.ulp(-x), math.ulp(x))
|
self.assertEqual(math.ulp(-x), math.ulp(x))
|
||||||
|
|
||||||
|
def test_issue39871(self):
|
||||||
|
# A SystemError should not be raised if the first arg to atan2(),
|
||||||
|
# copysign(), or remainder() cannot be converted to a float.
|
||||||
|
class F:
|
||||||
|
def __float__(self):
|
||||||
|
self.converted = True
|
||||||
|
1/0
|
||||||
|
for func in math.atan2, math.copysign, math.remainder:
|
||||||
|
y = F()
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
func("not a number", y)
|
||||||
|
|
||||||
|
# There should not have been any attempt to convert the second
|
||||||
|
# argument to a float.
|
||||||
|
self.assertFalse(getattr(y, "converted", False))
|
||||||
|
|
||||||
# Custom assertions.
|
# Custom assertions.
|
||||||
|
|
||||||
def assertIsNaN(self, value):
|
def assertIsNaN(self, value):
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
Fix a possible :exc:`SystemError` in ``math.{atan2,copysign,remainder}()``
|
||||||
|
when the first argument cannot be converted to a :class:`float`. Patch by
|
||||||
|
Zachary Spytz.
|
|
@ -1106,9 +1106,13 @@ math_2(PyObject *const *args, Py_ssize_t nargs,
|
||||||
if (!_PyArg_CheckPositional(funcname, nargs, 2, 2))
|
if (!_PyArg_CheckPositional(funcname, nargs, 2, 2))
|
||||||
return NULL;
|
return NULL;
|
||||||
x = PyFloat_AsDouble(args[0]);
|
x = PyFloat_AsDouble(args[0]);
|
||||||
y = PyFloat_AsDouble(args[1]);
|
if (x == -1.0 && PyErr_Occurred()) {
|
||||||
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
y = PyFloat_AsDouble(args[1]);
|
||||||
|
if (y == -1.0 && PyErr_Occurred()) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
errno = 0;
|
errno = 0;
|
||||||
r = (*func)(x, y);
|
r = (*func)(x, y);
|
||||||
if (Py_IS_NAN(r)) {
|
if (Py_IS_NAN(r)) {
|
||||||
|
|
Loading…
Reference in New Issue