diff --git a/Lib/fractions.py b/Lib/fractions.py index c1b12e7a1c091c..a1c854e3295bdd 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -54,18 +54,18 @@ def _hash_algorithm(numerator, denominator): return -2 if result == -1 else result _RATIONAL_FORMAT = re.compile(r""" - \A\s* # optional whitespace at the start, - (?P[-+]?) # an optional sign, then - (?=\d|\.\d) # lookahead for digit or .digit - (?P\d*|\d+(_\d+)*) # numerator (possibly empty) - (?: # followed by - (?:\s*/\s*(?P\d+(_\d+)*))? # an optional denominator - | # or - (?:\.(?P\d*|\d+(_\d+)*))? # an optional fractional part - (?:E(?P[-+]?\d+(_\d+)*))? # and optional exponent + \A\s*+ # optional whitespace at the start, + (?P[-+]?+) # an optional sign, then + (?=\d|\.\d) # lookahead for digit or .digit + (?P(?:\d++(?:_\d++)*+)?+) # numerator (possibly empty) + (?: # followed by + \s*+/\s*+(?P\d++(?:_\d++)*+) # a denominator + | # or + (?:\.(?P(?:\d++(?:_\d++)*+)?+))?+ # an optional fractional part + (?:[eE](?P[-+]?+\d++(?:_\d++)*+))?+ # and optional exponent ) - \s*\z # and optional whitespace to finish -""", re.VERBOSE | re.IGNORECASE) + \s*+\z # and optional whitespace to finish +""", re.VERBOSE) # Helpers for formatting @@ -255,26 +255,24 @@ def __new__(cls, numerator=0, denominator=None): if m is None: raise ValueError('Invalid literal for Fraction: %r' % numerator) - numerator = int(m.group('num') or '0') - denom = m.group('denom') + sign, num, denom, decimal, exp = m.groups() + numerator = int(num) if num else 0 if denom: denominator = int(denom) else: denominator = 1 - decimal = m.group('decimal') if decimal: decimal = decimal.replace('_', '') scale = 10**len(decimal) numerator = numerator * scale + int(decimal) - denominator *= scale - exp = m.group('exp') + denominator = scale if exp: exp = int(exp) if exp >= 0: numerator *= 10**exp else: denominator *= 10**-exp - if m.group('sign') == '-': + if sign == '-': numerator = -numerator elif isinstance(numerator, numbers.Rational): diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index cf42b86358dbca..d0b573ff474f4b 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -434,6 +434,7 @@ def check_invalid(s): # Imitate float's parsing. check_invalid("+ 3/2") check_invalid("- 3/2") + check_invalid("+ 343.33") # Avoid treating '.' as a regex special character. check_invalid("3a2") # Don't accept combinations of decimals and rationals. @@ -445,6 +446,7 @@ def check_invalid(s): # No space around e. check_invalid("3.2 e1") check_invalid("3.2e 1") + check_invalid("232e\t2") # Fractional part don't need a sign. check_invalid("3.+2") check_invalid("3.-2")