From a1d2c1afbf2f435f6fabf6dc0b3df8502907e9c5 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Sep 2023 09:15:07 +0300 Subject: [PATCH 01/18] gh-102837: Increase test coverage for the math module * fsum: L1367, L1377, L1381, L1410 // line numbers wrt to 54fbfa8d5e --- Lib/test/test_math.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index d5d2197c36b254..b1ba16d7aeca97 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -685,6 +685,8 @@ def msum(iterable): ([], 0.0), ([0.0], 0.0), ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100), + ([1e100, 1.0, -1e100, 1e-100, 1e50, -1, -1e50], 1e-100), + ([1e100, FloatLike(1.0), -1e100, 1e-100, 1e50, FloatLike(-1.0), -1e50], 1e-100), ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0), ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0), ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0), @@ -733,9 +735,18 @@ def msum(iterable): self.assertEqual(msum(vals), math.fsum(vals)) self.assertEqual(math.fsum([1.0, math.inf]), math.inf) + self.assertTrue(math.isnan(math.fsum([math.nan, 1.0]))) self.assertRaises(OverflowError, math.fsum, [1e+308, 1e+308]) self.assertRaises(ValueError, math.fsum, [math.inf, -math.inf]) self.assertRaises(TypeError, math.fsum, ['spam']) + self.assertRaises(TypeError, math.fsum, 1) + self.assertRaises(OverflowError, math.fsum, [10**1000]) + + def bad_iter(): + yield 1.0 + raise ZeroDivisionError + + self.assertRaises(ZeroDivisionError, math.fsum, bad_iter()) def testGcd(self): gcd = math.gcd From 03e8eadea26e113df2a866430b0dd7be86cb7395 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Sep 2023 09:15:46 +0300 Subject: [PATCH 02/18] Improve math_2() comment (mention real use-cases for math_2) --- Modules/mathmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 2d896e7fe333a4..7837baa028305e 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1020,7 +1020,7 @@ math_1a(PyObject *arg, double (*func) (double)) The last rule is used to catch overflow on platforms which follow C89 but for which HUGE_VAL is not an infinity. - For most two-argument functions (copysign, fmod, hypot, atan2) + For most two-argument functions (copysign, remainder, atan2) these rules are enough to ensure that Python's functions behave as specified in 'Annex F' of the C99 standard, with the 'invalid' and 'divide-by-zero' floating-point exceptions mapping to Python's From 26489bbcd43bea4317fe13526677224e82ca81e4 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Sep 2023 12:05:30 +0300 Subject: [PATCH 03/18] * trunc: drop _PyType_IsReady() check (L2071) like floor/ceil, L2079 --- Lib/test/test_math.py | 3 +++ Modules/mathmodule.c | 5 ----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index b1ba16d7aeca97..b7844cc4428661 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1890,6 +1890,8 @@ def __trunc__(self): return 23 class TestNoTrunc: pass + class TestBadTrunc: + __trunc__ = BadDescr() self.assertEqual(math.trunc(TestTrunc()), 23) self.assertEqual(math.trunc(FloatTrunc()), 23) @@ -1898,6 +1900,7 @@ class TestNoTrunc: self.assertRaises(TypeError, math.trunc, 1, 2) self.assertRaises(TypeError, math.trunc, FloatLike(23.5)) self.assertRaises(TypeError, math.trunc, TestNoTrunc()) + self.assertRaises(ValueError, math.trunc, TestBadTrunc()) def testIsfinite(self): self.assertTrue(math.isfinite(0.0)) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 7837baa028305e..8d72148b89d068 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2068,11 +2068,6 @@ math_trunc(PyObject *module, PyObject *x) return PyFloat_Type.tp_as_number->nb_int(x); } - if (!_PyType_IsReady(Py_TYPE(x))) { - if (PyType_Ready(Py_TYPE(x)) < 0) - return NULL; - } - math_module_state *state = get_math_module_state(module); trunc = _PyObject_LookupSpecial(x, state->str___trunc__); if (trunc == NULL) { From 128c81d659400b07fee152c439f398071bec2b61 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Sep 2023 13:12:10 +0300 Subject: [PATCH 04/18] * log: L2265 --- Lib/test/test_math.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index b7844cc4428661..690bde6c67cadf 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1186,6 +1186,7 @@ def testLdexp(self): def testLog(self): self.assertRaises(TypeError, math.log) + self.assertRaises(TypeError, math.log, 1, 2, 3) self.ftest('log(1/e)', math.log(1/math.e), -1) self.ftest('log(1)', math.log(1), 0) self.ftest('log(e)', math.log(math.e), 1) From ead9eeec59cb8b7ef6b5827919f37d11c0248ad6 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Sep 2023 13:23:19 +0300 Subject: [PATCH 05/18] * loghelper: drop inaccessible cases L2234, L2235, L2241. Here arg is nonnegative and PyLong_AsDouble raises only OverflowError. --- Modules/mathmodule.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 8d72148b89d068..d5cc1d8f09e6ef 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2226,14 +2226,12 @@ loghelper(PyObject* arg, double (*func)(double)) } x = PyLong_AsDouble(arg); - if (x == -1.0 && PyErr_Occurred()) { - if (!PyErr_ExceptionMatches(PyExc_OverflowError)) - return NULL; + if (PyErr_Occurred()) { /* Here the conversion to double overflowed, but it's possible to compute the log anyway. Clear the exception and continue. */ PyErr_Clear(); x = _PyLong_Frexp((PyLongObject *)arg, &e); - if (x == -1.0 && PyErr_Occurred()) + if (PyErr_Occurred()) return NULL; /* Value is ~= x * 2**e, so the log ~= log(x) + log(2) * e. */ result = func(x) + func(2.0) * e; From 3a80c7831636e6a02a7f2e94de5999d4461ce5cb Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Sep 2023 15:33:31 +0300 Subject: [PATCH 06/18] * dist: L2575, L2577 --- Lib/test/test_math.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 690bde6c67cadf..51a14d574f6b0d 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -959,6 +959,10 @@ def testDist(self): # Test allowable types (those with __float__) self.assertEqual(dist((14.0, 1.0), (2.0, -4.0)), 13.0) self.assertEqual(dist((14, 1), (2, -4)), 13) + self.assertEqual(dist((FloatLike(14.), 1), (2, -4)), 13) + self.assertEqual(dist((11, 1), (FloatLike(-1.), -4)), 13) + self.assertEqual(dist((14, FloatLike(-1.)), (2, -6)), 13) + self.assertEqual(dist((14, -1), (2, -6)), 13) self.assertEqual(dist((D(14), D(1)), (D(2), D(-4))), D(13)) self.assertEqual(dist((F(14, 32), F(1, 32)), (F(2, 32), F(-4, 32))), F(13, 32)) @@ -1016,6 +1020,12 @@ class T(tuple): with self.assertRaises(TypeError): dist([1], 2) + class BadFloat: + __float__ = BadDescr() + + with self.assertRaises(ValueError): + dist([1], [BadFloat()]) + # Verify that the one dimensional case is equivalent to abs() for i in range(20): p, q = random.random(), random.random() From 8b3bb524204cc9cbcb39d1d7a7194508ada71615 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Mon, 18 Sep 2023 16:01:54 +0300 Subject: [PATCH 07/18] * hypot: L2630 --- Lib/test/test_math.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 51a14d574f6b0d..85da10dfd57aa2 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -808,6 +808,8 @@ def testHypot(self): # Test allowable types (those with __float__) self.assertEqual(hypot(12.0, 5.0), 13.0) self.assertEqual(hypot(12, 5), 13) + self.assertEqual(hypot(1, -1), 1.4142135623730951) + self.assertEqual(hypot(1, FloatLike(-1.)), 1.4142135623730951) self.assertEqual(hypot(Decimal(12), Decimal(5)), 13) self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32)) self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3)) From 4e25c35e300f48d8b0f7f94a8bfabc41f05f2082 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 19 Sep 2023 06:48:30 +0300 Subject: [PATCH 08/18] * sumprod: L2742, L2752, L2772, L2775, L2779, L2783 --- Lib/test/test_math.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 85da10dfd57aa2..64eec800699bd5 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1299,6 +1299,12 @@ def testSumProd(self): self.assertRaises(ValueError, sumprod, [10, 20], [30]) self.assertRaises(ValueError, sumprod, [10], [20, 30]) + # Overflows + self.assertEqual(sumprod([10**20], [1]), 10**20) + self.assertEqual(sumprod([1], [10**20]), 10**20) + self.assertEqual(sumprod([10**10], [10**10]), 10**20) + self.assertEqual(sumprod([10**7]*10**5, [10**7]*10**5), 10**19) + # Error in iterator def raise_after(n): for i in range(n): @@ -1309,6 +1315,11 @@ def raise_after(n): with self.assertRaises(RuntimeError): sumprod(raise_after(5), range(10)) + from test.test_iter import BasicIterClass + + self.assertEqual(sumprod(BasicIterClass(1), [1]), 0) + self.assertEqual(sumprod([1], BasicIterClass(1)), 0) + # Error in multiplication class BadMultiply: def __mul__(self, other): From 7956447091d8107a73b11c6ccf14a464c1c8be22 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 19 Sep 2023 08:28:38 +0300 Subject: [PATCH 09/18] Fix typo in sumprod() --- Modules/mathmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index d5cc1d8f09e6ef..e479cad5e12d2b 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2823,7 +2823,7 @@ math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q) PyErr_Clear(); goto finalize_flt_path; } - } else if (q_type_float && (PyLong_CheckExact(p_i) || PyBool_Check(q_i))) { + } else if (q_type_float && (PyLong_CheckExact(p_i) || PyBool_Check(p_i))) { flt_q = PyFloat_AS_DOUBLE(q_i); flt_p = PyLong_AsDouble(p_i); if (flt_p == -1.0 && PyErr_Occurred()) { From 052d7de86743e260a50cc691b5d45e33bec6eab7 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 19 Sep 2023 08:29:08 +0300 Subject: [PATCH 10/18] * sumprod: L2829, L2833, L2836 --- Lib/test/test_math.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 64eec800699bd5..d1a09a706de17d 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1269,6 +1269,9 @@ def testSumProd(self): self.assertEqual(sumprod(iter([10, 20, 30]), (1, 2, 3)), 140) self.assertEqual(sumprod([1.5, 2.5], [3.5, 4.5]), 16.5) self.assertEqual(sumprod([], []), 0) + self.assertEqual(sumprod([-1], [1.]), -1) + self.assertEqual(sumprod([1.], [-1]), -1) + self.assertEqual(sumprod([True], [1.0]), 1) # Type preservation and coercion for v in [ @@ -1294,6 +1297,7 @@ def testSumProd(self): self.assertRaises(TypeError, sumprod, [], [], []) # Three args self.assertRaises(TypeError, sumprod, None, [10]) # Non-iterable self.assertRaises(TypeError, sumprod, [10], None) # Non-iterable + self.assertRaises(TypeError, sumprod, ['x'], [1.0]) # Uneven lengths self.assertRaises(ValueError, sumprod, [10, 20], [30]) @@ -1304,6 +1308,8 @@ def testSumProd(self): self.assertEqual(sumprod([1], [10**20]), 10**20) self.assertEqual(sumprod([10**10], [10**10]), 10**20) self.assertEqual(sumprod([10**7]*10**5, [10**7]*10**5), 10**19) + self.assertRaises(OverflowError, sumprod, [10**1000], [1.0]) + self.assertRaises(OverflowError, sumprod, [1.0], [10**1000]) # Error in iterator def raise_after(n): From b431805ae437a072eaa5f9f57a67e17d251709f6 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 19 Sep 2023 08:43:05 +0300 Subject: [PATCH 11/18] * pow: L2979, L2980 --- Lib/test/test_math.py | 1 + Modules/mathmodule.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index d1a09a706de17d..6403f97dc98494 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1564,6 +1564,7 @@ def testPow(self): self.assertTrue(math.isnan(math.pow(2, NAN))) self.assertTrue(math.isnan(math.pow(0, NAN))) self.assertEqual(math.pow(1, NAN), 1) + self.assertRaises(OverflowError, math.pow, 1e+100, 1e+100) # pow(0., x) self.assertEqual(math.pow(0., INF), 0.) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index e479cad5e12d2b..1b888948ce0ad7 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2969,7 +2969,8 @@ math_pow_impl(PyObject *module, double x, double y) (A) (+/-0.)**negative (-> divide-by-zero) (B) overflow of x**y with x and y finite */ - else if (Py_IS_INFINITY(r)) { + else { + assert(Py_IS_INFINITY(r)); if (x == 0.) errno = EDOM; else From a046568e818ddf7b7018ee9aee5f51463d0bfa71 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Tue, 19 Sep 2023 10:46:09 +0300 Subject: [PATCH 12/18] * prod: L3292, L3306, L3316-3328 --- Lib/test/test_math.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 6403f97dc98494..34738d689ec4ad 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2132,6 +2132,8 @@ def test_mtestfile(self): '\n '.join(failures)) def test_prod(self): + from fractions import Fraction as F + prod = math.prod self.assertEqual(prod([]), 1) self.assertEqual(prod([], start=5), 5) @@ -2143,6 +2145,14 @@ def test_prod(self): self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0) self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0) self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0) + self.assertEqual(prod([1., F(3, 2)]), 1.5) + + # Error in multiplication + class BadMultiply: + def __rmul__(self, other): + raise RuntimeError + with self.assertRaises(RuntimeError): + prod([10., BadMultiply()]) # Test overflow in fast-path for integers self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32) From 3df127ee1789cf9fb01c1cb98bc98ab6e26d1679 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Fri, 6 Oct 2023 12:15:59 +0300 Subject: [PATCH 13/18] More efficient (for finite x) handling of special cases in math.modf Rewrite changes in #102523 --- Modules/mathmodule.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 1b888948ce0ad7..2736d6114510a4 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2190,10 +2190,12 @@ math_modf_impl(PyObject *module, double x) double y; /* some platforms don't do the right thing for NaNs and infinities, so we take care of special cases directly. */ - if (Py_IS_INFINITY(x)) - return Py_BuildValue("(dd)", copysign(0., x), x); - else if (Py_IS_NAN(x)) - return Py_BuildValue("(dd)", x, x); + if (!Py_IS_FINITE(x)) { + if (Py_IS_INFINITY(x)) + return Py_BuildValue("(dd)", copysign(0., x), x); + else + return Py_BuildValue("(dd)", x, x); + } errno = 0; x = modf(x, &y); From 5e6d59fef1d8e5651aaff427ff14e101b0227dda Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Fri, 6 Oct 2023 12:28:52 +0300 Subject: [PATCH 14/18] Change error tests in loghelper() to more lightweight versions (x == -1.0) --- Modules/mathmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 2736d6114510a4..c12b97bd4e9b60 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2228,12 +2228,12 @@ loghelper(PyObject* arg, double (*func)(double)) } x = PyLong_AsDouble(arg); - if (PyErr_Occurred()) { + if (x == -1.0) { /* Here the conversion to double overflowed, but it's possible to compute the log anyway. Clear the exception and continue. */ PyErr_Clear(); x = _PyLong_Frexp((PyLongObject *)arg, &e); - if (PyErr_Occurred()) + if (x == -1.0) return NULL; /* Value is ~= x * 2**e, so the log ~= log(x) + log(2) * e. */ result = func(x) + func(2.0) * e; From 3e8d96f01c8715e0722d545a81a545fe6f083f3d Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 15 Oct 2023 14:33:25 +0300 Subject: [PATCH 15/18] Explicit tests for non-float objects (amend a1d2c1afbf) --- Lib/test/test_math.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 34738d689ec4ad..2be0713a96d8e0 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -686,7 +686,6 @@ def msum(iterable): ([0.0], 0.0), ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100), ([1e100, 1.0, -1e100, 1e-100, 1e50, -1, -1e50], 1e-100), - ([1e100, FloatLike(1.0), -1e100, 1e-100, 1e50, FloatLike(-1.0), -1e50], 1e-100), ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0), ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0), ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0), @@ -736,6 +735,8 @@ def msum(iterable): self.assertEqual(math.fsum([1.0, math.inf]), math.inf) self.assertTrue(math.isnan(math.fsum([math.nan, 1.0]))) + self.assertEqual(math.fsum([1e100, FloatLike(1.0), -1e100, 1e-100, + 1e50, FloatLike(-1.0), -1e50]), 1e-100) self.assertRaises(OverflowError, math.fsum, [1e+308, 1e+308]) self.assertRaises(ValueError, math.fsum, [math.inf, -math.inf]) self.assertRaises(TypeError, math.fsum, ['spam']) From 35db2247fb997598b558263691a941f49a62f40c Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 15 Oct 2023 14:49:39 +0300 Subject: [PATCH 16/18] Amend 8b3bb52420 (use math.sqrt(2) instead) --- Lib/test/test_math.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 2be0713a96d8e0..adab2bd61fa5cf 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -809,8 +809,8 @@ def testHypot(self): # Test allowable types (those with __float__) self.assertEqual(hypot(12.0, 5.0), 13.0) self.assertEqual(hypot(12, 5), 13) - self.assertEqual(hypot(1, -1), 1.4142135623730951) - self.assertEqual(hypot(1, FloatLike(-1.)), 1.4142135623730951) + self.assertEqual(hypot(1, -1), math.sqrt(2)) + self.assertEqual(hypot(1, FloatLike(-1.)), math.sqrt(2)) self.assertEqual(hypot(Decimal(12), Decimal(5)), 13) self.assertEqual(hypot(Fraction(12, 32), Fraction(5, 32)), Fraction(13, 32)) self.assertEqual(hypot(bool(1), bool(0), bool(1), bool(1)), math.sqrt(3)) From 6844b19bc963f4273ea9fc5da5afc5e9805e13c1 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 29 Oct 2023 07:17:47 +0300 Subject: [PATCH 17/18] Amend 052d7de86 Remove redundant test (#111416) --- Lib/test/test_math.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index adab2bd61fa5cf..4d21cbba07b555 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1272,7 +1272,6 @@ def testSumProd(self): self.assertEqual(sumprod([], []), 0) self.assertEqual(sumprod([-1], [1.]), -1) self.assertEqual(sumprod([1.], [-1]), -1) - self.assertEqual(sumprod([True], [1.0]), 1) # Type preservation and coercion for v in [ From ad84c4a4fee745d25bfee2f61935452bb1f196c4 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 9 Dec 2023 06:43:53 +0300 Subject: [PATCH 18/18] Revert PyErr_ExceptionMatches --- Modules/mathmodule.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 643560747e2f62..d930e7a7337e66 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2231,6 +2231,8 @@ loghelper(PyObject* arg, double (*func)(double)) x = PyLong_AsDouble(arg); if (x == -1.0) { + if (!PyErr_ExceptionMatches(PyExc_OverflowError)) + return NULL; /* Here the conversion to double overflowed, but it's possible to compute the log anyway. Clear the exception and continue. */ PyErr_Clear();