From 1933e5f56e44f9cfbe7a48706bd71dbe4d7851a5 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Thu, 8 Sep 2022 17:00:42 +0900 Subject: [PATCH 1/2] Add `math.exp2` --- Lib/test/test_math.py | 11 +++++++++++ stdlib/src/math.rs | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 91d071f7b46..34e37ef23bc 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -485,6 +485,17 @@ def testExp(self): self.assertTrue(math.isnan(math.exp(NAN))) self.assertRaises(OverflowError, math.exp, 1000000) + def testExp2(self): + self.assertRaises(TypeError, math.exp2) + self.ftest('exp2(-1)', math.exp2(-1), 0.5) + self.ftest('exp2(0)', math.exp2(0), 1) + self.ftest('exp2(1)', math.exp2(1), 2) + self.ftest('exp2(2.3)', math.exp2(2.3), 4.924577653379665) + self.assertEqual(math.exp2(INF), INF) + self.assertEqual(math.exp2(NINF), 0.) + self.assertTrue(math.isnan(math.exp2(NAN))) + self.assertRaises(OverflowError, math.exp2, 1000000) + def testFabs(self): self.assertRaises(TypeError, math.fabs) self.ftest('fabs(-1)', math.fabs(-1), 1) diff --git a/stdlib/src/math.rs b/stdlib/src/math.rs index d4ad0f55c43..6ceb0e4917a 100644 --- a/stdlib/src/math.rs +++ b/stdlib/src/math.rs @@ -120,6 +120,11 @@ mod math { call_math_func!(exp, x, vm) } + #[pyfunction] + fn exp2(x: ArgIntoFloat, vm: &VirtualMachine) -> PyResult { + call_math_func!(exp2, x, vm) + } + #[pyfunction] fn expm1(x: ArgIntoFloat, vm: &VirtualMachine) -> PyResult { call_math_func!(exp_m1, x, vm) From ea4f2e7bac2b71c84d5e5e75533068ad077b38e9 Mon Sep 17 00:00:00 2001 From: Gyubong Date: Sun, 11 Sep 2022 11:16:11 +0900 Subject: [PATCH 2/2] Update test_math.py from CPython v3.12.0a0 --- Lib/test/test_math.py | 69 ++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 34e37ef23bc..456695ecef8 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1,7 +1,7 @@ # Python test set -- math module # XXXX Should not do tests around zero only -from test.support import run_unittest, verbose, requires_IEEE_754 +from test.support import verbose, requires_IEEE_754 from test import support import unittest import itertools @@ -377,6 +377,24 @@ def testAtan2(self): self.assertTrue(math.isnan(math.atan2(NAN, INF))) self.assertTrue(math.isnan(math.atan2(NAN, NAN))) + # TODO: RUSTPYTHON + @unittest.expectedFailure + def testCbrt(self): + self.assertRaises(TypeError, math.cbrt) + self.ftest('cbrt(0)', math.cbrt(0), 0) + self.ftest('cbrt(1)', math.cbrt(1), 1) + self.ftest('cbrt(8)', math.cbrt(8), 2) + self.ftest('cbrt(0.0)', math.cbrt(0.0), 0.0) + self.ftest('cbrt(-0.0)', math.cbrt(-0.0), -0.0) + self.ftest('cbrt(1.2)', math.cbrt(1.2), 1.062658569182611) + self.ftest('cbrt(-2.6)', math.cbrt(-2.6), -1.375068867074141) + self.ftest('cbrt(27)', math.cbrt(27), 3) + self.ftest('cbrt(-1)', math.cbrt(-1), -1) + self.ftest('cbrt(-27)', math.cbrt(-27), -3) + self.assertEqual(math.cbrt(INF), INF) + self.assertEqual(math.cbrt(NINF), NINF) + self.assertTrue(math.isnan(math.cbrt(NAN))) + def testCeil(self): self.assertRaises(TypeError, math.ceil) self.assertEqual(int, type(math.ceil(0.5))) @@ -1209,6 +1227,8 @@ def testmodf(name, result, expected): self.assertTrue(math.isnan(modf_nan[0])) self.assertTrue(math.isnan(modf_nan[1])) + # TODO: RUSTPYTHON + @unittest.expectedFailure def testPow(self): self.assertRaises(TypeError, math.pow) self.ftest('pow(0,1)', math.pow(0,1), 0) @@ -1234,7 +1254,7 @@ def testPow(self): self.assertRaises(ValueError, math.pow, 0., -2.) self.assertRaises(ValueError, math.pow, 0., -2.3) self.assertRaises(ValueError, math.pow, 0., -3.) - self.assertRaises(ValueError, math.pow, 0., NINF) + self.assertEqual(math.pow(0., NINF), INF) self.assertTrue(math.isnan(math.pow(0., NAN))) # pow(INF, x) @@ -1260,7 +1280,7 @@ def testPow(self): self.assertRaises(ValueError, math.pow, -0., -2.) self.assertRaises(ValueError, math.pow, -0., -2.3) self.assertRaises(ValueError, math.pow, -0., -3.) - self.assertRaises(ValueError, math.pow, -0., NINF) + self.assertEqual(math.pow(-0., NINF), INF) self.assertTrue(math.isnan(math.pow(-0., NAN))) # pow(NINF, x) @@ -1519,6 +1539,10 @@ def testSinh(self): def testSqrt(self): self.assertRaises(TypeError, math.sqrt) self.ftest('sqrt(0)', math.sqrt(0), 0) + self.ftest('sqrt(0)', math.sqrt(0.0), 0.0) + self.ftest('sqrt(2.5)', math.sqrt(2.5), 1.5811388300841898) + self.ftest('sqrt(0.25)', math.sqrt(0.25), 0.5) + self.ftest('sqrt(25.25)', math.sqrt(25.25), 5.024937810560445) self.ftest('sqrt(1)', math.sqrt(1), 1) self.ftest('sqrt(4)', math.sqrt(4), 2) self.assertEqual(math.sqrt(INF), INF) @@ -1808,16 +1832,22 @@ def test_prod(self): self.assertRaises(TypeError, prod) self.assertRaises(TypeError, prod, 42) self.assertRaises(TypeError, prod, ['a', 'b', 'c']) - self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '') - self.assertRaises(TypeError, prod, [b'a', b'c'], b'') + self.assertRaises(TypeError, prod, ['a', 'b', 'c'], start='') + self.assertRaises(TypeError, prod, [b'a', b'c'], start=b'') values = [bytearray(b'a'), bytearray(b'b')] - self.assertRaises(TypeError, prod, values, bytearray(b'')) + self.assertRaises(TypeError, prod, values, start=bytearray(b'')) self.assertRaises(TypeError, prod, [[1], [2], [3]]) self.assertRaises(TypeError, prod, [{2:3}]) - self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3}) - self.assertRaises(TypeError, prod, [[1], [2], [3]], []) + self.assertRaises(TypeError, prod, [{2:3}]*2, start={2:3}) + self.assertRaises(TypeError, prod, [[1], [2], [3]], start=[]) + + # Some odd cases + self.assertEqual(prod([2, 3], start='ab'), 'abababababab') + self.assertEqual(prod([2, 3], start=[1, 2]), [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]) + self.assertEqual(prod([], start={2: 3}), {2:3}) + with self.assertRaises(TypeError): - prod([10, 20], [30, 40]) # start is a keyword-only argument + prod([10, 20], 1) # start is a keyword-only argument self.assertEqual(prod([0, 1, 2, 3]), 0) self.assertEqual(prod([1, 0, 2, 3]), 0) @@ -1877,8 +1907,8 @@ 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): + for n in range(500): + for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)): self.assertEqual(perm(n, k), factorial(n) // factorial(n - k)) @@ -1941,8 +1971,8 @@ 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): + for n in range(500): + for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)): self.assertEqual(comb(n, k), factorial(n) // (factorial(k) * factorial(n - k))) @@ -2230,13 +2260,10 @@ def test_fractions(self): self.assertAllNotClose(fraction_examples, rel_tol=1e-9) -def test_main(): - # from doctest import DocFileSuite - suite = unittest.TestSuite() - suite.addTest(unittest.makeSuite(MathTests)) - suite.addTest(unittest.makeSuite(IsCloseTests)) - # suite.addTest(DocFileSuite("ieee754.txt")) - run_unittest(suite) +def load_tests(loader, tests, pattern): + from doctest import DocFileSuite + # tests.addTest(DocFileSuite("ieee754.txt")) + return tests if __name__ == '__main__': - test_main() + unittest.main()