From cd77dae4800c503719f6a28098229d4c88e8df53 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 25 May 2026 23:55:47 +0200 Subject: [PATCH 1/5] gh-149879: Fix test_math on Cygwin Skip tests which fail on Cygwin: when Python is built with newlib C library. --- Lib/test/test_math.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 8f9a239bead1309..147fff46e6eea3d 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -37,6 +37,9 @@ math_testcases = os.path.join(test_dir, 'mathdata', 'math_testcases.txt') test_file = os.path.join(test_dir, 'mathdata', 'cmath_testcases.txt') +skip_on_newlib = unittest.skipIf(sys.platform == 'cygwin', + 'the test fails on newlib C library') + def to_ulps(x): """Convert a non-NaN float x to an integer, in such a way that @@ -922,6 +925,7 @@ def testHypot(self): @requires_IEEE_754 @unittest.skipIf(HAVE_DOUBLE_ROUNDING, "hypot() loses accuracy on machines with double rounding") + @skip_on_newlib def testHypotAccuracy(self): # Verify improved accuracy in cases that were known to be inaccurate. # @@ -1244,6 +1248,7 @@ def testLog1p(self): self.assertEqual(math.log1p(INF), INF) @requires_IEEE_754 + @skip_on_newlib def testLog2(self): self.assertRaises(TypeError, math.log2) @@ -1276,6 +1281,7 @@ def testLog2(self): @requires_IEEE_754 # log2() is not accurate enough on Mac OS X Tiger (10.4) @support.requires_mac_ver(10, 5) + @skip_on_newlib def testLog2Exact(self): # Check that we get exact equality for log2 of powers of 2. actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] @@ -2615,6 +2621,7 @@ def test_fma_nan_results(self): self.assertIsNaN(math.fma(a, math.nan, b)) self.assertIsNaN(math.fma(a, b, math.nan)) + @skip_on_newlib def test_fma_infinities(self): # Cases involving infinite inputs or results. positives = [1e-300, 2.3, 1e300, math.inf] @@ -2685,7 +2692,7 @@ def test_fma_infinities(self): # gh-73468: On some platforms, libc fma() doesn't implement IEE 754-2008 # properly: it doesn't use the right sign when the result is zero. @unittest.skipIf( - sys.platform.startswith(("freebsd", "wasi", "netbsd", "emscripten")) + sys.platform.startswith(("freebsd", "wasi", "netbsd", "emscripten", "cygwin")) or (sys.platform == "android" and platform.machine() == "x86_64") or support.linked_to_musl(), # gh-131032 f"this platform doesn't implement IEE 754-2008 properly") @@ -2743,6 +2750,7 @@ def test_fma_zero_result(self): self.assertIsNegativeZero(math.fma(y-x, -(x+y), -z)) self.assertIsPositiveZero(math.fma(x-y, -(x+y), z)) + @skip_on_newlib def test_fma_overflow(self): a = b = float.fromhex('0x1p512') c = float.fromhex('0x1p1023') @@ -2776,10 +2784,12 @@ def test_fma_overflow(self): c = float.fromhex('0x1.fffffffffffffp+1023') self.assertEqual(math.fma(a, b, -c), c) + @skip_on_newlib def test_fma_single_round(self): a = float.fromhex('0x1p-50') self.assertEqual(math.fma(a - 1.0, a + 1.0, 1.0), a*a) + @skip_on_newlib def test_random(self): # A collection of randomly generated inputs for which the naive FMA # (with two rounds) gives a different result from a singly-rounded FMA. From 7e743a3a4573b193b0e2f3e0d692a6372b74f70f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 26 May 2026 02:33:26 +0200 Subject: [PATCH 2/5] Fix test_statistics --- Lib/test/test_statistics.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 677a87b51b91925..64ad01e51ae19f1 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -138,6 +138,10 @@ def approx_equal(x, y, tol=1e-12, rel=1e-7): return actual_error <= allowed_error +skip_on_newlib = unittest.skipIf(sys.platform == 'cygwin', + 'the test fails on newlib C library') + + # This class exists only as somewhere to stick a docstring containing # doctests. The following docstring and tests were originally in a separate # module. Now that it has been merged in here, I need somewhere to hang the. @@ -2799,6 +2803,7 @@ def test_sqrtprod_helper_function_fundamentals(self): @unittest.skipIf(HAVE_DOUBLE_ROUNDING, "accuracy not guaranteed on machines with double rounding") @support.cpython_only # Allow for a weaker sumprod() implementation + @skip_on_newlib def test_sqrtprod_helper_function_improved_accuracy(self): # Test a known example where accuracy is improved x, y, target = 0.8035720646477457, 0.7957468097636939, 0.7996498651651661 From a144a7ace8d2fdb9a7794690618fdf47867866eb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 26 May 2026 04:08:09 +0200 Subject: [PATCH 3/5] Move @skip_on_newlib to test.support --- Lib/test/support/__init__.py | 4 ++++ Lib/test/test_math.py | 17 +++++++---------- Lib/test/test_statistics.py | 6 +----- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 87082ff37d1e58d..62804e2fa2d68e9 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2806,6 +2806,10 @@ def exceeds_recursion_limit(): is_s390x = hasattr(os, 'uname') and os.uname().machine == 's390x' skip_on_s390x = unittest.skipIf(is_s390x, 'skipped on s390x') +# Cygwin uses the newlib C library +skip_on_newlib = unittest.skipIf(sys.platform == 'cygwin', + 'the test fails on newlib C library') + Py_TRACE_REFS = hasattr(sys, 'getobjects') _JIT_ENABLED = sys._jit.is_enabled() diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 147fff46e6eea3d..35aba3c79961d9f 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -37,9 +37,6 @@ math_testcases = os.path.join(test_dir, 'mathdata', 'math_testcases.txt') test_file = os.path.join(test_dir, 'mathdata', 'cmath_testcases.txt') -skip_on_newlib = unittest.skipIf(sys.platform == 'cygwin', - 'the test fails on newlib C library') - def to_ulps(x): """Convert a non-NaN float x to an integer, in such a way that @@ -925,7 +922,7 @@ def testHypot(self): @requires_IEEE_754 @unittest.skipIf(HAVE_DOUBLE_ROUNDING, "hypot() loses accuracy on machines with double rounding") - @skip_on_newlib + @support.skip_on_newlib def testHypotAccuracy(self): # Verify improved accuracy in cases that were known to be inaccurate. # @@ -1248,7 +1245,7 @@ def testLog1p(self): self.assertEqual(math.log1p(INF), INF) @requires_IEEE_754 - @skip_on_newlib + @support.skip_on_newlib def testLog2(self): self.assertRaises(TypeError, math.log2) @@ -1281,7 +1278,7 @@ def testLog2(self): @requires_IEEE_754 # log2() is not accurate enough on Mac OS X Tiger (10.4) @support.requires_mac_ver(10, 5) - @skip_on_newlib + @support.skip_on_newlib def testLog2Exact(self): # Check that we get exact equality for log2 of powers of 2. actual = [math.log2(math.ldexp(1.0, n)) for n in range(-1074, 1024)] @@ -2621,7 +2618,7 @@ def test_fma_nan_results(self): self.assertIsNaN(math.fma(a, math.nan, b)) self.assertIsNaN(math.fma(a, b, math.nan)) - @skip_on_newlib + @support.skip_on_newlib def test_fma_infinities(self): # Cases involving infinite inputs or results. positives = [1e-300, 2.3, 1e300, math.inf] @@ -2750,7 +2747,7 @@ def test_fma_zero_result(self): self.assertIsNegativeZero(math.fma(y-x, -(x+y), -z)) self.assertIsPositiveZero(math.fma(x-y, -(x+y), z)) - @skip_on_newlib + @support.skip_on_newlib def test_fma_overflow(self): a = b = float.fromhex('0x1p512') c = float.fromhex('0x1p1023') @@ -2784,12 +2781,12 @@ def test_fma_overflow(self): c = float.fromhex('0x1.fffffffffffffp+1023') self.assertEqual(math.fma(a, b, -c), c) - @skip_on_newlib + @support.skip_on_newlib def test_fma_single_round(self): a = float.fromhex('0x1p-50') self.assertEqual(math.fma(a - 1.0, a + 1.0, 1.0), a*a) - @skip_on_newlib + @support.skip_on_newlib def test_random(self): # A collection of randomly generated inputs for which the naive FMA # (with two rounds) gives a different result from a singly-rounded FMA. diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 64ad01e51ae19f1..de7d13651cfea62 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -16,7 +16,7 @@ import sys import unittest from test import support -from test.support import import_helper, requires_IEEE_754 +from test.support import import_helper, requires_IEEE_754, skip_on_newlib from decimal import Decimal from fractions import Fraction @@ -138,10 +138,6 @@ def approx_equal(x, y, tol=1e-12, rel=1e-7): return actual_error <= allowed_error -skip_on_newlib = unittest.skipIf(sys.platform == 'cygwin', - 'the test fails on newlib C library') - - # This class exists only as somewhere to stick a docstring containing # doctests. The following docstring and tests were originally in a separate # module. Now that it has been merged in here, I need somewhere to hang the. From 412dfa9b8e38d567ac00f32a4acb9e16e7a84392 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 26 May 2026 04:09:05 +0200 Subject: [PATCH 4/5] Rename test_random() to test_fma_random() --- Lib/test/test_math.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 35aba3c79961d9f..892f812adc5c7fd 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -2787,7 +2787,7 @@ def test_fma_single_round(self): self.assertEqual(math.fma(a - 1.0, a + 1.0, 1.0), a*a) @support.skip_on_newlib - def test_random(self): + def test_fma_random(self): # A collection of randomly generated inputs for which the naive FMA # (with two rounds) gives a different result from a singly-rounded FMA. From 9cb8cf57d4a06898d374b6881c598748c7fecd36 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 26 May 2026 04:12:44 +0200 Subject: [PATCH 5/5] unskip testLog2() Move tests on large integer values from testLog2() to testLog2Exact(). --- Lib/test/test_math.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 892f812adc5c7fd..7c40f9f94c37ad9 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1245,7 +1245,6 @@ def testLog1p(self): self.assertEqual(math.log1p(INF), INF) @requires_IEEE_754 - @support.skip_on_newlib def testLog2(self): self.assertRaises(TypeError, math.log2) @@ -1255,12 +1254,6 @@ def testLog2(self): self.assertEqual(math.log2(4), 2.0) self.assertEqual(math.log2(MyIndexable(4)), 2.0) - # Large integer values - self.assertEqual(math.log2(2**1023), 1023.0) - self.assertEqual(math.log2(2**1024), 1024.0) - self.assertEqual(math.log2(2**2000), 2000.0) - self.assertEqual(math.log2(MyIndexable(2**2000)), 2000.0) - self.assertRaises(ValueError, math.log2, 0.0) self.assertRaises(ValueError, math.log2, 0) self.assertRaises(ValueError, math.log2, MyIndexable(0)) @@ -1285,6 +1278,12 @@ def testLog2Exact(self): expected = [float(n) for n in range(-1074, 1024)] self.assertEqual(actual, expected) + # Large integer values + self.assertEqual(math.log2(2**1023), 1023.0) + self.assertEqual(math.log2(2**1024), 1024.0) + self.assertEqual(math.log2(2**2000), 2000.0) + self.assertEqual(math.log2(MyIndexable(2**2000)), 2000.0) + def testLog10(self): self.assertRaises(TypeError, math.log10) self.ftest('log10(0.1)', math.log10(0.1), -1)