https://github.com/python/cpython/commit/e634a8ac1f8a2904a2241b83fc5e4c9f40d5c7ca commit: e634a8ac1f8a2904a2241b83fc5e4c9f40d5c7ca branch: 3.8 author: Mark Dickinson <mdickinson at enthought.com> committer: GitHub <noreply at github.com> date: 2020-03-14T11:38:52Z summary: [3.8] bpo-39871: Fix possible SystemError in atan2, copysign and remainder (GH-18806) (GH-18989) In math_2(), the first PyFloat_AsDouble() call should be checked for failure before the second call. Co-authored-by: Mark Dickinson <dickinsm at gmail.com>. (cherry picked from commit 5208b4b37953a406db0ed6a9db545c2948dde989) Co-authored-by: Zackery Spytz <zspytz at gmail.com> files: A Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst M Lib/test/test_math.py M Modules/mathmodule.c diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 6abaeead5c20c..4a1ba830c98d6 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1878,6 +1878,22 @@ def testComb(self): self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int) self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int) + 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. def assertIsNaN(self, value): diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst new file mode 100644 index 0000000000000..0b4c2e5f4cc92 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst @@ -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. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 4e97337811113..b78fcedd03de5 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1027,9 +1027,13 @@ math_2(PyObject *const *args, Py_ssize_t nargs, if (!_PyArg_CheckPositional(funcname, nargs, 2, 2)) return NULL; x = PyFloat_AsDouble(args[0]); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } y = PyFloat_AsDouble(args[1]); - if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) + if (y == -1.0 && PyErr_Occurred()) { return NULL; + } errno = 0; PyFPE_START_PROTECT("in math_2", return 0); r = (*func)(x, y);
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4