Skip to content

Commit

Permalink
pythongh-102837: more tests for the math module (pythonGH-111930)
Browse files Browse the repository at this point in the history
Add tests to improve coverage:

* fsum: L1369, L1379, L1383, L1412
* trunc: L2081
* log: L2267
* dist: L2577, L2579
* hypot: L2632
* sumprod: L2744, L2754, L2774, L2778, L2781, L2785, L2831, L2835, L2838
* pow: L2982
* prod: L3294, L3308, L3318-3330

// line numbers wrt to 9dc4fb8
  • Loading branch information
skirpichev committed Nov 13, 2023
1 parent a430b4f commit c61de45
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions Lib/test/test_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,7 @@ 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),
([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),
Expand Down Expand Up @@ -733,9 +734,20 @@ 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.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'])
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
Expand Down Expand Up @@ -797,6 +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), 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))
Expand Down Expand Up @@ -948,6 +962,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))
Expand Down Expand Up @@ -1005,6 +1023,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()
Expand Down Expand Up @@ -1175,6 +1199,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)
Expand Down Expand Up @@ -1245,6 +1270,8 @@ 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)

# Type preservation and coercion
for v in [
Expand All @@ -1270,11 +1297,20 @@ 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])
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)
self.assertRaises(OverflowError, sumprod, [10**1000], [1.0])
self.assertRaises(OverflowError, sumprod, [1.0], [10**1000])

# Error in iterator
def raise_after(n):
for i in range(n):
Expand All @@ -1285,6 +1321,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):
Expand Down Expand Up @@ -1524,6 +1565,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.)
Expand Down Expand Up @@ -1880,6 +1922,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)
Expand All @@ -1888,6 +1932,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))
Expand Down Expand Up @@ -2088,6 +2133,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)
Expand All @@ -2099,6 +2146,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)
Expand Down

0 comments on commit c61de45

Please sign in to comment.