Skip to content
10 changes: 10 additions & 0 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"run_no_yield_async_fn", "run_yielding_async_fn", "async_yield",
"reset_code", "on_github_actions",
"requires_root_user", "requires_non_root_user",
"skip_if_double_rounding",
]


Expand Down Expand Up @@ -514,6 +515,15 @@ def dec(*args, **kwargs):
float.__getformat__("double").startswith("IEEE"),
"test requires IEEE 754 doubles")

# detect evidence of double-rounding:
x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
skip_if_double_rounding = unittest.skipIf(HAVE_DOUBLE_ROUNDING,
"accuracy not guaranteed on "
"machines with double rounding")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since all tests use @skip_if_double_rounding, I don't think that it's useful to expose HAVE_DOUBLE_ROUNDING variable. I suggest removing unused variables:

del x, y, HAVE_DOUBLE_ROUNDING

del x, y, HAVE_DOUBLE_ROUNDING


def requires_zlib(reason='requires zlib'):
try:
import zlib
Expand Down
10 changes: 2 additions & 8 deletions Lib/test/test_builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,14 @@
from test.support.script_helper import assert_python_ok
from test.support.testcase import ComplexesAreIdenticalMixin
from test.support.warnings_helper import check_warnings
from test.support import requires_IEEE_754
from test.support import requires_IEEE_754, skip_if_double_rounding
from unittest.mock import MagicMock, patch
try:
import pty, signal
except ImportError:
pty = signal = None


# Detect evidence of double-rounding: sum() does not always
# get improved accuracy on machines that suffer from double rounding.
x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)

# used as proof of globals being used
A_GLOBAL_VALUE = 123
A_SENTINEL = sentinel("A_SENTINEL")
Expand Down Expand Up @@ -2235,8 +2230,7 @@ def __getitem__(self, index):
complex(2, -0.0))

@requires_IEEE_754
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
"sum accuracy not guaranteed on machines with double rounding")
@skip_if_double_rounding
@support.cpython_only # Other implementations may choose a different algorithm
def test_sum_accuracy(self):
self.assertEqual(sum([0.1] * 10), 1.0)
Expand Down
20 changes: 6 additions & 14 deletions Lib/test/test_math.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Python test set -- math module
# XXXX Should not do tests around zero only

from test.support import verbose, requires_IEEE_754
from test.support import (verbose, requires_IEEE_754,
skip_if_double_rounding)
from test import support
import unittest
import fractions
Expand All @@ -23,11 +24,6 @@
FLOAT_MAX = sys.float_info.max
FLOAT_MIN = sys.float_info.min

# detect evidence of double-rounding: fsum is not always correctly
# rounded on machines that suffer from double rounding.
x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)

# locate file with test values
if __name__ == '__main__':
file = sys.argv[0]
Expand Down Expand Up @@ -683,8 +679,7 @@ def testfrexp(name, result, expected):
self.assertTrue(math.isnan(math.frexp(NAN)[0]))

@requires_IEEE_754
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
"fsum is not exact on machines with double rounding")
@skip_if_double_rounding
def testFsum(self):
# math.fsum relies on exact rounding for correct operation.
# There's a known problem with IA32 floating-point that causes
Expand Down Expand Up @@ -920,8 +915,7 @@ def testHypot(self):
self.assertRaises(TypeError, math.hypot, *([1.0]*18), 'spam')

@requires_IEEE_754
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
"hypot() loses accuracy on machines with double rounding")
@skip_if_double_rounding
@support.skip_on_newlib
def testHypotAccuracy(self):
# Verify improved accuracy in cases that were known to be inaccurate.
Expand Down Expand Up @@ -1412,8 +1406,7 @@ def __rmul__(self, other):
self.assertEqual(sumprod(*args), 0.0)

@requires_IEEE_754
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
"sumprod() accuracy not guaranteed on machines with double rounding")
@skip_if_double_rounding
@support.cpython_only # Other implementations may choose a different algorithm
def test_sumprod_accuracy(self):
sumprod = math.sumprod
Expand Down Expand Up @@ -1498,8 +1491,7 @@ def run(func, *args):
)

@requires_IEEE_754
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
"sumprod() accuracy not guaranteed on machines with double rounding")
@skip_if_double_rounding
@support.cpython_only # Other implementations may choose a different algorithm
@support.requires_resource('cpu')
def test_sumprod_extended_precision_accuracy(self):
Expand Down
12 changes: 3 additions & 9 deletions Lib/test/test_statistics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
import sys
import unittest
from test import support
from test.support import import_helper, requires_IEEE_754, skip_on_newlib
from test.support import (import_helper, requires_IEEE_754,
skip_if_double_rounding, skip_on_newlib)

from decimal import Decimal
from fractions import Fraction
Expand All @@ -28,12 +29,6 @@

# === Helper functions and class ===

# Test copied from Lib/test/test_math.py
# detect evidence of double-rounding: fsum is not always correctly
# rounded on machines that suffer from double rounding.
x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)

def sign(x):
"""Return -1.0 for negatives, including -0.0, otherwise +1.0."""
return math.copysign(1, x)
Expand Down Expand Up @@ -2796,8 +2791,7 @@ def test_sqrtprod_helper_function_fundamentals(self):
self.assertEqual(sign(actual), sign(expected))

@requires_IEEE_754
@unittest.skipIf(HAVE_DOUBLE_ROUNDING,
"accuracy not guaranteed on machines with double rounding")
@skip_if_double_rounding
@support.cpython_only # Allow for a weaker sumprod() implementation
@skip_on_newlib
def test_sqrtprod_helper_function_improved_accuracy(self):
Expand Down
Loading