mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Issue #7554: Various fixups in test_cmath.py: remove code duplication,
use new-style formatting. Thanks Florent Xicluna for the patch.
This commit is contained in:
parent
ed284991e1
commit
603ae9e371
1 changed files with 49 additions and 62 deletions
|
@ -46,37 +46,6 @@ complex_nans = [complex(x, y) for x, y in [
|
||||||
(INF, NAN)
|
(INF, NAN)
|
||||||
]]
|
]]
|
||||||
|
|
||||||
def almostEqualF(a, b, rel_err=2e-15, abs_err = 5e-323):
|
|
||||||
"""Determine whether floating-point values a and b are equal to within
|
|
||||||
a (small) rounding error. The default values for rel_err and
|
|
||||||
abs_err are chosen to be suitable for platforms where a float is
|
|
||||||
represented by an IEEE 754 double. They allow an error of between
|
|
||||||
9 and 19 ulps."""
|
|
||||||
|
|
||||||
# special values testing
|
|
||||||
if math.isnan(a):
|
|
||||||
return math.isnan(b)
|
|
||||||
if math.isinf(a):
|
|
||||||
return a == b
|
|
||||||
|
|
||||||
# if both a and b are zero, check whether they have the same sign
|
|
||||||
# (in theory there are examples where it would be legitimate for a
|
|
||||||
# and b to have opposite signs; in practice these hardly ever
|
|
||||||
# occur).
|
|
||||||
if not a and not b:
|
|
||||||
return math.copysign(1., a) == math.copysign(1., b)
|
|
||||||
|
|
||||||
# if a-b overflows, or b is infinite, return False. Again, in
|
|
||||||
# theory there are examples where a is within a few ulps of the
|
|
||||||
# max representable float, and then b could legitimately be
|
|
||||||
# infinite. In practice these examples are rare.
|
|
||||||
try:
|
|
||||||
absolute_error = abs(b-a)
|
|
||||||
except OverflowError:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return absolute_error <= max(abs_err, rel_err * abs(a))
|
|
||||||
|
|
||||||
class CMathTests(unittest.TestCase):
|
class CMathTests(unittest.TestCase):
|
||||||
# list of all functions in cmath
|
# list of all functions in cmath
|
||||||
test_functions = [getattr(cmath, fname) for fname in [
|
test_functions = [getattr(cmath, fname) for fname in [
|
||||||
|
@ -93,47 +62,63 @@ class CMathTests(unittest.TestCase):
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.test_values.close()
|
self.test_values.close()
|
||||||
|
|
||||||
def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323):
|
def rAssertAlmostEqual(self, a, b, rel_err = 2e-15, abs_err = 5e-323,
|
||||||
"""Check that two floating-point numbers are almost equal."""
|
msg=None):
|
||||||
|
"""Fail if the two floating-point numbers are not almost equal.
|
||||||
|
|
||||||
|
Determine whether floating-point values a and b are equal to within
|
||||||
|
a (small) rounding error. The default values for rel_err and
|
||||||
|
abs_err are chosen to be suitable for platforms where a float is
|
||||||
|
represented by an IEEE 754 double. They allow an error of between
|
||||||
|
9 and 19 ulps.
|
||||||
|
"""
|
||||||
|
|
||||||
# special values testing
|
# special values testing
|
||||||
if math.isnan(a):
|
if math.isnan(a):
|
||||||
if math.isnan(b):
|
if math.isnan(b):
|
||||||
return
|
return
|
||||||
self.fail("%s should be nan" % repr(b))
|
self.fail(msg or '{!r} should be nan'.format(b))
|
||||||
|
|
||||||
if math.isinf(a):
|
if math.isinf(a):
|
||||||
if a == b:
|
if a == b:
|
||||||
return
|
return
|
||||||
self.fail("finite result where infinity excpected: "
|
self.fail(msg or 'finite result where infinity expected: '
|
||||||
"expected %s, got %s" % (repr(a), repr(b)))
|
'expected {!r}, got {!r}'.format(a, b))
|
||||||
|
|
||||||
|
# if both a and b are zero, check whether they have the same sign
|
||||||
|
# (in theory there are examples where it would be legitimate for a
|
||||||
|
# and b to have opposite signs; in practice these hardly ever
|
||||||
|
# occur).
|
||||||
if not a and not b:
|
if not a and not b:
|
||||||
if math.atan2(a, -1.) != math.atan2(b, -1.):
|
if math.copysign(1., a) != math.copysign(1., b):
|
||||||
self.fail("zero has wrong sign: expected %s, got %s" %
|
self.fail(msg or 'zero has wrong sign: expected {!r}, '
|
||||||
(repr(a), repr(b)))
|
'got {!r}'.format(a, b))
|
||||||
|
|
||||||
# test passes if either the absolute error or the relative
|
|
||||||
# error is sufficiently small. The defaults amount to an
|
|
||||||
# error of between 9 ulps and 19 ulps on an IEEE-754 compliant
|
|
||||||
# machine.
|
|
||||||
|
|
||||||
|
# if a-b overflows, or b is infinite, return False. Again, in
|
||||||
|
# theory there are examples where a is within a few ulps of the
|
||||||
|
# max representable float, and then b could legitimately be
|
||||||
|
# infinite. In practice these examples are rare.
|
||||||
try:
|
try:
|
||||||
absolute_error = abs(b-a)
|
absolute_error = abs(b-a)
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
# test passes if either the absolute error or the relative
|
||||||
|
# error is sufficiently small. The defaults amount to an
|
||||||
|
# error of between 9 ulps and 19 ulps on an IEEE-754 compliant
|
||||||
|
# machine.
|
||||||
if absolute_error <= max(abs_err, rel_err * abs(a)):
|
if absolute_error <= max(abs_err, rel_err * abs(a)):
|
||||||
return
|
return
|
||||||
self.fail("%s and %s are not sufficiently close" % (repr(a), repr(b)))
|
self.fail(msg or
|
||||||
|
'{!r} and {!r} are not sufficiently close'.format(a, b))
|
||||||
|
|
||||||
def test_constants(self):
|
def test_constants(self):
|
||||||
e_expected = 2.71828182845904523536
|
e_expected = 2.71828182845904523536
|
||||||
pi_expected = 3.14159265358979323846
|
pi_expected = 3.14159265358979323846
|
||||||
self.assertAlmostEqual(cmath.pi, pi_expected, places=9,
|
self.assertAlmostEqual(cmath.pi, pi_expected, places=9,
|
||||||
msg="cmath.pi is %s; should be %s" % (cmath.pi, pi_expected))
|
msg="cmath.pi is {}; should be {}".format(cmath.pi, pi_expected))
|
||||||
self.assertAlmostEqual(cmath.e, e_expected, places=9,
|
self.assertAlmostEqual(cmath.e, e_expected, places=9,
|
||||||
msg="cmath.e is %s; should be %s" % (cmath.e, e_expected))
|
msg="cmath.e is {}; should be {}".format(cmath.e, e_expected))
|
||||||
|
|
||||||
def test_user_object(self):
|
def test_user_object(self):
|
||||||
# Test automatic calling of __complex__ and __float__ by cmath
|
# Test automatic calling of __complex__ and __float__ by cmath
|
||||||
|
@ -325,8 +310,8 @@ class CMathTests(unittest.TestCase):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai)
|
self.fail('ValueError not raised in test '
|
||||||
self.fail('ValueError not raised in test %s' % test_str)
|
'{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai))
|
||||||
|
|
||||||
if 'overflow' in flags:
|
if 'overflow' in flags:
|
||||||
try:
|
try:
|
||||||
|
@ -334,8 +319,8 @@ class CMathTests(unittest.TestCase):
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
test_str = "%s: %s(complex(%r, %r))" % (id, fn, ar, ai)
|
self.fail('OverflowError not raised in test '
|
||||||
self.fail('OverflowError not raised in test %s' % test_str)
|
'{}: {}(complex({!r}, {!r}))'.format(id, fn, ar, ai))
|
||||||
|
|
||||||
actual = function(arg)
|
actual = function(arg)
|
||||||
|
|
||||||
|
@ -353,17 +338,19 @@ class CMathTests(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
real_abs_err = 5e-323
|
real_abs_err = 5e-323
|
||||||
|
|
||||||
if not (almostEqualF(expected.real, actual.real,
|
error_message = (
|
||||||
abs_err = real_abs_err) and
|
'{}: {}(complex({!r}, {!r}))\n'
|
||||||
almostEqualF(expected.imag, actual.imag)):
|
'Expected: complex({!r}, {!r})\n'
|
||||||
error_message = (
|
'Received: complex({!r}, {!r})\n'
|
||||||
"%s: %s(complex(%r, %r))\n" % (id, fn, ar, ai) +
|
'Received value insufficiently close to expected value.'
|
||||||
"Expected: complex(%r, %r)\n" %
|
).format(id, fn, ar, ai,
|
||||||
(expected.real, expected.imag) +
|
expected.real, expected.imag,
|
||||||
"Received: complex(%r, %r)\n" %
|
actual.real, actual.imag)
|
||||||
(actual.real, actual.imag) +
|
self.rAssertAlmostEqual(expected.real, actual.real,
|
||||||
"Received value insufficiently close to expected value.")
|
abs_err=real_abs_err,
|
||||||
self.fail(error_message)
|
msg=error_message)
|
||||||
|
self.rAssertAlmostEqual(expected.imag, actual.imag,
|
||||||
|
msg=error_message)
|
||||||
|
|
||||||
def assertCISEqual(self, a, b):
|
def assertCISEqual(self, a, b):
|
||||||
eps = 1E-7
|
eps = 1E-7
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue