Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 17d0fec

Browse files
Improve tests for str to Fraction conversion (GH-134010)
1 parent 0afbd4e commit 17d0fec

File tree

1 file changed

+97
-110
lines changed

1 file changed

+97
-110
lines changed

Lib/test/test_fractions.py

Lines changed: 97 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Tests for Lib/fractions.py."""
22

33
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
55
import math
66
import numbers
77
import operator
@@ -395,12 +395,14 @@ class B(metaclass=M):
395395

396396
def testFromString(self):
397397
self.assertEqual((5, 1), _components(F("5")))
398+
self.assertEqual((5, 1), _components(F("005")))
398399
self.assertEqual((3, 2), _components(F("3/2")))
399400
self.assertEqual((3, 2), _components(F("3 / 2")))
400401
self.assertEqual((3, 2), _components(F(" \n +3/2")))
401402
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 ")))
403404
self.assertEqual((16, 5), _components(F(" 3.2 ")))
405+
self.assertEqual((16, 5), _components(F("003.2")))
404406
self.assertEqual((-16, 5), _components(F(" -3.2 ")))
405407
self.assertEqual((-3, 1), _components(F(" -3. ")))
406408
self.assertEqual((3, 5), _components(F(" .6 ")))
@@ -419,116 +421,101 @@ def testFromString(self):
419421
self.assertRaisesMessage(
420422
ZeroDivisionError, "Fraction(3, 0)",
421423
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")
518491
# Test catastrophic backtracking.
519492
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))
532519

533520
def testImmutable(self):
534521
r = F(7, 3)

0 commit comments

Comments
 (0)