2
2
3
3
import cmath
4
4
from decimal import Decimal
5
- from test .support import requires_IEEE_754
5
+ from test .support import requires_IEEE_754 , adjust_int_max_str_digits
6
6
import math
7
7
import numbers
8
8
import operator
@@ -357,12 +357,14 @@ def testInitFromDecimal(self):
357
357
358
358
def testFromString (self ):
359
359
self .assertEqual ((5 , 1 ), _components (F ("5" )))
360
+ self .assertEqual ((5 , 1 ), _components (F ("005" )))
360
361
self .assertEqual ((3 , 2 ), _components (F ("3/2" )))
361
362
self .assertEqual ((3 , 2 ), _components (F ("3 / 2" )))
362
363
self .assertEqual ((3 , 2 ), _components (F (" \n +3/2" )))
363
364
self .assertEqual ((- 3 , 2 ), _components (F ("-3/2 " )))
364
- self .assertEqual ((13 , 2 ), _components (F (" 013/02 \n " )))
365
+ self .assertEqual ((13 , 2 ), _components (F (" 0013/002 \n " )))
365
366
self .assertEqual ((16 , 5 ), _components (F (" 3.2 " )))
367
+ self .assertEqual ((16 , 5 ), _components (F ("003.2" )))
366
368
self .assertEqual ((- 16 , 5 ), _components (F (" -3.2 " )))
367
369
self .assertEqual ((- 3 , 1 ), _components (F (" -3. " )))
368
370
self .assertEqual ((3 , 5 ), _components (F (" .6 " )))
@@ -381,116 +383,101 @@ def testFromString(self):
381
383
self .assertRaisesMessage (
382
384
ZeroDivisionError , "Fraction(3, 0)" ,
383
385
F , "3/0" )
384
- self .assertRaisesMessage (
385
- ValueError , "Invalid literal for Fraction: '3/'" ,
386
- F , "3/" )
387
- self .assertRaisesMessage (
388
- ValueError , "Invalid literal for Fraction: '/2'" ,
389
- F , "/2" )
390
- self .assertRaisesMessage (
391
- # Denominators don't need a sign.
392
- ValueError , "Invalid literal for Fraction: '3/+2'" ,
393
- F , "3/+2" )
394
- self .assertRaisesMessage (
395
- # Imitate float's parsing.
396
- ValueError , "Invalid literal for Fraction: '+ 3/2'" ,
397
- F , "+ 3/2" )
398
- self .assertRaisesMessage (
399
- # Avoid treating '.' as a regex special character.
400
- ValueError , "Invalid literal for Fraction: '3a2'" ,
401
- F , "3a2" )
402
- self .assertRaisesMessage (
403
- # Don't accept combinations of decimals and rationals.
404
- ValueError , "Invalid literal for Fraction: '3/7.2'" ,
405
- F , "3/7.2" )
406
- self .assertRaisesMessage (
407
- # Don't accept combinations of decimals and rationals.
408
- ValueError , "Invalid literal for Fraction: '3.2/7'" ,
409
- F , "3.2/7" )
410
- self .assertRaisesMessage (
411
- # Allow 3. and .3, but not .
412
- ValueError , "Invalid literal for Fraction: '.'" ,
413
- F , "." )
414
- self .assertRaisesMessage (
415
- ValueError , "Invalid literal for Fraction: '_'" ,
416
- F , "_" )
417
- self .assertRaisesMessage (
418
- ValueError , "Invalid literal for Fraction: '_1'" ,
419
- F , "_1" )
420
- self .assertRaisesMessage (
421
- ValueError , "Invalid literal for Fraction: '1__2'" ,
422
- F , "1__2" )
423
- self .assertRaisesMessage (
424
- ValueError , "Invalid literal for Fraction: '/_'" ,
425
- F , "/_" )
426
- self .assertRaisesMessage (
427
- ValueError , "Invalid literal for Fraction: '1_/'" ,
428
- F , "1_/" )
429
- self .assertRaisesMessage (
430
- ValueError , "Invalid literal for Fraction: '_1/'" ,
431
- F , "_1/" )
432
- self .assertRaisesMessage (
433
- ValueError , "Invalid literal for Fraction: '1__2/'" ,
434
- F , "1__2/" )
435
- self .assertRaisesMessage (
436
- ValueError , "Invalid literal for Fraction: '1/_'" ,
437
- F , "1/_" )
438
- self .assertRaisesMessage (
439
- ValueError , "Invalid literal for Fraction: '1/_1'" ,
440
- F , "1/_1" )
441
- self .assertRaisesMessage (
442
- ValueError , "Invalid literal for Fraction: '1/1__2'" ,
443
- F , "1/1__2" )
444
- self .assertRaisesMessage (
445
- ValueError , "Invalid literal for Fraction: '1._111'" ,
446
- F , "1._111" )
447
- self .assertRaisesMessage (
448
- ValueError , "Invalid literal for Fraction: '1.1__1'" ,
449
- F , "1.1__1" )
450
- self .assertRaisesMessage (
451
- ValueError , "Invalid literal for Fraction: '1.1e+_1'" ,
452
-
9E81
F , "1.1e+_1" )
453
- self .assertRaisesMessage (
454
- ValueError , "Invalid literal for Fraction: '1.1e+1__1'" ,
455
- F , "1.1e+1__1" )
456
- self .assertRaisesMessage (
457
- ValueError , "Invalid literal for Fraction: '123.dd'" ,
458
- F , "123.dd" )
459
- self .assertRaisesMessage (
460
- ValueError , "Invalid literal for Fraction: '123.5_dd'" ,
461
- F , "123.5_dd" )
462
- self .assertRaisesMessage (
463
- ValueError , "Invalid literal for Fraction: 'dd.5'" ,
464
- F , "dd.5" )
465
- self .assertRaisesMessage (
466
- ValueError , "Invalid literal for Fraction: '7_dd'" ,
467
- F , "7_dd" )
468
- self .assertRaisesMessage (
469
- ValueError , "Invalid literal for Fraction: '1/dd'" ,
470
- F , "1/dd" )
471
- self .assertRaisesMessage (
472
- ValueError , "Invalid literal for Fraction: '1/123_dd'" ,
473
- F , "1/123_dd" )
474
- self .assertRaisesMessage (
475
- ValueError , "Invalid literal for Fraction: '789edd'" ,
476
- F , "789edd" )
477
- self .assertRaisesMessage (
478
- ValueError , "Invalid literal for Fraction: '789e2_dd'" ,
479
- F , "
F438
789e2_dd" )
386
+
387
+ def check_invalid (s ):
388
+ msg = "Invalid literal for Fraction: " + repr (s )
389
+ self .assertRaisesMessage (ValueError , msg , F , s )
390
+
391
+ check_invalid ("3/" )
392
+ check_invalid ("/2" )
393
+ # Denominators don't need a sign.
394
+ check_invalid ("3/+2" )
395
+ check_invalid ("3/-2" )
396
+ # Imitate float's parsing.
397
+ check_invalid ("+ 3/2" )
398
+ check_invalid ("- 3/2" )
399
+ # Avoid treating '.' as a regex special character.
400
+ check_invalid ("3a2" )
401
+ # Don't accept combinations of decimals and rationals.
402
+ check_invalid ("3/7.2" )
403
+ check_invalid ("3.2/7" )
404
+ # No space around dot.
405
+ check_invalid ("3 .2" )
406
+ check_invalid ("3. 2" )
407
+ # No space around e.
408
+ check_invalid ("3.2 e1" )
409
+ check_invalid ("3.2e 1" )
410
+ # Fractional part don't need a sign.
411
+ check_invalid ("3.+2" )
412
+ check_invalid ("3.-2" )
413
+ # Only accept base 10.
414
+ check_invalid ("0x10" )
415
+ check_invalid ("0x10/1" )
416
+ check_invalid ("1/0x10" )
417
+ check_invalid ("0x10." )
418
+ check_invalid ("0x10.1" )
419
+ check_invalid ("1.0x10" )
420
+ check_invalid ("1.0e0x10" )
421
+ # Only accept decimal digits.
422
+ check_invalid ("³" )
423
+ check_invalid ("³/2" )
424
+ check_invalid ("3/²" )
425
+ check_invalid ("³.2" )
426
+ check_invalid ("3.²" )
427
+ check_invalid ("3.2e²" )
428
+ check_invalid ("¼" )
429
+ # Allow 3. and .3, but not .
430
+ check_invalid ("." )
431
+ check_invalid ("_" )
432
+ check_invalid ("_1" )
433
+ check_invalid ("1__2" )
434
+ check_invalid ("/_" )
435
+ check_invalid ("1_/" )
436
+ check_invalid ("_1/" )
437
+ check_invalid ("1__2/" )
438
+ check_invalid ("1/_" )
439
+ check_invalid ("1/_1" )
440
+ check_invalid ("1/1__2" )
441
+ check_invalid ("1._111" )
442
+ check_invalid ("1.1__1" )
443
+ check_invalid ("1.1e+_1" )
444
+ check_invalid ("1.1e+1__1" )
445
+ check_invalid ("123.dd" )
446
+ check_invalid ("123.5_dd" )
447
+ check_invalid ("dd.5" )
448
+ check_invalid ("7_dd" )
449
+ check_invalid ("1/dd" )
450
+ check_invalid ("1/123_dd" )
451
+ check_invalid ("789edd" )
452
+ check_invalid ("789e2_dd" )
480
453
# Test catastrophic backtracking.
481
454
val = "9" * 50 + "_"
482
- self .assertRaisesMessage (
483
- ValueError , "Invalid literal for Fraction: '" + val + "'" ,
484
- F , val )
485
- self .assertRaisesMessage (
486
- ValueError , "Invalid literal for Fraction: '1/" + val + "'" ,
487
- F , "1/" + val )
488
- self .assertRaisesMessage (
489
- ValueError , "Invalid literal for Fraction: '1." + val + "'" ,
490
- F , "1." + val )
491
- self .assertRaisesMessage (
492
- ValueError , "Invalid literal for Fraction: '1.1+e" + val + "'" ,
493
- F , "1.1+e" + val )
455
+ check_invalid (val )
456
+ check_invalid ("1/" + val )
457
+ check_invalid ("1." + val )
458
+ check_invalid ("." + val )
459
+ check_invalid ("1.1+e" + val )
460
+ check_invalid ("1.1e" + val )
461
+
462
+ def test_limit_int (self ):
463
+ maxdigits = 5000
464
+ with adjust_int_max_str_digits (maxdigits ):
465
+ val = '1' * maxdigits
466
+ num = (10 ** maxdigits - 1 )// 9
467
+ self .assertEqual ((num , 1 ), _components (F (val )))
468
+ self .assertRaises (ValueError , F , val + '1' )
469
+ self .assertEqual ((num , 2 ), _components (F (val + '/2' )))
470
+ self .assertRaises (ValueError , F , val + '1/2' )
471
+ self .assertEqual ((1 , num ), _components (F ('1/' + val )))
472
+ self .assertRaises (ValueError , F , '1/1' + val )
473
+ self .assertEqual (((10 ** (maxdigits + 1 ) - 1 )// 9 , 10 ** maxdigits ),
474
+ _components (F ('1.' + val )))
475
+ self .assertRaises (ValueError , F , '1.1' + val )
476
+ self .assertEqual ((num , 10 ** maxdigits ), _components (F ('.' + val )))
477
+ self .assertRaises (ValueError , F , '.1' + val )
478
+ self .assertRaises (ValueError , F , '1.1e1' + val )
479
+ self .assertEqual ((11 , 10 ), _components (F ('1.1e' + '0' * maxdigits )))
480
+ self .assertRaises (ValueError , F , '1.1e' + '0' * (maxdigits + 1 ))
494
481
495
482
def testImmutable (self ):
496
483
r = F (7 , 3 )
0 commit comments