@@ -235,6 +235,10 @@ def __init__(self, value):
235
235
def __index__ (self ):
236
236
return self .value
237
237
238
+ class BadDescr :
239
+ def __get__ (self , obj , objtype = None ):
240
+ raise ValueError
241
+
238
242
class MathTests (unittest .TestCase ):
239
243
240
244
def ftest (self , name , got , expected , ulp_tol = 5 , abs_tol = 0.0 ):
@@ -324,6 +328,7 @@ def testAtan2(self):
324
328
self .ftest ('atan2(0, 1)' , math .atan2 (0 , 1 ), 0 )
325
329
self .ftest ('atan2(1, 1)' , math .atan2 (1 , 1 ), math .pi / 4 )
326
330
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 )
327
332
328
333
# math.atan2(0, x)
329
334
self .ftest ('atan2(0., -inf)' , math .atan2 (0. , NINF ), math .pi )
@@ -417,16 +422,22 @@ def __ceil__(self):
417
422
return 42
418
423
class TestNoCeil :
419
424
pass
425
+ class TestBadCeil :
426
+ __ceil__ = BadDescr ()
420
427
self .assertEqual (math .ceil (TestCeil ()), 42 )
421
428
self .assertEqual (math .ceil (FloatCeil ()), 42 )
422
429
self .assertEqual (math .ceil (FloatLike (42.5 )), 43 )
423
430
self .assertRaises (TypeError , math .ceil , TestNoCeil ())
431
+ self .assertRaises (ValueError , math .ceil , TestBadCeil ())
424
432
425
433
t = TestNoCeil ()
426
434
t .__ceil__ = lambda * args : args
427
435
self .assertRaises (TypeError , math .ceil , t )
428
436
self .assertRaises (TypeError , math .ceil , t , 0 )
429
437
438
+ self .assertEqual (math .ceil (FloatLike (+ 1.0 )), + 1.0 )
439
+ self .assertEqual (math .ceil (FloatLike (- 1.0 )), - 1.0 )
440
+
430
441
@requires_IEEE_754
431
442
def testCopysign (self ):
432
443
self .assertEqual (math .copysign (1 , 42 ), 1.0 )
@@ -567,16 +578,22 @@ def __floor__(self):
567
578
return 42
568
579
class TestNoFloor :
569
580
pass
581
+ class TestBadFloor :
582
+ __floor__ = BadDescr ()
570
583
self .assertEqual (math .floor (TestFloor ()), 42 )
571
584
self .assertEqual (math .floor (FloatFloor ()), 42 )
572
585
self .assertEqual (math .floor (FloatLike (41.9 )), 41 )
573
586
self .assertRaises (TypeError , math .floor , TestNoFloor ())
587
+ self .assertRaises (ValueError , math .floor , TestBadFloor ())
574
588
575
589
t = TestNoFloor ()
576
590
t .__floor__ = lambda * args : args
577
591
self .assertRaises (TypeError , math .floor , t )
578
592
self .assertRaises (TypeError , math .floor , t , 0 )
579
593
594
+ self .assertEqual (math .floor (FloatLike (+ 1.0 )), + 1.0 )
595
+ self .assertEqual (math .floor (FloatLike (- 1.0 )), - 1.0 )
596
+
580
597
def testFmod (self ):
581
598
self .assertRaises (TypeError , math .fmod )
582
599
self .ftest ('fmod(10, 1)' , math .fmod (10 , 1 ), 0.0 )
@@ -598,6 +615,7 @@ def testFmod(self):
598
615
self .assertEqual (math .fmod (- 3.0 , NINF ), - 3.0 )
599
616
self .assertEqual (math .fmod (0.0 , 3.0 ), 0.0 )
600
617
self .assertEqual (math .fmod (0.0 , NINF ), 0.0 )
618
+ self .assertRaises (ValueError , math .fmod , INF , INF )
601
619
602
620
def testFrexp (self ):
603
621
self .assertRaises (TypeError , math .frexp )
@@ -667,6 +685,7 @@ def msum(iterable):
667
685
([], 0.0 ),
668
686
([0.0 ], 0.0 ),
669
687
([1e100 , 1.0 , - 1e100 , 1e-100 , 1e50 , - 1.0 , - 1e50 ], 1e-100 ),
688
+ ([1e100 , 1.0 , - 1e100 , 1e-100 , 1e50 , - 1 , - 1e50 ], 1e-100 ),
670
689
([2.0 ** 53 , - 0.5 , - 2.0 ** - 54 ], 2.0 ** 53 - 1.0 ),
671
690
([2.0 ** 53 , 1.0 , 2.0 ** - 100 ], 2.0 ** 53 + 2.0 ),
672
691
([2.0 ** 53 + 10.0 , 1.0 , 2.0 ** - 100 ], 2.0 ** 53 + 12.0 ),
@@ -714,6 +733,22 @@ def msum(iterable):
714
733
s = msum (vals )
715
734
self .assertEqual (msum (vals ), math .fsum (vals ))
716
735
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
+
717
752
def testGcd (self ):
718
753
gcd = math .gcd
719
754
self .assertEqual (gcd (0 , 0 ), 0 )
@@ -774,6 +809,8 @@ def testHypot(self):
774
809
# Test allowable types (those with __float__)
775
810
self .assertEqual (hypot (12.0 , 5.0 ), 13.0 )
776
811
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 ))
777
814
self .assertEqual (hypot (Decimal (12 ), Decimal (5 )), 13 )
778
815
self .assertEqual (hypot (Fraction (12 , 32 ), Fraction (5 , 32 )), Fraction (13 , 32 ))
779
816
self .assertEqual (hypot (bool (1 ), bool (0 ), bool (1 ), bool (1 )), math .sqrt (3 ))
@@ -831,6 +868,8 @@ def testHypot(self):
831
868
scale = FLOAT_MIN / 2.0 ** exp
832
869
self .assertEqual (math .hypot (4 * scale , 3 * scale ), 5 * scale )
833
870
871
+ self .assertRaises (TypeError , math .hypot , * ([1.0 ]* 18 ), 'spam' )
872
+
834
873
@requires_IEEE_754
835
874
@unittest .skipIf (HAVE_DOUBLE_ROUNDING ,
836
875
"hypot() loses accuracy on machines with double rounding" )
@@ -923,6 +962,10 @@ def testDist(self):
923
962
# Test allowable types (those with __float__)
924
963
self .assertEqual (dist ((14.0 , 1.0 ), (2.0 , - 4.0 )), 13.0 )
925
964
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 )
926
969
self .assertEqual (dist ((D (14 ), D (1 )), (D (2 ), D (- 4 ))), D (13 ))
927
970
self .assertEqual (dist ((F (14 , 32 ), F (1 , 32 )), (F (2 , 32 ), F (- 4 , 32 ))),
928
971
F (13 , 32 ))
@@ -966,13 +1009,25 @@ class T(tuple):
966
1009
dist ((1 , 2 , 3 , 4 ), (5 , 6 , 7 ))
967
1010
with self .assertRaises (ValueError ): # Check dimension agree
968
1011
dist ((1 , 2 , 3 ), (4 , 5 , 6 , 7 ))
1012
+ with self .assertRaises (TypeError ):
1013
+ dist ((1 ,)* 17 + ("spam" ,), (1 ,)* 18 )
969
1014
with self .assertRaises (TypeError ): # Rejects invalid types
970
1015
dist ("abc" , "xyz" )
971
1016
int_too_big_for_float = 10 ** (sys .float_info .max_10_exp + 5 )
972
1017
with self .assertRaises ((ValueError , OverflowError )):
973
1018
dist ((1 , int_too_big_for_float ), (2 , 3 ))
974
1019
with self .assertRaises ((ValueError , OverflowError )):
975
1020
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 ()])
976
1031
977
1032
# Verify that the one dimensional case is equivalent to abs()
978
1033
for i in range (20 ):
@@ -1111,6 +1166,7 @@ def test_lcm(self):
1111
1166
1112
1167
def testLdexp (self ):
1113
1168
self .assertRaises (TypeError , math .ldexp )
1169
+ self .assertRaises (TypeError , math .ldexp , 2.0 , 1.1 )
1114
1170
self .ftest ('ldexp(0,1)' , math .ldexp (0 ,1 ), 0 )
1115
1171
self .ftest ('ldexp(1,1)' , math .ldexp (1 ,1 ), 2 )
1116
1172
self .ftest ('ldexp(1,-1)' , math .ldexp (1 ,- 1 ), 0.5 )
@@ -1143,6 +1199,7 @@ def testLdexp(self):
1143
1199
1144
1200
def testLog (self ):
1145
1201
self .assertRaises (TypeError , math .log )
1202
+ self .assertRaises (TypeError , math .log , 1 , 2 , 3 )
1146
1203
self .ftest ('log(1/e)' , math .log (1 / math .e ), - 1 )
1147
1204
self .ftest ('log(1)' , math .log (1 ), 0 )
1148
1205
self .ftest ('log(e)' , math .log (math .e ), 1 )
@@ -1153,6 +1210,7 @@ def testLog(self):
1153
1210
2302.5850929940457 )
1154
1211
self .assertRaises (ValueError , math .log , - 1.5 )
1155
1212
self .assertRaises (ValueError , math .log , - 10 ** 1000 )
1213
+ self .assertRaises (ValueError , math .log , 10 , - 10 )
1156
1214
self .assertRaises (ValueError , math .log , NINF )
1157
1215
self .assertEqual (math .log (INF ), INF )
1158
1216
self .assertTrue (math .isnan (math .log (NAN )))
@@ -1212,6 +1270,8 @@ def testSumProd(self):
1212
1270
self .assertEqual (sumprod (iter ([10 , 20 , 30 ]), (1 , 2 , 3 )), 140 )
1213
1271
self .assertEqual (sumprod ([1.5 , 2.5 ], [3.5 , 4.5 ]), 16.5 )
1214
1272
self .assertEqual (sumprod ([], []), 0 )
1273
+ self .assertEqual (sumprod ([- 1 ], [1. ]), - 1 )
1274
+ self .assertEqual (sumprod ([1. ], [- 1 ]), - 1 )
1215
1275
1216
1276
# Type preservation and coercion
1217
1277
for v in [
@@ -1237,11 +1297,20 @@ def testSumProd(self):
1237
1297
self .assertRaises (TypeError , sumprod , [], [], []) # Three args
1238
1298
self .assertRaises (TypeError , sumprod , None , [10 ]) # Non-iterable
1239
1299
self .assertRaises (TypeError , sumprod , [10 ], None ) # Non-iterable
1300
+ self .assertRaises (TypeError , sumprod , ['x' ], [1.0 ])
1240
1301
1241
1302
# Uneven lengths
1242
1303
self .assertRaises (ValueError , sumprod , [10 , 20 ], [30 ])
1243
1304
self .assertRaises (ValueError , sumprod , [10 ], [20 , 30 ])
1244
1305
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
+
1245
1314
# Error in iterator
1246
1315
def raise_after (n ):
1247
1316
for i in range (n ):
@@ -1252,6 +1321,11 @@ def raise_after(n):
1252
1321
with self .assertRaises (RuntimeError ):
1253
1322
sumprod (raise_after (5 ), range (10 ))
1254
1323
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
+
1255
1329
# Error in multiplication
1256
1330
class BadMultiply :
1257
1331
def __mul__ (self , other ):
@@ -1491,6 +1565,7 @@ def testPow(self):
1491
1565
self .assertTrue (math .isnan (math .pow (2 , NAN )))
1492
1566
self .assertTrue (math .isnan (math .pow (0 , NAN )))
1493
1567
self .assertEqual (math .pow (1 , NAN ), 1 )
1568
+ self .assertRaises (OverflowError , math .pow , 1e+100 , 1e+100 )
1494
1569
1495
1570
# pow(0., x)
1496
1571
self .assertEqual (math .pow (0. , INF ), 0. )
@@ -1847,6 +1922,8 @@ def __trunc__(self):
1847
1922
return 23
1848
1923
class TestNoTrunc :
1849
1924
pass
1925
+ class TestBadTrunc :
1926
+ __trunc__ = BadDescr ()
1850
1927
1851
1928
self .assertEqual (math .trunc (TestTrunc ()), 23 )
1852
1929
self .assertEqual (math .trunc (FloatTrunc ()), 23 )
@@ -1855,6 +1932,7 @@ class TestNoTrunc:
1855
1932
self .assertRaises (TypeError , math .trunc , 1 , 2 )
1856
1933
self .assertRaises (TypeError , math .trunc , FloatLike (23.5 ))
1857
1934
self .assertRaises (TypeError , math .trunc , TestNoTrunc ())
1935
+ self .assertRaises (ValueError , math .trunc , TestBadTrunc ())
1858
1936
1859
1937
def testIsfinite (self ):
1860
1938
self .assertTrue (math .isfinite (0.0 ))
@@ -2055,6 +2133,8 @@ def test_mtestfile(self):
2055
2133
'\n ' .join (failures ))
2056
2134
2057
2135
def test_prod (self ):
2136
+ from fractions import Fraction as F
2137
+
2058
2138
prod = math .prod
2059
2139
self .assertEqual (prod ([]), 1 )
2060
2140
self .assertEqual (prod ([], start = 5 ), 5 )
@@ -2066,6 +2146,14 @@ def test_prod(self):
2066
2146
self .assertEqual (prod ([1.0 , 2.0 , 3.0 , 4.0 , 5.0 ]), 120.0 )
2067
2147
self .assertEqual (prod ([1 , 2 , 3 , 4.0 , 5.0 ]), 120.0 )
2068
2148
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 ()])
2069
2157
2070
2158
# Test overflow in fast-path for integers
2071
2159
self .assertEqual (prod ([1 , 1 , 2 ** 32 , 1 , 1 ]), 2 ** 32 )
@@ -2379,6 +2467,14 @@ def __float__(self):
2379
2467
# argument to a float.
2380
2468
self .assertFalse (getattr (y , "converted" , False ))
2381
2469
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
+
2382
2478
# Custom assertions.
2383
2479
2384
2480
def assertIsNaN (self , value ):
0 commit comments