1
1
"""Tests for Lib/fractions.py."""
2
2
3
3
from decimal import Decimal
4
- from test .support import requires_IEEE_754
4
+ from test .support import requires_IEEE_754 , adjust_int_max_str_digits
5
5
import math
6
6
import numbers
7
7
import operator
@@ -395,12 +395,14 @@ class B(metaclass=M):
395
395
396
396
def testFromString (self ):
397
397
self .assertEqual ((5 , 1 ), _components (F ("5" )))
398
+ self .assertEqual ((5 , 1 ), _components (F ("005" )))
398
399
self .assertEqual ((3 , 2 ), _components (F ("3/2" )))
399
400
self .assertEqual ((3 , 2 ), _components (F ("3 / 2" )))
400
401
self .assertEqual ((3 , 2 ), _components (F (" \n +3/2" )))
401
402
self .assertEqual ((- 3 , 2 ), _components (F ("-3/2 " )))
402
- self .assertEqual ((13 , 2 ), _components (F (" 013/02 \n " )))
403
+ self .assertEqual ((13 , 2 ), _components (F (" 0013/002 \n " )))
403
404
self .assertEqual ((16 , 5 ), _components (F (" 3.2 " )))
405
+ self .assertEqual ((16 , 5 ), _components (F ("003.2" )))
404
406
self .assertEqual ((- 16 , 5 ), _components (F (" -3.2 " )))
405
407
self .assertEqual ((- 3 , 1 ), _components (F (" -3. " )))
406
408
self .assertEqual ((3 , 5 ), _components (F (" .6 " )))
@@ -419,116 +421,101 @@ def testFromString(self):
419
421
self .assertRaisesMessage (
420
422
ZeroDivisionError , "Fraction(3, 0)" ,
421
423
F , "3/0" )
422
- self .assertRaisesMessage (
423
- ValueError , "Invalid literal for Fraction: '3/'" ,
424
- F , "3/" )
425
- self .assertRaisesMessage (
426
- ValueError , "Invalid literal for Fraction: '/2'" ,
427
- F , "/2" )
428
- self .assertRaisesMessage (
429
- # Denominators don't need a sign.
430
- ValueError , "Invalid literal for Fraction: '3/+2'" ,
431
- F , "3/+2" )
432
- self .assertRaisesMessage (
433
- # Imitate float's parsing.
434
- ValueError , "Invalid literal for Fraction: '+ 3/2'" ,
435
- F , "+ 3/2" )
436
- self .assertRaisesMessage (
437
- # Avoid treating '.' as a regex special character.
438
- ValueError , "Invalid literal for Fraction: '3a2'" ,
439
- F , "3a2" )
440
- self .assertRaisesMessage (
441
- # Don't accept combinations of decimals and rationals.
442
- ValueError , "Invalid literal for Fraction: '3/7.2'" ,
443
- F , "3/7.2" )
444
- self .assertRaisesMessage (
445
- # Don't accept combinations of decimals and rationals.
446
- ValueError , "Invalid literal for Fraction: '3.2/7'" ,
447
- F , "3.2/7" )
448
- self .assertRaisesMessage (
449
- # Allow 3. and .3, but not .
450
- ValueError , "Invalid literal for Fraction: '.'" ,
451
- F , "." )
452
- self .assertRaisesMessage (
453
- ValueError , "Invalid literal for Fraction: '_'" ,
454
- F , "_" )
455
- self .assertRaisesMessage (
456
- ValueError , "Invalid literal for Fraction: '_1'" ,
457
- F , "_1" )
458
- self .assertRaisesMessage (
459
- ValueError , "Invalid literal for Fraction: '1__2'" ,
460
- F , "1__2" )
461
- self .assertRaisesMessage (
462
- ValueError , "Invalid literal for Fraction: '/_'" ,
463
- F , "/_" )
464
- self .assertRaisesMessage (
465
- ValueError , "Invalid literal for Fraction: '1_/'" ,
466
- F , "1_/" )
467
- self .assertRaisesMessage (
468
- ValueError , "Invalid literal for Fraction: '_1/'" ,
469
- F , "_1/" )
470
- self .assertRaisesMessage (
471
- ValueError , "Invalid literal for Fraction: '1__2/'" ,
472
- F , "1__2/" )
473
- self .assertRaisesMessage (
474
- ValueError , "Invalid literal for Fraction: '1/_'" ,
475
- F , "1/_" )
476
- self .assertRaisesMessage (
477
- ValueError , "Invalid literal for Fraction: '1/_1'" ,
478
- F , "1/_1" )
479
- self .assertRaisesMessage (
480
- ValueError , "Invalid literal for Fraction: '1/1__2'" ,
481
- F , "1/1__2" )
482
- self .assertRaisesMessage (
483
- ValueError , "Invalid literal for Fraction: '1._111'" ,
484
- F , "1._111" )
485
- self .assertRaisesMessage (
486
- ValueError , "Invalid literal for Fraction: '1.1__1'" ,
487
- F , "1.1__1" )
488
- self .assertRaisesMessage (
489
- ValueError , "Invalid literal for Fraction: '1.1e+_1'" ,
490
- F , "1.1e+_1" )
491
- self .assertRaisesMessage (
492
- ValueError , "Invalid literal for Fraction: '1.1e+1__1'" ,
493
- F , "1.1e+1__1" )
494
- self .assertRaisesMessage (
495
- ValueError , "Invalid literal for Fraction: '123.dd'" ,
496
- F , "123.dd" )
497
- self .assertRaisesMessage (
498
- ValueError , "Invalid literal for Fraction: '123.5_dd'" ,
499
- F , "123.5_dd" )
500
- self .assertRaisesMessage (
501
- ValueError , "Invalid literal for Fraction: 'dd.5'" ,
502
- F , "dd.5" )
503
- self .assertRaisesMessage (
504
- ValueError , "Invalid literal for Fraction: '7_dd'" ,
505
- F , "7_dd" )
506
- self .assertRaisesMessage (
507
- ValueError , "Invalid literal for Fraction: '1/dd'" ,
508
- F , "1/dd" )
509
- self .assertRaisesMessage (
510
- ValueError , "Invalid literal for Fraction: '1/123_dd'" ,
511
- F , "1/123_dd" )
512
- self .assertRaisesMessage (
513
- ValueError , "Invalid literal for Fraction: '789edd'" ,
514
- F , "789edd" )
515
- self .assertRaisesMessage (
516
- ValueError , "Invalid literal for Fraction: '789e2_dd'" ,
517
- F , "789e2_dd" )
424
+
425
+ def check_invalid (s ):
426
+ msg = "Invalid literal for Fraction: " + repr (s )
427
+ self .assertRaisesMessage (ValueError , msg , F , s )
428
+
429
+ check_invalid ("3/" )
430
+ check_invalid ("/2" )
431
+ # Denominators don't need a sign.
432
+ check_invalid ("3/+2" )
433
+ check_invalid ("3/-2" )
434
+ # Imitate float's parsing.
435
+ check_invalid ("+ 3/2" )
436
+ check_invalid ("- 3/2" )
437
+ # Avoid treating '.' as a regex special character.
438
+ check_invalid ("3a2" )
439
+ # Don't accept combinations of decimals and rationals.
440
+ check_invalid ("3/7.2" )
441
+ check_invalid ("3.2/7" )
442
+ # No space around dot.
443
+ check_invalid ("3 .2" )
444
+ check_invalid ("3. 2" )
445
+ # No space around e.
446
+ check_invalid ("3.2 e1" )
447
+ check_invalid ("3.2e 1" )
448
+ # Fractional part don't need a sign.
449
+ check_invalid ("3.+2" )
450
+ check_invalid ("3.-2" )
451
+ # Only accept base 10.
452
+ check_invalid ("0x10" )
453
+ check_invalid ("0x10/1" )
454
+ check_invalid ("1/0x10" )
455
+ check_invalid ("0x10." )
456
+ check_invalid ("0x10.1" )
457
+ check_invalid ("1.0x10" )
458
+ check_invalid ("1.0e0x10" )
459
+ # Only accept decimal digits.
460
+ check_invalid ("³" )
461
+ check_invalid ("³/2" )
462
+ check_invalid ("3/²" )
463
+ check_invalid ("³.2" )
464
+ check_invalid ("3.²" )
465
+ check_invalid ("3.2e²" )
466
+ check_invalid ("¼" )
467
+ # Allow 3. and .3, but not .
468
+ check_invalid ("." )
469
+ check_invalid ("_" )
470
+ check_invalid ("_1" )
471
+ check_invalid ("1__2" )
472
+ check_invalid ("/_" )
473
+ check_invalid ("1_/" )
474
+ check_invalid ("_1/" )
475
+ check_invalid ("1__2/" )
476
+ check_invalid ("1/_" )
477
+ check_invalid ("1/_1" )
478
+ check_invalid ("1/1__2" )
479
+ check_invalid ("1._111" )
480
+ check_invalid ("1.1__1" )
481
+ check_invalid ("1.1e+_1" )
482
+ check_invalid ("1.1e+1__1" )
483
+ check_invalid ("123.dd" )
484
+ check_invalid ("123.5_dd" )
485
+ check_invalid ("dd.5" )
486
+ check_invalid ("7_dd" )
487
+ check_invalid ("1/dd" )
488
+ check_invalid ("1/123_dd" )
489
+ check_invalid ("789edd" )
490
+ check_invalid ("789e2_dd" )
518
491
# Test catastrophic backtracking.
519
492
val = "9" * 50 + "_"
520
- self .assertRaisesMessage (
521
- ValueError , "Invalid literal for Fraction: '" + val + "'" ,
522
- F , val )
523
- self .assertRaisesMessage (
524
- ValueError , "Invalid literal for Fraction: '1/" + val + "'" ,
525
- F , "1/" + val )
526
- self .assertRaisesMessage (
527
- ValueError , "Invalid literal for Fraction: '1." + val + "'" ,
528
- F , "1." + val )
529
- self .assertRaisesMessage (
530
- ValueError , "Invalid literal for Fraction: '1.1+e" + val + "'" ,
531
- F , "1.1+e" + val )
493
+ check_invalid (val )
494
+ check_invalid ("1/" + val )
495
+ check_invalid ("1." + val )
496
+ check_invalid ("." + val )
497
+ check_invalid ("1.1+e" + val )
498
+ check_invalid ("1.1e" + val )
499
+
500
+ def test_limit_int (self ):
501
+ maxdigits = 5000
502
+ with adjust_int_max_str_digits (maxdigits ):
503
+ val = '1' * maxdigits
504
+ num = (10 ** maxdigits - 1 )// 9
505
+ self .assertEqual ((num , 1 ), _components (F (val )))
506
+ self .assertRaises (ValueError , F , val + '1' )
507
+ self .assertEqual ((num , 2 ), _components (F (val + '/2' )))
508
+ self .assertRaises (ValueError , F , val + '1/2' )
509
+ self .assertEqual ((1 , num ), _components (F ('1/' + val )))
510
+ self .assertRaises (ValueError , F , '1/1' + val )
511
+ self .assertEqual (((10 ** (maxdigits + 1 ) - 1 )// 9 , 10 ** maxdigits ),
512
+ _components (F ('1.' + val )))
513
+ self .assertRaises (ValueError , F , '1.1' + val )
514
+ self .assertEqual ((num , 10 ** maxdigits ), _components (F ('.' + val )))
515
+ self .assertRaises (ValueError , F , '.1' + val )
516
+ self .assertRaises (ValueError , F , '1.1e1' + val )
517
+ self .assertEqual ((11 , 10 ), _components (F ('1.1e' + '0' * maxdigits )))
518
+ self .assertRaises (ValueError , F , '1.1e' + '0' * (maxdigits + 1 ))
532
519
533
520
def testImmutable (self ):
534
521
r = F (7 , 3 )
0 commit comments