[Python-checkins] Move test_math tests (GH-18098)
Victor Stinner
webhook-mailer at python.org
Tue Jan 21 06:48:20 EST 2020
https://github.com/python/cpython/commit/59e2d26b258c12f18d8d2e789ef741703d6c52d5
commit: 59e2d26b258c12f18d8d2e789ef741703d6c52d5
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-01-21T12:48:16+01:00
summary:
Move test_math tests (GH-18098)
testPerm() and testComb() belong to MathTests, not to IsCloseTests().
test_nextafter() and test_ulp() now use assertIsNaN().
files:
M Lib/test/test_math.py
diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py
index e96fd745970a1..b3301f6a5cf74 100644
--- a/Lib/test/test_math.py
+++ b/Lib/test/test_math.py
@@ -1746,19 +1746,139 @@ def _naive_prod(iterable, start=1):
self.assertEqual(type(prod([1, decimal.Decimal(2.0), 3, 4, 5, 6])),
decimal.Decimal)
- # Custom assertions.
+ def testPerm(self):
+ perm = math.perm
+ factorial = math.factorial
+ # Test if factorial definition is satisfied
+ for n in range(100):
+ for k in range(n + 1):
+ self.assertEqual(perm(n, k),
+ factorial(n) // factorial(n - k))
- def assertIsNaN(self, value):
- if not math.isnan(value):
- self.fail("Expected a NaN, got {!r}.".format(value))
+ # Test for Pascal's identity
+ for n in range(1, 100):
+ for k in range(1, n):
+ self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
- def assertEqualSign(self, x, y):
- """Similar to assertEqual(), but compare also the sign.
+ # Test corner cases
+ for n in range(1, 100):
+ self.assertEqual(perm(n, 0), 1)
+ self.assertEqual(perm(n, 1), n)
+ self.assertEqual(perm(n, n), factorial(n))
- Function useful to compare signed zeros.
- """
- self.assertEqual(x, y)
- self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
+ # Test one argument form
+ for n in range(20):
+ self.assertEqual(perm(n), factorial(n))
+ self.assertEqual(perm(n, None), factorial(n))
+
+ # Raises TypeError if any argument is non-integer or argument count is
+ # not 1 or 2
+ self.assertRaises(TypeError, perm, 10, 1.0)
+ self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
+ self.assertRaises(TypeError, perm, 10, "1")
+ self.assertRaises(TypeError, perm, 10.0, 1)
+ self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
+ self.assertRaises(TypeError, perm, "10", 1)
+
+ self.assertRaises(TypeError, perm)
+ self.assertRaises(TypeError, perm, 10, 1, 3)
+ self.assertRaises(TypeError, perm)
+
+ # Raises Value error if not k or n are negative numbers
+ self.assertRaises(ValueError, perm, -1, 1)
+ self.assertRaises(ValueError, perm, -2**1000, 1)
+ self.assertRaises(ValueError, perm, 1, -1)
+ self.assertRaises(ValueError, perm, 1, -2**1000)
+
+ # Returns zero if k is greater than n
+ self.assertEqual(perm(1, 2), 0)
+ self.assertEqual(perm(1, 2**1000), 0)
+
+ n = 2**1000
+ self.assertEqual(perm(n, 0), 1)
+ self.assertEqual(perm(n, 1), n)
+ self.assertEqual(perm(n, 2), n * (n-1))
+ if support.check_impl_detail(cpython=True):
+ self.assertRaises(OverflowError, perm, n, n)
+
+ for n, k in (True, True), (True, False), (False, False):
+ self.assertEqual(perm(n, k), 1)
+ self.assertIs(type(perm(n, k)), int)
+ self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
+ self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
+ for k in range(3):
+ self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
+ self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
+
+ def testComb(self):
+ comb = math.comb
+ factorial = math.factorial
+ # Test if factorial definition is satisfied
+ for n in range(100):
+ for k in range(n + 1):
+ self.assertEqual(comb(n, k), factorial(n)
+ // (factorial(k) * factorial(n - k)))
+
+ # Test for Pascal's identity
+ for n in range(1, 100):
+ for k in range(1, n):
+ self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
+
+ # Test corner cases
+ for n in range(100):
+ self.assertEqual(comb(n, 0), 1)
+ self.assertEqual(comb(n, n), 1)
+
+ for n in range(1, 100):
+ self.assertEqual(comb(n, 1), n)
+ self.assertEqual(comb(n, n - 1), n)
+
+ # Test Symmetry
+ for n in range(100):
+ for k in range(n // 2):
+ self.assertEqual(comb(n, k), comb(n, n - k))
+
+ # Raises TypeError if any argument is non-integer or argument count is
+ # not 2
+ self.assertRaises(TypeError, comb, 10, 1.0)
+ self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
+ self.assertRaises(TypeError, comb, 10, "1")
+ self.assertRaises(TypeError, comb, 10.0, 1)
+ self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
+ self.assertRaises(TypeError, comb, "10", 1)
+
+ self.assertRaises(TypeError, comb, 10)
+ self.assertRaises(TypeError, comb, 10, 1, 3)
+ self.assertRaises(TypeError, comb)
+
+ # Raises Value error if not k or n are negative numbers
+ self.assertRaises(ValueError, comb, -1, 1)
+ self.assertRaises(ValueError, comb, -2**1000, 1)
+ self.assertRaises(ValueError, comb, 1, -1)
+ self.assertRaises(ValueError, comb, 1, -2**1000)
+
+ # Returns zero if k is greater than n
+ self.assertEqual(comb(1, 2), 0)
+ self.assertEqual(comb(1, 2**1000), 0)
+
+ n = 2**1000
+ self.assertEqual(comb(n, 0), 1)
+ self.assertEqual(comb(n, 1), n)
+ self.assertEqual(comb(n, 2), n * (n-1) // 2)
+ self.assertEqual(comb(n, n), 1)
+ self.assertEqual(comb(n, n-1), n)
+ self.assertEqual(comb(n, n-2), n * (n-1) // 2)
+ if support.check_impl_detail(cpython=True):
+ self.assertRaises(OverflowError, comb, n, n//2)
+
+ for n, k in (True, True), (True, False), (False, False):
+ self.assertEqual(comb(n, k), 1)
+ self.assertIs(type(comb(n, k)), int)
+ self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
+ self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
+ for k in range(3):
+ self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
+ self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
@requires_IEEE_754
def test_nextafter(self):
@@ -1802,9 +1922,9 @@ def test_nextafter(self):
self.assertEqual(math.nextafter(-largest_normal, -INF), -INF)
# NaN
- self.assertTrue(math.isnan(math.nextafter(NAN, 1.0)))
- self.assertTrue(math.isnan(math.nextafter(1.0, NAN)))
- self.assertTrue(math.isnan(math.nextafter(NAN, NAN)))
+ self.assertIsNaN(math.nextafter(NAN, 1.0))
+ self.assertIsNaN(math.nextafter(1.0, NAN))
+ self.assertIsNaN(math.nextafter(NAN, NAN))
@requires_IEEE_754
def test_ulp(self):
@@ -1822,13 +1942,27 @@ def test_ulp(self):
# special cases
self.assertEqual(math.ulp(INF), INF)
- self.assertTrue(math.isnan(math.ulp(math.nan)))
+ self.assertIsNaN(math.ulp(math.nan))
# negative number: ulp(-x) == ulp(x)
for x in (0.0, 1.0, 2 ** 52, 2 ** 64, INF):
with self.subTest(x=x):
self.assertEqual(math.ulp(-x), math.ulp(x))
+ # Custom assertions.
+
+ def assertIsNaN(self, value):
+ if not math.isnan(value):
+ self.fail("Expected a NaN, got {!r}.".format(value))
+
+ def assertEqualSign(self, x, y):
+ """Similar to assertEqual(), but compare also the sign with copysign().
+
+ Function useful to compare signed zeros.
+ """
+ self.assertEqual(x, y)
+ self.assertEqual(math.copysign(1.0, x), math.copysign(1.0, y))
+
class IsCloseTests(unittest.TestCase):
isclose = math.isclose # subclasses should override this
@@ -1952,140 +2086,6 @@ def test_fractions(self):
self.assertAllClose(fraction_examples, rel_tol=1e-8)
self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
- def testPerm(self):
- perm = math.perm
- factorial = math.factorial
- # Test if factorial definition is satisfied
- for n in range(100):
- for k in range(n + 1):
- self.assertEqual(perm(n, k),
- factorial(n) // factorial(n - k))
-
- # Test for Pascal's identity
- for n in range(1, 100):
- for k in range(1, n):
- self.assertEqual(perm(n, k), perm(n - 1, k - 1) * k + perm(n - 1, k))
-
- # Test corner cases
- for n in range(1, 100):
- self.assertEqual(perm(n, 0), 1)
- self.assertEqual(perm(n, 1), n)
- self.assertEqual(perm(n, n), factorial(n))
-
- # Test one argument form
- for n in range(20):
- self.assertEqual(perm(n), factorial(n))
- self.assertEqual(perm(n, None), factorial(n))
-
- # Raises TypeError if any argument is non-integer or argument count is
- # not 1 or 2
- self.assertRaises(TypeError, perm, 10, 1.0)
- self.assertRaises(TypeError, perm, 10, decimal.Decimal(1.0))
- self.assertRaises(TypeError, perm, 10, "1")
- self.assertRaises(TypeError, perm, 10.0, 1)
- self.assertRaises(TypeError, perm, decimal.Decimal(10.0), 1)
- self.assertRaises(TypeError, perm, "10", 1)
-
- self.assertRaises(TypeError, perm)
- self.assertRaises(TypeError, perm, 10, 1, 3)
- self.assertRaises(TypeError, perm)
-
- # Raises Value error if not k or n are negative numbers
- self.assertRaises(ValueError, perm, -1, 1)
- self.assertRaises(ValueError, perm, -2**1000, 1)
- self.assertRaises(ValueError, perm, 1, -1)
- self.assertRaises(ValueError, perm, 1, -2**1000)
-
- # Returns zero if k is greater than n
- self.assertEqual(perm(1, 2), 0)
- self.assertEqual(perm(1, 2**1000), 0)
-
- n = 2**1000
- self.assertEqual(perm(n, 0), 1)
- self.assertEqual(perm(n, 1), n)
- self.assertEqual(perm(n, 2), n * (n-1))
- if support.check_impl_detail(cpython=True):
- self.assertRaises(OverflowError, perm, n, n)
-
- for n, k in (True, True), (True, False), (False, False):
- self.assertEqual(perm(n, k), 1)
- self.assertIs(type(perm(n, k)), int)
- self.assertEqual(perm(IntSubclass(5), IntSubclass(2)), 20)
- self.assertEqual(perm(MyIndexable(5), MyIndexable(2)), 20)
- for k in range(3):
- self.assertIs(type(perm(IntSubclass(5), IntSubclass(k))), int)
- self.assertIs(type(perm(MyIndexable(5), MyIndexable(k))), int)
-
- def testComb(self):
- comb = math.comb
- factorial = math.factorial
- # Test if factorial definition is satisfied
- for n in range(100):
- for k in range(n + 1):
- self.assertEqual(comb(n, k), factorial(n)
- // (factorial(k) * factorial(n - k)))
-
- # Test for Pascal's identity
- for n in range(1, 100):
- for k in range(1, n):
- self.assertEqual(comb(n, k), comb(n - 1, k - 1) + comb(n - 1, k))
-
- # Test corner cases
- for n in range(100):
- self.assertEqual(comb(n, 0), 1)
- self.assertEqual(comb(n, n), 1)
-
- for n in range(1, 100):
- self.assertEqual(comb(n, 1), n)
- self.assertEqual(comb(n, n - 1), n)
-
- # Test Symmetry
- for n in range(100):
- for k in range(n // 2):
- self.assertEqual(comb(n, k), comb(n, n - k))
-
- # Raises TypeError if any argument is non-integer or argument count is
- # not 2
- self.assertRaises(TypeError, comb, 10, 1.0)
- self.assertRaises(TypeError, comb, 10, decimal.Decimal(1.0))
- self.assertRaises(TypeError, comb, 10, "1")
- self.assertRaises(TypeError, comb, 10.0, 1)
- self.assertRaises(TypeError, comb, decimal.Decimal(10.0), 1)
- self.assertRaises(TypeError, comb, "10", 1)
-
- self.assertRaises(TypeError, comb, 10)
- self.assertRaises(TypeError, comb, 10, 1, 3)
- self.assertRaises(TypeError, comb)
-
- # Raises Value error if not k or n are negative numbers
- self.assertRaises(ValueError, comb, -1, 1)
- self.assertRaises(ValueError, comb, -2**1000, 1)
- self.assertRaises(ValueError, comb, 1, -1)
- self.assertRaises(ValueError, comb, 1, -2**1000)
-
- # Returns zero if k is greater than n
- self.assertEqual(comb(1, 2), 0)
- self.assertEqual(comb(1, 2**1000), 0)
-
- n = 2**1000
- self.assertEqual(comb(n, 0), 1)
- self.assertEqual(comb(n, 1), n)
- self.assertEqual(comb(n, 2), n * (n-1) // 2)
- self.assertEqual(comb(n, n), 1)
- self.assertEqual(comb(n, n-1), n)
- self.assertEqual(comb(n, n-2), n * (n-1) // 2)
- if support.check_impl_detail(cpython=True):
- self.assertRaises(OverflowError, comb, n, n//2)
-
- for n, k in (True, True), (True, False), (False, False):
- self.assertEqual(comb(n, k), 1)
- self.assertIs(type(comb(n, k)), int)
- self.assertEqual(comb(IntSubclass(5), IntSubclass(2)), 10)
- self.assertEqual(comb(MyIndexable(5), MyIndexable(2)), 10)
- for k in range(3):
- self.assertIs(type(comb(IntSubclass(5), IntSubclass(k))), int)
- self.assertIs(type(comb(MyIndexable(5), MyIndexable(k))), int)
-
def test_main():
from doctest import DocFileSuite
More information about the Python-checkins
mailing list