https://github.com/python/cpython/commit/39e5ed7fea8364dc30efd3fa5d68644606b0eac8
commit: 39e5ed7fea8364dc30efd3fa5d68644606b0eac8
branch: main
author: Victor Stinner <[email protected]>
committer: vstinner <[email protected]>
date: 2026-09-29T22:15:41+02:00
summary:
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().
files:
M Lib/test/test_capi/test_unicode.py
M Objects/longobject.c
diff --git a/Lib/test/test_capi/test_unicode.py
b/Lib/test/test_capi/test_unicode.py
index fc2bec2124a39b..36ecca48230ddd 100644
--- a/Lib/test/test_capi/test_unicode.py
+++ b/Lib/test/test_capi/test_unicode.py
@@ -2267,6 +2267,35 @@ def __repr__(self):
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')
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 1dac70820d142b..b9f00ca6fb471b 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -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;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]