@@ -235,6 +235,10 @@ def __init__(self, value):
235235 def __index__ (self ):
236236 return self .value
237237
238+ class BadDescr :
239+ def __get__ (self , obj , objtype = None ):
240+ raise ValueError
241+
238242class MathTests (unittest .TestCase ):
239243
240244 def ftest (self , name , got , expected , ulp_tol = 5 , abs_tol = 0.0 ):
@@ -324,6 +328,7 @@ def testAtan2(self):
324328 self .ftest ('atan2(0, 1)' , math .atan2 (0 , 1 ), 0 )
325329 self .ftest ('atan2(1, 1)' , math .atan2 (1 , 1 ), math .pi / 4 )
326330 self .ftest ('atan2(1, 0)' , math .atan2 (1 , 0 ), math .pi / 2 )
331+ self .ftest ('atan2(1, -1)' , math .atan2 (1 , - 1 ), 3 * math .pi / 4 )
327332
328333 # math.atan2(0, x)
329334 self .ftest ('atan2(0., -inf)' , math .atan2 (0. , NINF ), math .pi )
@@ -417,16 +422,22 @@ def __ceil__(self):
417422 return 42
418423 class TestNoCeil :
419424 pass
425+ class TestBadCeil :
426+ __ceil__ = BadDescr ()
420427 self .assertEqual (math .ceil (TestCeil ()), 42 )
421428 self .assertEqual (math .ceil (FloatCeil ()), 42 )
422429 self .assertEqual (math .ceil (FloatLike (42.5 )), 43 )
423430 self .assertRaises (TypeError , math .ceil , TestNoCeil ())
431+ self .assertRaises (ValueError , math .ceil , TestBadCeil ())
424432
425433 t = TestNoCeil ()
426434 t .__ceil__ = lambda * args : args
427435 self .assertRaises (TypeError , math .ceil , t )
428436 self .assertRaises (TypeError , math .ceil , t , 0 )
429437
438+ self .assertEqual (math .ceil (FloatLike (+ 1.0 )), + 1.0 )
439+ self .assertEqual (math .ceil (FloatLike (- 1.0 )), - 1.0 )
440+
430441 @requires_IEEE_754
431442 def testCopysign (self ):
432443 self .assertEqual (math .copysign (1 , 42 ), 1.0 )
@@ -567,16 +578,22 @@ def __floor__(self):
567578 return 42
568579 class TestNoFloor :
569580 pass
581+ class TestBadFloor :
582+ __floor__ = BadDescr ()
570583 self .assertEqual (math .floor (TestFloor ()), 42 )
571584 self .assertEqual (math .floor (FloatFloor ()), 42 )
572585 self .assertEqual (math .floor (FloatLike (41.9 )), 41 )
573586 self .assertRaises (TypeError , math .floor , TestNoFloor ())
587+ self .assertRaises (ValueError , math .floor , TestBadFloor ())
574588
575589 t = TestNoFloor ()
576590 t .__floor__ = lambda * args : args
577591 self .assertRaises (TypeError , math .floor , t )
578592 self .assertRaises (TypeError , math .floor , t , 0 )
579593
594+ self .assertEqual (math .floor (FloatLike (+ 1.0 )), + 1.0 )
595+ self .assertEqual (math .floor (FloatLike (- 1.0 )), - 1.0 )
596+
580597 def testFmod (self ):
581598 self .assertRaises (TypeError , math .fmod )
582599 self .ftest ('fmod(10, 1)' , math .fmod (10 , 1 ), 0.0 )
@@ -598,6 +615,7 @@ def testFmod(self):
598615 self .assertEqual (math .fmod (- 3.0 , NINF ), - 3.0 )
599616 self .assertEqual (math .fmod (0.0 , 3.0 ), 0.0 )
600617 self .assertEqual (math .fmod (0.0 , NINF ), 0.0 )
618+ self .assertRaises (ValueError , math .fmod , INF , INF )
601619
602620 def testFrexp (self ):
603621 self .assertRaises (TypeError , math .frexp )
@@ -667,6 +685,7 @@ def msum(iterable):
667685 ([], 0.0 ),
668686 ([0.0 ], 0.0 ),
669687 ([1e100 , 1.0 , - 1e100 , 1e-100 , 1e50 , - 1.0 , - 1e50 ], 1e-100 ),
688+ ([1e100 , 1.0 , - 1e100 , 1e-100 , 1e50 , - 1 , - 1e50 ], 1e-100 ),
670689 ([2.0 ** 53 , - 0.5 , - 2.0 ** - 54 ], 2.0 ** 53 - 1.0 ),
671690 ([2.0 ** 53 , 1.0 , 2.0 ** - 100 ], 2.0 ** 53 + 2.0 ),
672691 ([2.0 ** 53 + 10.0 , 1.0 , 2.0 ** - 100 ], 2.0 ** 53 + 12.0 ),
@@ -714,6 +733,22 @@ def msum(iterable):
714733 s = msum (vals )
715734 self .assertEqual (msum (vals ), math .fsum (vals ))
716735
736+ self .assertEqual (math .fsum ([1.0 , math .inf ]), math .inf )
737+ self .assertTrue (math .isnan (math .fsum ([math .nan , 1.0 ])))
738+ self .assertEqual (math .fsum ([1e100 , FloatLike (1.0 ), - 1e100 , 1e-100 ,
739+ 1e50 , FloatLike (- 1.0 ), - 1e50 ]), 1e-100 )
740+ self .assertRaises (OverflowError , math .fsum , [1e+308 , 1e+308 ])
741+ self .assertRaises (ValueError , math .fsum , [math .inf , - math .inf ])
742+ self .assertRaises (TypeError , math .fsum , ['spam' ])
743+ self .assertRaises (TypeError , math .fsum , 1 )
744+ self .assertRaises (OverflowError , math .fsum , [10 ** 1000 ])
745+
746+ def bad_iter ():
747+ yield 1.0
748+ raise ZeroDivisionError
749+
750+ self .assertRaises (ZeroDivisionError , math .fsum , bad_iter ())
751+
717752 def testGcd (self ):
718753 gcd = math .gcd
719754 self .assertEqual (gcd (0 , 0 ), 0 )
@@ -774,6 +809,8 @@ def testHypot(self):
774809 # Test allowable types (those with __float__)
775810 self .assertEqual (hypot (12.0 , 5.0 ), 13.0 )
776811 self .assertEqual (hypot (12 , 5 ), 13 )
812+ self .assertEqual (hypot (1 , - 1 ), math .sqrt (2 ))
813+ self .assertEqual (hypot (1 , FloatLike (- 1. )), math .sqrt (2 ))
777814 self .assertEqual (hypot (Decimal (12 ), Decimal (5 )), 13 )
778815 self .assertEqual (hypot (Fraction (12 , 32 ), Fraction (5 , 32 )), Fraction (13 , 32 ))
779816 self .assertEqual (hypot (bool (1 ), bool (0 ), bool (1 ), bool (1 )), math .sqrt (3 ))
@@ -831,6 +868,8 @@ def testHypot(self):
831868 scale = FLOAT_MIN / 2.0 ** exp
832869 self .assertEqual (math .hypot (4 * scale , 3 * scale ), 5 * scale )
833870
871+ self .assertRaises (TypeError , math .hypot , * ([1.0 ]* 18 ), 'spam' )
872+
834873 @requires_IEEE_754
835874 @unittest .skipIf (HAVE_DOUBLE_ROUNDING ,
836875 "hypot() loses accuracy on machines with double rounding" )
@@ -923,6 +962,10 @@ def testDist(self):
923962 # Test allowable types (those with __float__)
924963 self .assertEqual (dist ((14.0 , 1.0 ), (2.0 , - 4.0 )), 13.0 )
925964 self .assertEqual (dist ((14 , 1 ), (2 , - 4 )), 13 )
965+ self .assertEqual (dist ((FloatLike (14. ), 1 ), (2 , - 4 )), 13 )
966+ self .assertEqual (dist ((11 , 1 ), (FloatLike (- 1. ), - 4 )), 13 )
967+ self .assertEqual (dist ((14 , FloatLike (- 1. )), (2 , - 6 )), 13 )
968+ self .assertEqual (dist ((14 , - 1 ), (2 , - 6 )), 13 )
926969 self .assertEqual (dist ((D (14 ), D (1 )), (D (2 ), D (- 4 ))), D (13 ))
927970 self .assertEqual (dist ((F (14 , 32 ), F (1 , 32 )), (F (2 , 32 ), F (- 4 , 32 ))),
928971 F (13 , 32 ))
@@ -966,13 +1009,25 @@ class T(tuple):
9661009 dist ((1 , 2 , 3 , 4 ), (5 , 6 , 7 ))
9671010 with self .assertRaises (ValueError ): # Check dimension agree
9681011 dist ((1 , 2 , 3 ), (4 , 5 , 6 , 7 ))
1012+ with self .assertRaises (TypeError ):
1013+ dist ((1 ,)* 17 + ("spam" ,), (1 ,)* 18 )
9691014 with self .assertRaises (TypeError ): # Rejects invalid types
9701015 dist ("abc" , "xyz" )
9711016 int_too_big_for_float = 10 ** (sys .float_info .max_10_exp + 5 )
9721017 with self .assertRaises ((ValueError , OverflowError )):
9731018 dist ((1 , int_too_big_for_float ), (2 , 3 ))
9741019 with self .assertRaises ((ValueError , OverflowError )):
9751020 dist ((2 , 3 ), (1 , int_too_big_for_float ))
1021+ with self .assertRaises (TypeError ):
1022+ dist ((1 ,), 2 )
1023+ with self .assertRaises (TypeError ):
1024+ dist ([1 ], 2 )
1025+
1026+ class BadFloat :
1027+ __float__ = BadDescr ()
1028+
1029+ with self .assertRaises (ValueError ):
1030+ dist ([1 ], [BadFloat ()])
9761031
9771032 # Verify that the one dimensional case is equivalent to abs()
9781033 for i in range (20 ):
@@ -1111,6 +1166,7 @@ def test_lcm(self):
11111166
11121167 def testLdexp (self ):
11131168 self .assertRaises (TypeError , math .ldexp )
1169+ self .assertRaises (TypeError , math .ldexp , 2.0 , 1.1 )
11141170 self .ftest ('ldexp(0,1)' , math .ldexp (0 ,1 ), 0 )
11151171 self .ftest ('ldexp(1,1)' , math .ldexp (1 ,1 ), 2 )
11161172 self .ftest ('ldexp(1,-1)' , math .ldexp (1 ,- 1 ), 0.5 )
@@ -1143,6 +1199,7 @@ def testLdexp(self):
11431199
11441200 def testLog (self ):
11451201 self .assertRaises (TypeError , math .log )
1202+ self .assertRaises (TypeError , math .log , 1 , 2 , 3 )
11461203 self .ftest ('log(1/e)' , math .log (1 / math .e ), - 1 )
11471204 self .ftest ('log(1)' , math .log (1 ), 0 )
11481205 self .ftest ('log(e)' , math .log (math .e ), 1 )
@@ -1153,6 +1210,7 @@ def testLog(self):
11531210 2302.5850929940457 )
11541211 self .assertRaises (ValueError , math .log , - 1.5 )
11551212 self .assertRaises (ValueError , math .log , - 10 ** 1000 )
1213+ self .assertRaises (ValueError , math .log , 10 , - 10 )
11561214 self .assertRaises (ValueError , math .log , NINF )
11571215 self .assertEqual (math .log (INF ), INF )
11581216 self .assertTrue (math .isnan (math .log (NAN )))
@@ -1212,6 +1270,8 @@ def testSumProd(self):
12121270 self .assertEqual (sumprod (iter ([10 , 20 , 30 ]), (1 , 2 , 3 )), 140 )
12131271 self .assertEqual (sumprod ([1.5 , 2.5 ], [3.5 , 4.5 ]), 16.5 )
12141272 self .assertEqual (sumprod ([], []), 0 )
1273+ self .assertEqual (sumprod ([- 1 ], [1. ]), - 1 )
1274+ self .assertEqual (sumprod ([1. ], [- 1 ]), - 1 )
12151275
12161276 # Type preservation and coercion
12171277 for v in [
@@ -1237,11 +1297,20 @@ def testSumProd(self):
12371297 self .assertRaises (TypeError , sumprod , [], [], []) # Three args
12381298 self .assertRaises (TypeError , sumprod , None , [10 ]) # Non-iterable
12391299 self .assertRaises (TypeError , sumprod , [10 ], None ) # Non-iterable
1300+ self .assertRaises (TypeError , sumprod , ['x' ], [1.0 ])
12401301
12411302 # Uneven lengths
12421303 self .assertRaises (ValueError , sumprod , [10 , 20 ], [30 ])
12431304 self .assertRaises (ValueError , sumprod , [10 ], [20 , 30 ])
12441305
1306+ # Overflows
1307+ self .assertEqual (sumprod ([10 ** 20 ], [1 ]), 10 ** 20 )
1308+ self .assertEqual (sumprod ([1 ], [10 ** 20 ]), 10 ** 20 )
1309+ self .assertEqual (sumprod ([10 ** 10 ], [10 ** 10 ]), 10 ** 20 )
1310+ self .assertEqual (sumprod ([10 ** 7 ]* 10 ** 5 , [10 ** 7 ]* 10 ** 5 ), 10 ** 19 )
1311+ self .assertRaises (OverflowError , sumprod , [10 ** 1000 ], [1.0 ])
1312+ self .assertRaises (OverflowError , sumprod , [1.0 ], [10 ** 1000 ])
1313+
12451314 # Error in iterator
12461315 def raise_after (n ):
12471316 for i in range (n ):
@@ -1252,6 +1321,11 @@ def raise_after(n):
12521321 with self .assertRaises (RuntimeError ):
12531322 sumprod (raise_after (5 ), range (10 ))
12541323
1324+ from test .test_iter import BasicIterClass
1325+
1326+ self .assertEqual (sumprod (BasicIterClass (1 ), [1 ]), 0 )
1327+ self .assertEqual (sumprod ([1 ], BasicIterClass (1 )), 0 )
1328+
12551329 # Error in multiplication
12561330 class BadMultiply :
12571331 def __mul__ (self , other ):
@@ -1491,6 +1565,7 @@ def testPow(self):
14911565 self .assertTrue (math .isnan (math .pow (2 , NAN )))
14921566 self .assertTrue (math .isnan (math .pow (0 , NAN )))
14931567 self .assertEqual (math .pow (1 , NAN ), 1 )
1568+ self .assertRaises (OverflowError , math .pow , 1e+100 , 1e+100 )
14941569
14951570 # pow(0., x)
14961571 self .assertEqual (math .pow (0. , INF ), 0. )
@@ -1847,6 +1922,8 @@ def __trunc__(self):
18471922 return 23
18481923 class TestNoTrunc :
18491924 pass
1925+ class TestBadTrunc :
1926+ __trunc__ = BadDescr ()
18501927
18511928 self .assertEqual (math .trunc (TestTrunc ()), 23 )
18521929 self .assertEqual (math .trunc (FloatTrunc ()), 23 )
@@ -1855,6 +1932,7 @@ class TestNoTrunc:
18551932 self .assertRaises (TypeError , math .trunc , 1 , 2 )
18561933 self .assertRaises (TypeError , math .trunc , FloatLike (23.5 ))
18571934 self .assertRaises (TypeError , math .trunc , TestNoTrunc ())
1935+ self .assertRaises (ValueError , math .trunc , TestBadTrunc ())
18581936
18591937 def testIsfinite (self ):
18601938 self .assertTrue (math .isfinite (0.0 ))
@@ -2055,6 +2133,8 @@ def test_mtestfile(self):
20552133 '\n ' .join (failures ))
20562134
20572135 def test_prod (self ):
2136+ from fractions import Fraction as F
2137+
20582138 prod = math .prod
20592139 self .assertEqual (prod ([]), 1 )
20602140 self .assertEqual (prod ([], start = 5 ), 5 )
@@ -2066,6 +2146,14 @@ def test_prod(self):
20662146 self .assertEqual (prod ([1.0 , 2.0 , 3.0 , 4.0 , 5.0 ]), 120.0 )
20672147 self .assertEqual (prod ([1 , 2 , 3 , 4.0 , 5.0 ]), 120.0 )
20682148 self .assertEqual (prod ([1.0 , 2.0 , 3.0 , 4 , 5 ]), 120.0 )
2149+ self .assertEqual (prod ([1. , F (3 , 2 )]), 1.5 )
2150+
2151+ # Error in multiplication
2152+ class BadMultiply :
2153+ def __rmul__ (self , other ):
2154+ raise RuntimeError
2155+ with self .assertRaises (RuntimeError ):
2156+ prod ([10. , BadMultiply ()])
20692157
20702158 # Test overflow in fast-path for integers
20712159 self .assertEqual (prod ([1 , 1 , 2 ** 32 , 1 , 1 ]), 2 ** 32 )
@@ -2379,6 +2467,14 @@ def __float__(self):
23792467 # argument to a float.
23802468 self .assertFalse (getattr (y , "converted" , False ))
23812469
2470+ def test_input_exceptions (self ):
2471+ self .assertRaises (TypeError , math .exp , "spam" )
2472+ self .assertRaises (TypeError , math .erf , "spam" )
2473+ self .assertRaises (TypeError , math .atan2 , "spam" , 1.0 )
2474+ self .assertRaises (TypeError , math .atan2 , 1.0 , "spam" )
2475+ self .assertRaises (TypeError , math .atan2 , 1.0 )
2476+ self .assertRaises (TypeError , math .atan2 , 1.0 , 2.0 , 3.0 )
2477+
23822478 # Custom assertions.
23832479
23842480 def assertIsNaN (self , value ):
0 commit comments