8000 gh-72902: improve Fraction(str) speed (don't use regexp's) by skirpichev · Pull Request #133994 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-72902: improve Fraction(str) speed (don't use regexp's) #133994

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
+ a quick fix
  • Loading branch information
skirpichev committed May 16, 2025
commit 05e9110cd59b9e2c5bfd78c41257138af28c85c8
21 changes: 16 additions & 5 deletions Lib/fractions.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,31 +247,42 @@ def __new__(cls, numerator=0, denominator=None):
if _ and not exp:
raise ValueError
num, _, decimal = num.partition('.')
if decimal:
if num and num[0] in ('+', '-'):
if num:
if num[0] in ('+', '-'):
sign = num[0] == '-'
num = num[1:]
else:
sign = 0
if num and not (num[-1].isdigit() and num[0].isdigit()):
raise ValueError
else:
sign = 0
if decimal:
if not decimal[0].isdigit() or not decimal[-1].isdigit():
raise ValueError
numerator = int(num or '0')
decimal_len = len(decimal.replace('_', ''))
decimal = int(decimal)
scale = 10**decimal_len
numerator = numerator*scale + decimal
denominator *= scale
if sign:
numerator = -numerator
else:
numerator = int(num)
if sign:
numerator = -numerator
if exp:
if not (exp[0] in ('+', '-') or exp[0].isdigit()):
raise ValueError
exp = int(exp)
if exp >= 0:
numerator *= 10**exp
else:
denominator *= 10**-exp
else:
raise ValueError
except ValueError:
except ValueError as exc:
if exc.args and re.match('^Exceeds', exc.args[0]):
raise
raise ValueError('Invalid literal for Fraction: %r' %
fraction_literal)

Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_fractions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading
0