8000 bpo-39871: Fix possible SystemError in atan2, copysign and remainder … · python/cpython@5208b4b · GitHub
[go: up one dir, main page]

Skip to content

Commit 5208b4b

Browse files
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>
1 parent 3a8c562 commit 5208b4b

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

Lib/test/test_math.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,22 @@ def test_ulp(self):
19921992
with self.subTest(x=x):
19931993
self.assertEqual(math.ulp(-x), math.ulp(x))
19941994

1995+
def test_issue39871(self):
1996+
# A SystemError should not be raised if the first arg to atan2(),
1997+
# copysign(), or remainder() cannot be converted to a float.
1998+
class F:
1999+
def __float__(self):
2000+
self.converted = True
2001+
1/0
2002+
for func in math.atan2, math.copysign, math.remainder:
2003+
y = F()
2004+
with self.assertRaises(TypeError):
2005+
func("not a number", y)
2006+
2007+
# There should not have been any attempt to convert the second
2008+
# argument to a float.
2009+
self.assertFalse(getattr(y, "converted", False))
2010+
19952011
# Custom assertions.
19962012

19972013
def assertIsNaN(self, value):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a possible :exc:`SystemError` in ``math.{atan2,copysign,remainder}()``
2+
when the first argument cannot be converted to a :class:`float`. Patch by
3+
Zachary Spytz.

Modules/mathmodule.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1106,9 +1106,13 @@ math_2(PyObject *const *args, Py_ssize_t nargs,
11061106
if (!_PyArg_CheckPositional(funcname, nargs, 2, 2))
11071107
return NULL;
11081108
x = PyFloat_AsDouble(args[0]);
1109+
if (x == -1.0 && PyErr_Occurred()) {
1110+
return NULL;
1111+
}
11091112
y = PyFloat_AsDouble(args[1]);
1110-
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
1113+
if (y == -1.0 && PyErr_Occurred()) {
11111114
return NULL;
1115+
}
11121116
errno = 0;
11131117
r = (*func)(x, y);
11141118
if (Py_IS_NAN(r)) {

0 commit comments

Comments
 (0)
0