Skip to content

Commit 41edd37

Browse files
mdickinsonthatbirdguythatuknownotblurb-it[bot]AA-Turner
authored
[3.11] gh-114014: Update fractions.Fraction()'s rational parsing regex (GH-114015) (#114025)
Fix a bug in the regex used for parsing a string input to the `fractions.Fraction` constructor. That bug led to an inconsistent exception message being given for some inputs. --------- Co-authored-by: Crowthebird <[email protected]> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Adam Turner <[email protected]>
1 parent 25af45d commit 41edd37

File tree

3 files changed

+35
-10
lines changed

3 files changed

+35
-10
lines changed

Lib/fractions.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@
2121
_PyHASH_INF = sys.hash_info.inf
2222

2323
_RATIONAL_FORMAT = re.compile(r"""
24-
\A\s* # optional whitespace at the start,
25-
(?P<sign>[-+]?) # an optional sign, then
26-
(?=\d|\.\d) # lookahead for digit or .digit
27-
(?P<num>\d*|\d+(_\d+)*) # numerator (possibly empty)
28-
(?: # followed by
29-
(?:/(?P<denom>\d+(_\d+)*))? # an optional denominator
30-
| # or
31-
(?:\.(?P<decimal>d*|\d+(_\d+)*))? # an optional fractional part
32-
(?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent
24+
\A\s* # optional whitespace at the start,
25+
(?P<sign>[-+]?) # an optional sign, then
26+
(?=\d|\.\d) # lookahead for digit or .digit
27+
(?P<num>\d*|\d+(_\d+)*) # numerator (possibly empty)
28+
(?: # followed by
29+
(?:/(?P<denom>\d+(_\d+)*))? # an optional denominator
30+
| # or
31+
(?:\.(?P<decimal>\d*|\d+(_\d+)*))? # an optional fractional part
32+
(?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent
3333
)
34-
\s*\Z # and optional whitespace to finish
34+
\s*\Z # and optional whitespace to finish
3535
""", re.VERBOSE | re.IGNORECASE)
3636

3737

Lib/test/test_fractions.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,30 @@ def testFromString(self):
259259
self.assertRaisesMessage(
260260
ValueError, "Invalid literal for Fraction: '1.1e+1__1'",
261261
F, "1.1e+1__1")
262+
self.assertRaisesMessage(
263+
ValueError, "Invalid literal for Fraction: '123.dd'",
264+
F, "123.dd")
265+
self.assertRaisesMessage(
266+
ValueError, "Invalid literal for Fraction: '123.5_dd'",
267+
F, "123.5_dd")
268+
self.assertRaisesMessage(
269+
ValueError, "Invalid literal for Fraction: 'dd.5'",
270+
F, "dd.5")
271+
self.assertRaisesMessage(
272+
ValueError, "Invalid literal for Fraction: '7_dd'",
273+
F, "7_dd")
274+
self.assertRaisesMessage(
275+
ValueError, "Invalid literal for Fraction: '1/dd'",
276+
F, "1/dd")
277+
self.assertRaisesMessage(
278+
ValueError, "Invalid literal for Fraction: '1/123_dd'",
279+
F, "1/123_dd")
280+
self.assertRaisesMessage(
281+
ValueError, "Invalid literal for Fraction: '789edd'",
282+
F, "789edd")
283+
self.assertRaisesMessage(
284+
ValueError, "Invalid literal for Fraction: '789e2_dd'",
285+
F, "789e2_dd")
262286
# Test catastrophic backtracking.
263287
val = "9"*50 + "_"
264288
self.assertRaisesMessage(
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed a bug in :class:`fractions.Fraction` where an invalid string using ``d`` in the decimals part creates a different error compared to other invalid letters/characters. Patch by Jeremiah Gabriel Pascual.

0 commit comments

Comments
 (0)