Skip to content

Commit 92b3f8f

Browse files
committed
Improve fractions startup time
1 parent 5d41632 commit 92b3f8f

2 files changed

Lines changed: 17 additions & 17 deletions

File tree

Lib/fractions.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,18 @@ def _hash_algorithm(numerator, denominator):
5454
return -2 if result == -1 else result
5555

5656
_RATIONAL_FORMAT = re.compile(r"""
57-
\A\s* # optional whitespace at the start,
58-
(?P<sign>[-+]?) # an optional sign, then
59-
(?=\d|\.\d) # lookahead for digit or .digit
60-
(?P<num>\d*|\d+(_\d+)*) # numerator (possibly empty)
61-
(?: # followed by
62-
(?:\s*/\s*(?P<denom>\d+(_\d+)*))? # an optional denominator
63-
| # or
64-
(?:\.(?P<decimal>\d*|\d+(_\d+)*))? # an optional fractional part
65-
(?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent
57+
\A\s*+ # optional whitespace at the start,
58+
(?P<sign>[-+]?+) # an optional sign, then
59+
(?=\d|\.\d) # lookahead for digit or .digit
60+
(?P<num>(?:\d++(?:_\d++)*+)?+) # numerator (possibly empty)
61+
(?: # followed by
62+
\s*+/\s*+(?P<denom>\d++(?:_\d++)*+) # a denominator
63+
| # or
64+
(?:\.(?P<decimal>(?:\d++(?:_\d++)*+)?+))?+ # an optional fractional part
65+
(?:[eE](?P<exp>[-+]?+\d++(?:_\d++)*+))?+ # and optional exponent
6666
)
67-
\s*\z # and optional whitespace to finish
68-
""", re.VERBOSE | re.IGNORECASE)
67+
\s*+\z # and optional whitespace to finish
68+
""", re.VERBOSE)
6969

7070

7171
# Helpers for formatting
@@ -255,26 +255,24 @@ def __new__(cls, numerator=0, denominator=None):
255255
if m is None:
256256
raise ValueError('Invalid literal for Fraction: %r' %
257257
numerator)
258-
numerator = int(m.group('num') or '0')
259-
denom = m.group('denom')
258+
sign, num, denom, decimal, exp = m.groups()
259+
numerator = int(num) if num else 0
260260
if denom:
261261
denominator = int(denom)
262262
else:
263263
denominator = 1
264-
decimal = m.group('decimal')
265264
if decimal:
266265
decimal = decimal.replace('_', '')
267266
scale = 10**len(decimal)
268267
numerator = numerator * scale + int(decimal)
269-
denominator *= scale
270-
exp = m.group('exp')
268+
denominator = scale
271269
if exp:
272270
exp = int(exp)
273271
if exp >= 0:
274272
numerator *= 10**exp
275273
else:
276274
denominator *= 10**-exp
277-
if m.group('sign') == '-':
275+
if sign == '-':
278276
numerator = -numerator
279277

280278
elif isinstance(numerator, numbers.Rational):

Lib/test/test_fractions.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ def check_invalid(s):
434434
# Imitate float's parsing.
435435
check_invalid("+ 3/2")
436436
check_invalid("- 3/2")
437+
check_invalid("+ 343.33")
437438
# Avoid treating '.' as a regex special character.
438439
check_invalid("3a2")
439440
# Don't accept combinations of decimals and rationals.
@@ -445,6 +446,7 @@ def check_invalid(s):
445446
# No space around e.
446447
check_invalid("3.2 e1")
447448
check_invalid("3.2e 1")
449+
check_invalid("232e\t2")
448450
# Fractional part don't need a sign.
449451
check_invalid("3.+2")
450452
check_invalid("3.-2")

0 commit comments

Comments
 (0)