diff -r fc7ceb001eec Objects/dictobject.c --- a/Objects/dictobject.c Mon Nov 18 21:11:57 2013 +0100 +++ b/Objects/dictobject.c Mon Nov 18 22:10:39 2013 +0100 @@ -1397,9 +1397,10 @@ static PyObject * dict_repr(PyDictObject *mp) { Py_ssize_t i; - PyObject *s, *temp, *colon = NULL; - PyObject *pieces = NULL, *result = NULL; + PyObject *colon = NULL, *sep = NULL; PyObject *key, *value; + _PyUnicodeWriter writer; + int first; i = Py_ReprEnter((PyObject *)mp); if (i != 0) { @@ -1407,74 +1408,88 @@ dict_repr(PyDictObject *mp) } if (mp->ma_used == 0) { - result = PyUnicode_FromString("{}"); - goto Done; + Py_ReprLeave((PyObject *)mp); + return PyUnicode_FromString("{}"); } - pieces = PyList_New(0); - if (pieces == NULL) - goto Done; + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + /* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */ + writer.min_length = 1 + 1 + 6 * (mp->ma_used - 1) + 1; colon = PyUnicode_FromString(": "); if (colon == NULL) goto Done; + if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0) + goto Done; + /* Do repr() on each key+value pair, and insert ": " between them. Note that repr may mutate the dict. */ i = 0; + first = 1; while (PyDict_Next((PyObject *)mp, &i, &key, &value)) { - int status; + PyObject *s; + + if (!first) { + if (sep == NULL) { + sep = PyUnicode_FromString(", "); + if (sep == NULL) + goto Done; + } + + if (_PyUnicodeWriter_WriteStr(&writer, sep) < 0) + goto Done; + } + first = 0; + /* Prevent repr from deleting key or value during key format. */ Py_INCREF(key); Py_INCREF(value); + s = PyObject_Repr(key); - PyUnicode_Append(&s, colon); - if (s == NULL) + if (s == NULL || _PyUnicodeWriter_WriteStr(&writer, s) < 0) { + Py_DECREF(key); + Py_DECREF(value); + Py_XDECREF(s); goto Done; - - PyUnicode_AppendAndDel(&s, PyObject_Repr(value)); + } + Py_DECREF(s); + + if (_PyUnicodeWriter_WriteStr(&writer, colon) < 0) { + Py_DECREF(key); + Py_DECREF(value); + goto Done; + } + + s = PyObject_Repr(value); + if (s == NULL || _PyUnicodeWriter_WriteStr(&writer, s) < 0) { + Py_DECREF(key); + Py_DECREF(value); + Py_XDECREF(s); + goto Done; + } + Py_DECREF(s); + Py_DECREF(key); Py_DECREF(value); - if (s == NULL) - goto Done; - status = PyList_Append(pieces, s); - Py_DECREF(s); /* append created a new ref */ - if (status < 0) - goto Done; } - - /* Add "{}" decorations to the first and last items. */ - assert(PyList_GET_SIZE(pieces) > 0); - s = PyUnicode_FromString("{"); - if (s == NULL) + Py_CLEAR(colon); + Py_CLEAR(sep); + + if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0) goto Done; - temp = PyList_GET_ITEM(pieces, 0); - PyUnicode_AppendAndDel(&s, temp); - PyList_SET_ITEM(pieces, 0, s); - if (s == NULL) - goto Done; - - s = PyUnicode_FromString("}"); - if (s == NULL) - goto Done; - temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); - PyUnicode_AppendAndDel(&temp, s); - PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); - if (temp == NULL) - goto Done; - - /* Paste them all together with ", " between. */ - s = PyUnicode_FromString(", "); - if (s == NULL) - goto Done; - result = PyUnicode_Join(s, pieces); - Py_DECREF(s); + + Py_ReprLeave((PyObject *)mp); + + return _PyUnicodeWriter_Finish(&writer); Done: - Py_XDECREF(pieces); + _PyUnicodeWriter_Dealloc(&writer); Py_XDECREF(colon); + Py_XDECREF(sep); Py_ReprLeave((PyObject *)mp); - return result; + return NULL; } static Py_ssize_t diff -r fc7ceb001eec Objects/listobject.c --- a/Objects/listobject.c Mon Nov 18 21:11:57 2013 +0100 +++ b/Objects/listobject.c Mon Nov 18 22:10:39 2013 +0100 @@ -359,14 +359,8 @@ list_repr(PyListObject *v) _PyUnicodeWriter_Init(&writer); writer.overallocate = 1; - if (Py_SIZE(v) > 1) { - /* "[" + "1" + ", 2" * (len - 1) + "]" */ - writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1; - } - else { - /* "[1]" */ - writer.min_length = 3; - } + /* "[" + "1" + ", 2" * (len - 1) + "]" */ + writer.min_length = 1 + 1 + (2 + 1) * (Py_SIZE(v) - 1) + 1; if (_PyUnicodeWriter_WriteChar(&writer, '[') < 0) goto error;