mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-135487: fix reprlib.Repr.repr_int
when given very large integers (#135506)
Some checks are pending
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
Some checks are pending
Tests / (push) Blocked by required conditions
Tests / Windows MSI (push) Blocked by required conditions
Tests / WASI (push) Blocked by required conditions
Tests / Change detection (push) Waiting to run
Tests / Docs (push) Blocked by required conditions
Tests / Check if Autoconf files are up to date (push) Blocked by required conditions
Tests / Check if generated files are up to date (push) Blocked by required conditions
Tests / Hypothesis tests on Ubuntu (push) Blocked by required conditions
Tests / Ubuntu SSL tests with OpenSSL (push) Blocked by required conditions
Tests / Address sanitizer (push) Blocked by required conditions
Tests / Undefined behavior sanitizer (push) Blocked by required conditions
Tests / Cross build Linux (push) Blocked by required conditions
Tests / CIFuzz (push) Blocked by required conditions
Tests / All required checks pass (push) Blocked by required conditions
Lint / lint (push) Waiting to run
mypy / Run mypy on Lib/_pyrepl (push) Waiting to run
mypy / Run mypy on Lib/test/libregrtest (push) Waiting to run
mypy / Run mypy on Lib/tomllib (push) Waiting to run
mypy / Run mypy on Tools/build (push) Waiting to run
mypy / Run mypy on Tools/cases_generator (push) Waiting to run
mypy / Run mypy on Tools/clinic (push) Waiting to run
mypy / Run mypy on Tools/jit (push) Waiting to run
mypy / Run mypy on Tools/peg_generator (push) Waiting to run
This commit is contained in:
parent
15c6d63fe6
commit
e5f03b94b6
3 changed files with 49 additions and 8 deletions
|
@ -181,7 +181,22 @@ class Repr:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def repr_int(self, x, level):
|
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:
|
if len(s) > self.maxlong:
|
||||||
i = max(0, (self.maxlong-3)//2)
|
i = max(0, (self.maxlong-3)//2)
|
||||||
j = max(0, self.maxlong-3-i)
|
j = max(0, self.maxlong-3-i)
|
||||||
|
|
|
@ -151,14 +151,38 @@ class ReprTests(unittest.TestCase):
|
||||||
eq(r(frozenset({1, 2, 3, 4, 5, 6, 7})), "frozenset({1, 2, 3, 4, 5, 6, ...})")
|
eq(r(frozenset({1, 2, 3, 4, 5, 6, 7})), "frozenset({1, 2, 3, 4, 5, 6, ...})")
|
||||||
|
|
||||||
def test_numbers(self):
|
def test_numbers(self):
|
||||||
eq = self.assertEqual
|
for x in [123, 1.0 / 3]:
|
||||||
eq(r(123), repr(123))
|
self.assertEqual(r(x), repr(x))
|
||||||
eq(r(123), repr(123))
|
|
||||||
eq(r(1.0/3), repr(1.0/3))
|
|
||||||
|
|
||||||
n = 10**100
|
max_digits = sys.get_int_max_str_digits()
|
||||||
expected = repr(n)[:18] + "..." + repr(n)[-19:]
|
for k in [100, max_digits - 1]:
|
||||||
eq(r(n), expected)
|
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):
|
def test_instance(self):
|
||||||
eq = self.assertEqual
|
eq = self.assertEqual
|
||||||
|
|
|
@ -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.
|
Loading…
Add table
Add a link
Reference in a new issue