https://github.com/python/cpython/commit/3cdb659a0cbf2c67100b172e7ece6b906ea45718
commit: 3cdb659a0cbf2c67100b172e7ece6b906ea45718
branch: 3.14
author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com>
committer: picnixz <10796600+picn...@users.noreply.github.com>
date: 2025-06-24T12:02:02Z
summary:

[3.14] gh-135487: fix `reprlib.Repr.repr_int` when given very large integers 
(GH-135506) (#135887)

gh-135487: fix `reprlib.Repr.repr_int` when given very large integers 
(GH-135506)
(cherry picked from commit e5f03b94b6d4decbf433d385f692c1b8d9b7e88d)

Co-authored-by: Bénédikt Tran <10796600+picn...@users.noreply.github.com>

files:
A Misc/NEWS.d/next/Library/2025-06-14-12-06-55.gh-issue-135487.KdVFff.rst
M Lib/reprlib.py
M Lib/test/test_reprlib.py

diff --git a/Lib/reprlib.py b/Lib/reprlib.py
index 441d1be4bdede2..ab18247682b69a 100644
--- a/Lib/reprlib.py
+++ b/Lib/reprlib.py
@@ -181,7 +181,22 @@ def repr_str(self, x, level):
         return s
 
     def repr_int(self, x, level):
-        s = builtins.repr(x) # XXX Hope this isn't too slow...
+        try:
+            s = builtins.repr(x)
+        except ValueError as exc:
+            assert 'sys.set_int_max_str_digits()' in str(exc)
+            # Those imports must be deferred due to Python's build system
+            # where the reprlib module is imported before the math module.
+            import math, sys
+            # Integers with more than sys.get_int_max_str_digits() digits
+            # are rendered differently as their repr() raises a ValueError.
+            # See https://github.com/python/cpython/issues/135487.
+            k = 1 + int(math.log10(abs(x)))
+            # Note: math.log10(abs(x)) may be overestimated or underestimated,
+            # but for simplicity, we do not compute the exact number of digits.
+            max_digits = sys.get_int_max_str_digits()
+            return (f'<{x.__class__.__name__} instance with roughly {k} '
+                    f'digits (limit at {max_digits}) at 0x{id(x):x}>')
         if len(s) > self.maxlong:
             i = max(0, (self.maxlong-3)//2)
             j = max(0, self.maxlong-3-i)
diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py
index 16623654c29b28..d5631efcdb75b7 100644
--- a/Lib/test/test_reprlib.py
+++ b/Lib/test/test_reprlib.py
@@ -151,14 +151,38 @@ def test_frozenset(self):
         eq(r(frozenset({1, 2, 3, 4, 5, 6, 7})), "frozenset({1, 2, 3, 4, 5, 6, 
...})")
 
     def test_numbers(self):
-        eq = self.assertEqual
-        eq(r(123), repr(123))
-        eq(r(123), repr(123))
-        eq(r(1.0/3), repr(1.0/3))
-
-        n = 10**100
-        expected = repr(n)[:18] + "..." + repr(n)[-19:]
-        eq(r(n), expected)
+        for x in [123, 1.0 / 3]:
+            self.assertEqual(r(x), repr(x))
+
+        max_digits = sys.get_int_max_str_digits()
+        for k in [100, max_digits - 1]:
+            with self.subTest(f'10 ** {k}', k=k):
+                n = 10 ** k
+                expected = repr(n)[:18] + "..." + repr(n)[-19:]
+                self.assertEqual(r(n), expected)
+
+        def re_msg(n, d):
+            return (rf'<{n.__class__.__name__} instance with roughly {d} '
+                    rf'digits \(limit at {max_digits}\) at 0x[a-f0-9]+>')
+
+        k = max_digits
+        with self.subTest(f'10 ** {k}', k=k):
+            n = 10 ** k
+            self.assertRaises(ValueError, repr, n)
+            self.assertRegex(r(n), re_msg(n, k + 1))
+
+        for k in [max_digits + 1, 2 * max_digits]:
+            self.assertGreater(k, 100)
+            with self.subTest(f'10 ** {k}', k=k):
+                n = 10 ** k
+                self.assertRaises(ValueError, repr, n)
+                self.assertRegex(r(n), re_msg(n, k + 1))
+            with self.subTest(f'10 ** {k} - 1', k=k):
+                n = 10 ** k - 1
+                # Here, since math.log10(n) == math.log10(n-1),
+                # the number of digits of n - 1 is overestimated.
+                self.assertRaises(ValueError, repr, n)
+                self.assertRegex(r(n), re_msg(n, k + 1))
 
     def test_instance(self):
         eq = self.assertEqual
diff --git 
a/Misc/NEWS.d/next/Library/2025-06-14-12-06-55.gh-issue-135487.KdVFff.rst 
b/Misc/NEWS.d/next/Library/2025-06-14-12-06-55.gh-issue-135487.KdVFff.rst
new file mode 100644
index 00000000000000..3ef51fa31dfac9
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-06-14-12-06-55.gh-issue-135487.KdVFff.rst
@@ -0,0 +1,2 @@
+Fix :meth:`!reprlib.Repr.repr_int` when given integers with more than
+:func:`sys.get_int_max_str_digits` digits. Patch by Bénédikt Tran.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: arch...@mail-archive.com

Reply via email to