gh-157710: Avoid copy for large int in PyUnicodeWriter_WriteStr() (#158448)

Enable the PyUnicodeWriter read-only optimization for large integer
(more than 1000 digits) in PyUnicodeWriter_WriteStr() and
PyUnicodeWriter_WriteRepr().
This commit is contained in:
Victor Stinner authored and GitHub committed 2026-09-29 22:15:41 +02:00
1 parent a0491c8939
commit 39e5ed7fea
2 files changed
+29 -4

No files matched your search

+29
View File
@@ -2267,6 +2267,35 @@ class PyUnicodeWriterTest(unittest.TestCase):
self.assertEqual(writer.get_buffer(), expected)
self.assertIs(writer.finish(), unique_string)
def test_readonly_optim_large_int(self):
# Read-only optimization in _PyLong_FormatWriter() for large integer:
# use _pylong.int_to_decimal_string() result as a read-only string.
# See pylong_int_to_decimal_string().
self.addCleanup(sys.set_int_max_str_digits,
sys.get_int_max_str_digits())
sys.set_int_max_str_digits(0)
# _PyLong_FormatWriter() calls _pylong.int_to_decimal_string() for
# integer with Py_SIZE() > 1000.
large_int = 1 << (sys.int_info.bits_per_digit * 1020)
large_int_str = str(large_int)
expected = (len(large_int_str), 127, True)
for size in (0, 123):
with self.subTest(size=size):
# Test PyUnicodeWriter_WriteStr()
writer = self.create_writer(size)
writer.write_str(large_int)
self.assertEqual(writer.get_buffer(), expected)
self.assertEqual(writer.finish(), large_int_str)
# Test PyUnicodeWriter_WriteRepr()
writer = self.create_writer(size)
writer.write_repr(large_int)
self.assertEqual(writer.get_buffer(), expected)
self.assertEqual(writer.finish(), large_int_str)
# Test PyUnicodeWriter_Format()
@unittest.skipIf(ctypes is None, 'need ctypes')
-4
View File
@@ -2045,10 +2045,6 @@ pylong_int_to_decimal_string(PyObject *aa,
goto error;
}
if (writer) {
Py_ssize_t size = PyUnicode_GET_LENGTH(s);
if (_PyUnicodeWriter_Prepare(writer, size, '9') == -1) {
goto error;
}
if (_PyUnicodeWriter_WriteStr(writer, s) < 0) {
goto error;
}