From 5e96bfb4b75e3aa28d84852d4a57a10cefc38e5b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 15 Oct 2024 16:22:07 +0200 Subject: [PATCH] gh-125196: Use PyUnicodeWriter in _io.StringIO --- Modules/_io/stringio.c | 49 ++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index f558613dc6233c..82fe552edc3e16 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -30,7 +30,7 @@ typedef struct { _PyUnicodeWriter is destroyed. */ int state; - _PyUnicodeWriter writer; + PyUnicodeWriter *writer; char ok; /* initialized? */ char closed; @@ -129,14 +129,20 @@ resize_buffer(stringio *self, size_t size) static PyObject * make_intermediate(stringio *self) { - PyObject *intermediate = _PyUnicodeWriter_Finish(&self->writer); + PyObject *intermediate = PyUnicodeWriter_Finish(self->writer); + self->writer = NULL; self->state = STATE_REALIZED; - if (intermediate == NULL) + if (intermediate == NULL) { return NULL; + } + + self->writer = PyUnicodeWriter_Create(0); + if (self->writer == NULL) { + Py_DECREF(intermediate); + return NULL; + } - _PyUnicodeWriter_Init(&self->writer); - self->writer.overallocate = 1; - if (_PyUnicodeWriter_WriteStr(&self->writer, intermediate)) { + if (PyUnicodeWriter_WriteStr(self->writer, intermediate)) { Py_DECREF(intermediate); return NULL; } @@ -147,22 +153,21 @@ make_intermediate(stringio *self) static int realize(stringio *self) { - Py_ssize_t len; - PyObject *intermediate; - if (self->state == STATE_REALIZED) return 0; assert(self->state == STATE_ACCUMULATING); self->state = STATE_REALIZED; - intermediate = _PyUnicodeWriter_Finish(&self->writer); - if (intermediate == NULL) + PyObject *intermediate = PyUnicodeWriter_Finish(self->writer); + self->writer = NULL; + if (intermediate == NULL) { return -1; + } /* Append the intermediate string to the internal buffer. The length should be equal to the current cursor position. */ - len = PyUnicode_GET_LENGTH(intermediate); + Py_ssize_t len = PyUnicode_GET_LENGTH(intermediate); if (resize_buffer(self, len) < 0) { Py_DECREF(intermediate); return -1; @@ -217,8 +222,9 @@ write_str(stringio *self, PyObject *obj) if (self->state == STATE_ACCUMULATING) { if (self->string_size == self->pos) { - if (_PyUnicodeWriter_WriteStr(&self->writer, decoded)) + if (PyUnicodeWriter_WriteStr(self->writer, decoded)) { goto fail; + } goto success; } if (realize(self)) @@ -577,7 +583,8 @@ _io_StringIO_close_impl(stringio *self) /* Free up some memory */ if (resize_buffer(self, 0) < 0) return NULL; - _PyUnicodeWriter_Dealloc(&self->writer); + PyUnicodeWriter_Discard(self->writer); + self->writer = NULL; Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); @@ -615,7 +622,8 @@ stringio_dealloc(stringio *self) PyMem_Free(self->buf); self->buf = NULL; } - _PyUnicodeWriter_Dealloc(&self->writer); + PyUnicodeWriter_Discard(self->writer); + self->writer = NULL; (void)stringio_clear(self); if (self->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); @@ -699,7 +707,8 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, self->ok = 0; - _PyUnicodeWriter_Dealloc(&self->writer); + PyUnicodeWriter_Discard(self->writer); + self->writer = NULL; Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); @@ -754,8 +763,12 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, /* Empty stringio object, we can start by accumulating */ if (resize_buffer(self, 0) < 0) return -1; - _PyUnicodeWriter_Init(&self->writer); - self->writer.overallocate = 1; + + self->writer = PyUnicodeWriter_Create(0); + if (self->writer == NULL) { + return -1; + } + self->state = STATE_ACCUMULATING; } self->pos = 0;