diff options
author | Mark Dickinson <dickinsm@gmail.com> | 2009-04-22 17:50:21 (GMT) |
---|---|---|
committer | Mark Dickinson <dickinsm@gmail.com> | 2009-04-22 17:50:21 (GMT) |
commit | cf63f2fb88826ae67843b8574bca6ef25c2e791f (patch) | |
tree | 81dbf873651fdd3f9a2dcabd3c291d9911aad609 /Lib/fractions.py | |
parent | 937491d1a9a327a782f3717fd1a0d4d9ad8fdc36 (diff) | |
download | cpython-cf63f2fb88826ae67843b8574bca6ef25c2e791f.zip cpython-cf63f2fb88826ae67843b8574bca6ef25c2e791f.tar.gz cpython-cf63f2fb88826ae67843b8574bca6ef25c2e791f.tar.bz2 |
Issue #5812: Make Fraction('1e6') valid. The Fraction constructor now
accepts all strings accepted by the float and Decimal constructors,
with the exception of strings representing NaNs or infinities.
Diffstat (limited to 'Lib/fractions.py')
-rwxr-xr-x | Lib/fractions.py | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/Lib/fractions.py b/Lib/fractions.py index ed1e9a0..5242f8f 100755 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -28,13 +28,14 @@ _RATIONAL_FORMAT = re.compile(r""" (?P<sign>[-+]?) # an optional sign, then (?=\d|\.\d) # lookahead for digit or .digit (?P<num>\d*) # numerator (possibly empty) - (?: # followed by an optional - /(?P<denom>\d+) # / and denominator + (?: # followed by + (?:/(?P<denom>\d+))? # an optional denominator | # or - \.(?P<decimal>\d*) # decimal point and fractional part - )? + (?:\.(?P<decimal>\d*))? # an optional fractional part + (?:E(?P<exp>[-+]?\d+))? # and optional exponent + ) \s*\Z # and optional whitespace to finish -""", re.VERBOSE) +""", re.VERBOSE | re.IGNORECASE) class Fraction(numbers.Rational): @@ -65,22 +66,28 @@ class Fraction(numbers.Rational): if not isinstance(numerator, int) and denominator == 1: if isinstance(numerator, str): # Handle construction from strings. - input = numerator - m = _RATIONAL_FORMAT.match(input) + m = _RATIONAL_FORMAT.match(numerator) if m is None: - raise ValueError('Invalid literal for Fraction: %r' % input) - numerator = m.group('num') - decimal = m.group('decimal') - if decimal: - # The literal is a decimal number. - numerator = int(numerator + decimal) - denominator = 10**len(decimal) + raise ValueError('Invalid literal for Fraction: %r' % + numerator) + numerator = int(m.group('num') or '0') + denom = m.group('denom') + if denom: + denominator = int(denom) else: - # The literal is an integer or fraction. - numerator = int(numerator) - # Default denominator to 1. - denominator = int(m.group('denom') or 1) - + denominator = 1 + decimal = m.group('decimal') + if decimal: + scale = 10**len(decimal) + numerator = numerator * scale + int(decimal) + denominator *= scale + exp = m.group('exp') + if exp: + exp = int(exp) + if exp >= 0: + numerator *= 10**exp + else: + denominator *= 10**-exp if m.group('sign') == '-': numerator = -numerator |