From 9c2e30d3ca18fb651c35959993d7cefc21c5140a Mon Sep 17 00:00:00 2001 From: tonghuaroot Date: Thu, 9 Jul 2026 13:59:54 +0800 Subject: [PATCH 1/2] gh-153392: Raise TOMLDecodeError for over-long integers in tomllib The number branch of tomllib's value parser called match_to_number without wrapping ValueError, so an integer with more digits than the interpreter's integer string conversion limit escaped as a bare ValueError. The date and time branch already wraps ValueError into TOMLDecodeError; do the same for the number branch so tomllib only raises TOMLDecodeError on a malformed document. --- Lib/test/test_tomllib/test_error.py | 10 ++++++++++ Lib/tomllib/_parser.py | 6 +++++- .../2026-07-09-12-30-00.gh-issue-153392.Tm1Num.rst | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2026-07-09-12-30-00.gh-issue-153392.Tm1Num.rst diff --git a/Lib/test/test_tomllib/test_error.py b/Lib/test/test_tomllib/test_error.py index 3a8587492859ca6..db25a8d42f37d01 100644 --- a/Lib/test/test_tomllib/test_error.py +++ b/Lib/test/test_tomllib/test_error.py @@ -34,6 +34,16 @@ def test_missing_value(self): tomllib.loads("\n\nfwfw=") self.assertEqual(str(exc_info.exception), "Invalid value (at end of document)") + def test_overlong_integer(self): + # An integer with more digits than the int-to-str conversion limit + # must raise TOMLDecodeError, not the bare ValueError from int(). + from test.support import adjust_int_max_str_digits + with adjust_int_max_str_digits(1000): + digits = "9" * 1001 + for src in (f"x = {digits}", f"x = -{digits}"): + with self.assertRaises(tomllib.TOMLDecodeError): + tomllib.loads(src) + def test_invalid_char_quotes(self): with self.assertRaises(tomllib.TOMLDecodeError) as exc_info: tomllib.loads("v = '\n'") diff --git a/Lib/tomllib/_parser.py b/Lib/tomllib/_parser.py index b89934808008efc..4620fdef07d65c8 100644 --- a/Lib/tomllib/_parser.py +++ b/Lib/tomllib/_parser.py @@ -738,7 +738,11 @@ def parse_value( # char, so needs to be located after handling of dates and times. number_match = RE_NUMBER.match(src, pos) if number_match: - return number_match.end(), match_to_number(number_match, parse_float) + try: + number = match_to_number(number_match, parse_float) + except ValueError as e: + raise TOMLDecodeError("Invalid number", src, pos) from e + return number_match.end(), number # Special floats first_three = src[pos : pos + 3] diff --git a/Misc/NEWS.d/next/Library/2026-07-09-12-30-00.gh-issue-153392.Tm1Num.rst b/Misc/NEWS.d/next/Library/2026-07-09-12-30-00.gh-issue-153392.Tm1Num.rst new file mode 100644 index 000000000000000..d5f8508eb7c4f12 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-09-12-30-00.gh-issue-153392.Tm1Num.rst @@ -0,0 +1,3 @@ +:func:`tomllib.loads` now raises :exc:`tomllib.TOMLDecodeError` instead of +:exc:`ValueError` when a document contains an integer with more digits than the +interpreter's integer string conversion limit. From c18c6e6c3605a95d15f4f770b0b7e1c3256421de Mon Sep 17 00:00:00 2001 From: tonghuaroot Date: Thu, 9 Jul 2026 15:10:44 +0800 Subject: [PATCH 2/2] Preserve parse_float error propagation Only wrap the integer conversion's ValueError into TOMLDecodeError. A parse_float callback raising ValueError must propagate unchanged, which test_invalid_parse_float asserts. --- Lib/tomllib/_parser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/tomllib/_parser.py b/Lib/tomllib/_parser.py index 4620fdef07d65c8..1a573d62c99afda 100644 --- a/Lib/tomllib/_parser.py +++ b/Lib/tomllib/_parser.py @@ -741,6 +741,9 @@ def parse_value( try: number = match_to_number(number_match, parse_float) except ValueError as e: + if number_match.group("floatpart"): + # A failing parse_float raises its own error unchanged. + raise raise TOMLDecodeError("Invalid number", src, pos) from e return number_match.end(), number