1- from test .test_support import run_unittest , is_jython
1+ from test .test_support import run_unittest , verbose
22from test .test_math import parse_testfile , test_file
33import unittest
44import cmath , math
@@ -52,7 +52,6 @@ class CMathTests(unittest.TestCase):
5252 'cos' , 'cosh' , 'exp' , 'log' , 'log10' , 'sin' , 'sinh' ,
5353 'sqrt' , 'tan' , 'tanh' ]]
5454 # test first and second arguments independently for 2-argument log
55-
5655 test_functions .append (lambda x : cmath .log (x , 1729. + 0j ))
5756 test_functions .append (lambda x : cmath .log (14. - 27j , x ))
5857
@@ -244,24 +243,30 @@ def test_cmath_matches_math(self):
244243 unit_interval = test_values + [- x for x in test_values ] + \
245244 [0. , 1. , - 1. ]
246245
246+ # test_values for acosh, atanh
247+ ge_one = [1. ] + [1. / x for x in test_values ]
248+ unit_open = test_values + [- x for x in test_values ] + [0. ]
249+
247250 # test_values for log, log10, sqrt
248- positive = test_values + [ 1. ] + [ 1. / x for x in test_values ]
251+ positive = test_values + ge_one
249252 nonnegative = [0. ] + positive
250253
251254 # test_values for functions defined on the whole real line
252255 real_line = [0. ] + positive + [- x for x in positive ]
253256
254257 test_functions = {
255- # FIXME uncomment tests for Jython
256- #'acos' : unit_interval,
257- #'asin' : unit_interval,
258- #'atan' : real_line,
259- #'cos' : real_line,
260- #'cosh' : real_line,
258+ 'acos' : unit_interval ,
259+ 'asin' : unit_interval ,
260+ 'atan' : real_line ,
261+ 'acosh' : ge_one , # Jython added
262+ 'asinh' : real_line , # Jython added
263+ 'atanh' : unit_open , # Jython added
264+ 'cos' : real_line ,
265+ 'cosh' : real_line ,
261266 'exp' : real_line ,
262267 'log' : positive ,
263268 'log10' : positive ,
264- # 'sin' : real_line,
269+ 'sin' : real_line ,
265270 'sinh' : real_line ,
266271 'sqrt' : nonnegative ,
267272 'tan' : real_line ,
@@ -273,7 +278,7 @@ def test_cmath_matches_math(self):
273278 for v in values :
274279 z = complex_fn (v )
275280 self .rAssertAlmostEqual (float_fn (v ), z .real )
276- self .rAssertAlmostEqual (0. , z .imag )
281+ self .assertEqual (0. , z .imag )
277282
278283 # test two-argument version of log with various bases
279284 for base in [0.5 , 2. , 10. ]:
@@ -282,10 +287,9 @@ def test_cmath_matches_math(self):
282287 self .rAssertAlmostEqual (math .log (v , base ), z .real )
283288 self .assertEqual (0. , z .imag )
284289
285- @unittest .skipIf (is_jython , "FIXME: not working in Jython" )
286290 def test_specific_values (self ):
287291 if not float .__getformat__ ("double" ).startswith ("IEEE" ):
288- return
292+ self . skipTest ( 'needs IEEE double' )
289293
290294 def rect_complex (z ):
291295 """Wrapped version of rect that accepts a complex number instead of
@@ -297,78 +301,88 @@ def polar_complex(z):
297301 two floats."""
298302 return complex (* polar (z ))
299303
304+ raised_fmt = '\n ' \
305+ '{}: {}(complex({!r}, {!r}))\n ' \
306+ 'Raised: {!r}\n ' \
307+ 'Expected: complex({!r}, {!r})'
308+ not_raised_fmt = '\n ' \
309+ '{} not raised in test {}: {}(complex({!r}, {!r}))\n ' \
310+ 'Received: complex({!r}, {!r})'
311+ value_fmt = '\n ' \
312+ '{}: {}(complex({!r}, {!r}))\n ' \
313+ 'Expected: complex({!r}, {!r})\n ' \
314+ 'Received: complex({!r}, {!r})\n ' \
315+ 'Received value insufficiently close to expected value.'
316+ failures = 0
317+
300318 for id , fn , ar , ai , er , ei , flags in parse_testfile (test_file ):
301319 arg = complex (ar , ai )
302- expected = complex (er , ei )
303320 if fn == 'rect' :
304321 function = rect_complex
305322 elif fn == 'polar' :
306323 function = polar_complex
307324 else :
308325 function = getattr (cmath , fn )
309- if 'divide-by-zero' in flags or 'invalid' in flags :
310- try :
326+
327+ try :
328+ # Catch and count failing test cases locally
329+ if 'divide-by-zero' in flags or 'invalid' in flags :
311330 try :
312331 actual = function (arg )
313332 except ValueError :
314- continue
333+ pass
315334 else :
316- self .fail ('ValueError not raised in test '
317- '{}: {}(complex({!r}, {!r}))' .format (id , fn , ar , ai ))
318- except AssertionError , ex :
319- print "Got" , function , ex
320- except BaseException , ex :
321- print "Got" , function , ex
335+ failures += 1
336+ self .fail (not_raised_fmt .format ('ValueError' ,
337+ id , fn , ar , ai , actual .real , actual .imag ))
322338
323- try :
324- if 'overflow' in flags :
339+ elif 'overflow' in flags :
325340 try :
326341 actual = function (arg )
327342 except OverflowError :
328- continue
329- except BaseException , ex :
330- print "\n Got" , function , ex
343+ pass
331344 else :
332- self .fail ('OverflowError not raised in test '
333- '{}: {}(complex({!r}, {!r}))' .format (id , fn , ar , ai ))
334- except AssertionError , ex :
335- print "\n Got" , function , ex
345+ failures += 1
346+ self .fail (not_raised_fmt .format ('OverflowError' ,
347+ id , fn , ar , ai , actual .real , actual .imag ))
348+
349+ else :
350+ actual = function (arg )
351+
352+ # Make sign of expected conform to actual, where ignored.
353+ exr , exi = er , ei
354+ if 'ignore-real-sign' in flags :
355+ exr = math .copysign (er , actual .real )
356+ if 'ignore-imag-sign' in flags :
357+ exi = math .copysign (ei , actual .imag )
358+
359+ # for the real part of the log function, we allow an
360+ # absolute error of up to 2e-15.
361+ if fn in ('log' , 'log10' ):
362+ real_abs_err = 2e-15
363+ else :
364+ real_abs_err = 5e-323
336365
337- try :
338- actual = function (arg )
339- except BaseException , ex :
340- print "\n Got" , function , ex
341-
342- if 'ignore-real-sign' in flags :
343- actual = complex (abs (actual .real ), actual .imag )
344- expected = complex (abs (expected .real ), expected .imag )
345- if 'ignore-imag-sign' in flags :
346- actual = complex (actual .real , abs (actual .imag ))
347- expected = complex (expected .real , abs (expected .imag ))
348-
349- # for the real part of the log function, we allow an
350- # absolute error of up to 2e-15.
351- if fn in ('log' , 'log10' ):
352- real_abs_err = 2e-15
353- else :
354- real_abs_err = 5e-323
366+ error_message = value_fmt .format (id , fn , ar , ai , er , ei ,
367+ actual .real , actual .imag )
368+ self .rAssertAlmostEqual (exr , actual .real ,
369+ abs_err = real_abs_err ,
370+ msg = error_message )
371+ self .rAssertAlmostEqual (exi , actual .imag ,
372+ msg = error_message )
373+
374+ except AssertionError as ex :
375+ failures += 1
376+ if verbose :
377+ print (ex )
378+ except BaseException as ex :
379+ failures += 1
380+ if verbose :
381+ print (raised_fmt .format (id , fn , ar , ai , ex , er , ei ))
382+
383+ if failures :
384+ self .fail ('{} discrepancies' .format (failures ))
355385
356- error_message = (
357- '{}: {}(complex({!r}, {!r}))\n '
358- 'Expected: complex({!r}, {!r})\n '
359- 'Received: complex({!r}, {!r})\n '
360- 'Received value insufficiently close to expected value.'
361- ).format (id , fn , ar , ai ,
362- expected .real , expected .imag ,
363- actual .real , actual .imag )
364- try :
365- self .rAssertAlmostEqual (expected .real , actual .real ,
366- abs_err = real_abs_err ,
367- msg = error_message )
368- self .rAssertAlmostEqual (expected .imag , actual .imag ,
369- msg = error_message )
370- except AssertionError , ex :
371- print "\n Got" , ex , error_message
372386
373387 def assertCISEqual (self , a , b ):
374388 eps = 1E-7
@@ -446,6 +460,8 @@ def test_abs(self):
446460 self .assertTrue (math .isnan (abs (complex (2.3 , NAN ))))
447461 self .assertEqual (abs (complex (INF , NAN )), INF )
448462 self .assertTrue (math .isnan (abs (complex (NAN , NAN ))))
463+
464+ # result overflows
449465 if float .__getformat__ ("double" ).startswith ("IEEE" ):
450466 self .assertRaises (OverflowError , abs , complex (1.4e308 , 1.4e308 ))
451467
0 commit comments