From 8c33f9156279bb3c78f559a071c2330a9412945f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 9 Oct 2024 18:16:30 +0200 Subject: [PATCH 1/5] gh-125196: Use PyUnicodeWriter for repr(list) Replace the private _PyUnicodeWriter with the public PyUnicodeWriter. --- Objects/listobject.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 8abe15d6674140..e6b5c0c4052aa5 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -522,49 +522,45 @@ list_dealloc(PyObject *self) static PyObject * list_repr_impl(PyListObject *v) { - PyObject *s; - _PyUnicodeWriter writer; - Py_ssize_t i = Py_ReprEnter((PyObject*)v); - if (i != 0) { - return i > 0 ? PyUnicode_FromString("[...]") : NULL; + int res = Py_ReprEnter((PyObject*)v); + if (res != 0) { + return (res > 0 ? PyUnicode_FromString("[...]") : NULL); } - _PyUnicodeWriter_Init(&writer); - writer.overallocate = 1; /* "[" + "1" + ", 2" * (len - 1) + "]" */ - writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1; + Py_ssize_t prealloc = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1; + PyUnicodeWriter *writer = PyUnicodeWriter_Create(prealloc); + if (writer == NULL) { + return NULL; + } - if (_PyUnicodeWriter_WriteChar(&writer, '[') < 0) + if (PyUnicodeWriter_WriteChar(writer, '[') < 0) { goto error; + } /* Do repr() on each element. Note that this may mutate the list, so must refetch the list size on each iteration. */ - for (i = 0; i < Py_SIZE(v); ++i) { + for (Py_ssize_t i = 0; i < Py_SIZE(v); ++i) { if (i > 0) { - if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) + if (PyUnicodeWriter_WriteUTF8(writer, ", ", 2) < 0) { goto error; + } } - s = PyObject_Repr(v->ob_item[i]); - if (s == NULL) - goto error; - - if (_PyUnicodeWriter_WriteStr(&writer, s) < 0) { - Py_DECREF(s); + if (PyUnicodeWriter_WriteRepr(writer, v->ob_item[i]) < 0) { goto error; } - Py_DECREF(s); } - writer.overallocate = 0; - if (_PyUnicodeWriter_WriteChar(&writer, ']') < 0) + if (PyUnicodeWriter_WriteChar(writer, ']') < 0) { goto error; + } Py_ReprLeave((PyObject *)v); - return _PyUnicodeWriter_Finish(&writer); + return PyUnicodeWriter_Finish(writer); error: - _PyUnicodeWriter_Dealloc(&writer); + PyUnicodeWriter_Discard(writer); Py_ReprLeave((PyObject *)v); return NULL; } From 5fa346657ede25028fffd40441ceddb1d76d54da Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 9 Oct 2024 21:31:23 +0200 Subject: [PATCH 2/5] Fix error handling --- Objects/listobject.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index e6b5c0c4052aa5..a6b3fb566aa065 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -531,7 +531,7 @@ list_repr_impl(PyListObject *v) Py_ssize_t prealloc = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1; PyUnicodeWriter *writer = PyUnicodeWriter_Create(prealloc); if (writer == NULL) { - return NULL; + goto error; } if (PyUnicodeWriter_WriteChar(writer, '[') < 0) { @@ -560,7 +560,9 @@ list_repr_impl(PyListObject *v) return PyUnicodeWriter_Finish(writer); error: - PyUnicodeWriter_Discard(writer); + if (writer != NULL) { + PyUnicodeWriter_Discard(writer); + } Py_ReprLeave((PyObject *)v); return NULL; } From 027301708c66f421877428988f0e87789cf7b0bc Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 9 Oct 2024 22:34:49 +0200 Subject: [PATCH 3/5] Avoid PyUnicodeWriter_WriteUTF8() --- Objects/listobject.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index a6b3fb566aa065..e7090f20001a39 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -542,7 +542,10 @@ list_repr_impl(PyListObject *v) so must refetch the list size on each iteration. */ for (Py_ssize_t i = 0; i < Py_SIZE(v); ++i) { if (i > 0) { - if (PyUnicodeWriter_WriteUTF8(writer, ", ", 2) < 0) { + if (PyUnicodeWriter_WriteChar(writer, ',') < 0) { + goto error; + } + if (PyUnicodeWriter_WriteChar(writer, ' ') < 0) { goto error; } } From 8b33b0e5fa9dbe5dba3c0d71251efa0e5cd83273 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 9 Oct 2024 22:38:55 +0200 Subject: [PATCH 4/5] PyUnicodeWriter_Discard(NULL) does nothing --- Objects/listobject.c | 4 +--- Objects/unicodeobject.c | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index e7090f20001a39..930aefde325a7c 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -563,9 +563,7 @@ list_repr_impl(PyListObject *v) return PyUnicodeWriter_Finish(writer); error: - if (writer != NULL) { - PyUnicodeWriter_Discard(writer); - } + PyUnicodeWriter_Discard(writer); Py_ReprLeave((PyObject *)v); return NULL; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index bd5bb5048fdacc..4cb049d90a0182 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13428,6 +13428,9 @@ PyUnicodeWriter_Create(Py_ssize_t length) void PyUnicodeWriter_Discard(PyUnicodeWriter *writer) { + if (writer == NULL) { + return; + } _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer); PyMem_Free(writer); } From 9c910b593ab92d46de6c854814c0889029699083 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 9 Oct 2024 22:49:34 +0200 Subject: [PATCH 5/5] Revert "PyUnicodeWriter_Discard(NULL) does nothing" This reverts commit 8b33b0e5fa9dbe5dba3c0d71251efa0e5cd83273. --- Objects/listobject.c | 4 +++- Objects/unicodeobject.c | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index 930aefde325a7c..e7090f20001a39 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -563,7 +563,9 @@ list_repr_impl(PyListObject *v) return PyUnicodeWriter_Finish(writer); error: - PyUnicodeWriter_Discard(writer); + if (writer != NULL) { + PyUnicodeWriter_Discard(writer); + } Py_ReprLeave((PyObject *)v); return NULL; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4cb049d90a0182..bd5bb5048fdacc 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13428,9 +13428,6 @@ PyUnicodeWriter_Create(Py_ssize_t length) void PyUnicodeWriter_Discard(PyUnicodeWriter *writer) { - if (writer == NULL) { - return; - } _PyUnicodeWriter_Dealloc((_PyUnicodeWriter*)writer); PyMem_Free(writer); }