summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCrowthebird <78076854+thatbirdguythatuknownot@users.noreply.github.com>2024-01-13 12:02:39 (GMT)
committerGitHub <noreply@github.com>2024-01-13 12:02:39 (GMT)
commitdd56b5748317c3d504d6a9660d9207620c547f5c (patch)
tree62da7311e73f41d4377f6138f9413976a20e371b
parentc7d59bd8cfa053e77ae3446c82afff1fd38a4886 (diff)
downloadcpython-dd56b5748317c3d504d6a9660d9207620c547f5c.zip
cpython-dd56b5748317c3d504d6a9660d9207620c547f5c.tar.gz
cpython-dd56b5748317c3d504d6a9660d9207620c547f5c.tar.bz2
gh-114014: Update `fractions.Fraction()`'s rational parsing regex (#114015)
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: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
-rw-r--r--Lib/fractions.py20
-rw-r--r--Lib/test/test_fractions.py24
-rw-r--r--Misc/NEWS.d/next/Library/2024-01-13-11-34-29.gh-issue-114014.WRHifN.rst1
3 files changed, 35 insertions, 10 deletions
diff --git a/Lib/fractions.py b/Lib/fractions.py
index 6532d5d..389ab38 100644
--- a/Lib/fractions.py
+++ b/Lib/fractions.py
@@ -55,17 +55,17 @@ 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<sign>[-+]?) # an optional sign, then
- (?=\d|\.\d) # lookahead for digit or .digit
- (?P<num>\d*|\d+(_\d+)*) # numerator (possibly empty)
- (?: # followed by
- (?:\s*/\s*(?P<denom>\d+(_\d+)*))? # an optional denominator
- | # or
- (?:\.(?P<decimal>d*|\d+(_\d+)*))? # an optional fractional part
- (?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent
+ \A\s* # optional whitespace at the start,
+ (?P<sign>[-+]?) # an optional sign, then
+ (?=\d|\.\d) # lookahead for digit or .digit
+ (?P<num>\d*|\d+(_\d+)*) # numerator (possibly empty)
+ (?: # followed by
+ (?:\s*/\s*(?P<denom>\d+(_\d+)*))? # an optional denominator
+ | # or
+ (?:\.(?P<decimal>\d*|\d+(_\d+)*))? # an optional fractional part
+ (?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent
)
- \s*\Z # and optional whitespace to finish
+ \s*\Z # and optional whitespace to finish
""", re.VERBOSE | re.IGNORECASE)
diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py
index 8477952..af3cb21 100644
--- a/Lib/test/test_fractions.py
+++ b/Lib/test/test_fractions.py
@@ -261,6 +261,30 @@ class FractionTest(unittest.TestCase):
self.assertRaisesMessage(
ValueError, "Invalid literal for Fraction: '1.1e+1__1'",
F, "1.1e+1__1")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: '123.dd'",
+ F, "123.dd")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: '123.5_dd'",
+ F, "123.5_dd")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: 'dd.5'",
+ F, "dd.5")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: '7_dd'",
+ F, "7_dd")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: '1/dd'",
+ F, "1/dd")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: '1/123_dd'",
+ F, "1/123_dd")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: '789edd'",
+ F, "789edd")
+ self.assertRaisesMessage(
+ ValueError, "Invalid literal for Fraction: '789e2_dd'",
+ F, "789e2_dd")
# Test catastrophic backtracking.
val = "9"*50 + "_"
self.assertRaisesMessage(
diff --git a/Misc/NEWS.d/next/Library/2024-01-13-11-34-29.gh-issue-114014.WRHifN.rst b/Misc/NEWS.d/next/Library/2024-01-13-11-34-29.gh-issue-114014.WRHifN.rst
new file mode 100644
index 0000000..a6630d7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-01-13-11-34-29.gh-issue-114014.WRHifN.rst
@@ -0,0 +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.