https://github.com/python/cpython/commit/4c73f50ca9885e5850dae64463e87cf5e80992a1 commit: 4c73f50ca9885e5850dae64463e87cf5e80992a1 branch: main author: Donghee Na <[email protected]> committer: corona10 <[email protected]> date: 2026-10-19T21:00:42-07:00 summary:
gh-159813: Add a fast path for None in PyUnicodeWriter_WriteRepr (gh-159814) Co-authored-by: Victor Stinner <[email protected]> files: A Misc/NEWS.d/next/Core_and_Builtins/2026-10-19-16-38-39.gh-issue-159813.wHfSOc.rst M Lib/test/test_capi/test_unicode.py M Modules/_testcapi/unicode.c M Objects/unicode_writer.c diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py index 9237809e7f0dcca..0358bc38dfdf322 100644 --- a/Lib/test/test_capi/test_unicode.py +++ b/Lib/test/test_capi/test_unicode.py @@ -2038,6 +2038,21 @@ def __str__(self): self.assertEqual(result, 'abc') self.assertIs(type(result), str) + def test_repr(self): + # Test PyUnicodeWriter_WriteRepr() + writer = self.create_writer(0) + writer.write_str('str=') + writer.write_repr('abc') + writer.write_str(' int=') + writer.write_repr(123) + writer.write_str(' none=') + writer.write_repr_none() + obj = object() + writer.write_str(' obj=') + writer.write_repr(obj) + self.assertEqual(writer.finish(), + f"str='abc' int=123 none=None obj={obj!r}") + def test_repr_null(self): writer = self.create_writer(0) writer.write_utf8(b'var=', -1) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-19-16-38-39.gh-issue-159813.wHfSOc.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-19-16-38-39.gh-issue-159813.wHfSOc.rst new file mode 100644 index 000000000000000..7d5f0c8f2f53540 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-19-16-38-39.gh-issue-159813.wHfSOc.rst @@ -0,0 +1,2 @@ +Add a fast path for :const:`None` in :c:func:`PyUnicodeWriter_WriteRepr`. +Patch by Donghee Na. diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c index ec3e9a623519f6e..19178b2977e62ed 100644 --- a/Modules/_testcapi/unicode.c +++ b/Modules/_testcapi/unicode.c @@ -689,6 +689,23 @@ writer_write_repr(PyObject *self_raw, PyObject *obj) } +// write_repr(None) calls PyUnicodeWriter_WriteRepr(writer, NULL), so add +// a specialized function calling PyUnicodeWriter_WriteRepr(writer, Py_None). +static PyObject* +writer_write_repr_none(PyObject *self_raw, PyObject *Py_UNUSED(arg)) +{ + WriterObject *self = (WriterObject *)self_raw; + if (writer_check(self) < 0) { + return NULL; + } + + if (PyUnicodeWriter_WriteRepr(self->writer, Py_None) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + static PyObject* writer_write_substring(PyObject *self_raw, PyObject *args) { @@ -854,6 +871,7 @@ static PyMethodDef writer_methods[] = { {"write_ucs4", _PyCFunction_CAST(writer_write_ucs4), METH_VARARGS}, {"write_str", _PyCFunction_CAST(writer_write_str), METH_O}, {"write_repr", _PyCFunction_CAST(writer_write_repr), METH_O}, + {"write_repr_none", _PyCFunction_CAST(writer_write_repr_none), METH_NOARGS}, {"write_substring", _PyCFunction_CAST(writer_write_substring), METH_VARARGS}, {"write_latin1", _PyCFunction_CAST(writer_write_latin1), METH_VARARGS}, {"decodeutf8stateful", _PyCFunction_CAST(writer_decodeutf8stateful), METH_VARARGS}, diff --git a/Objects/unicode_writer.c b/Objects/unicode_writer.c index e1c8cb884a102f1..8046accfd7e2abb 100644 --- a/Objects/unicode_writer.c +++ b/Objects/unicode_writer.c @@ -320,6 +320,10 @@ PyUnicodeWriter_WriteRepr(PyUnicodeWriter *pub_writer, PyObject *obj) if (Py_TYPE(obj) == &PyLong_Type) { return _PyLong_FormatWriter(writer, obj, 10, 0); } + // Fast path for None; see gh-159813 for the rationale. + if (obj == Py_None) { + return _PyUnicodeWriter_WriteASCIIString(writer, "None", 4); + } PyObject *repr = PyObject_Repr(obj); if (repr == NULL) { _______________________________________________ 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]
