mirror of https://github.com/python/cpython
Issue #19646: repr(dict) now uses _PyUnicodeWriter API for better performances
This commit is contained in:
parent
88a9cd9b57
commit
f91929b1d8
|
@ -1397,9 +1397,9 @@ static PyObject *
|
|||
dict_repr(PyDictObject *mp)
|
||||
{
|
||||
Py_ssize_t i;
|
||||
PyObject *s, *temp, *colon = NULL;
|
||||
PyObject *pieces = NULL, *result = NULL;
|
||||
PyObject *key, *value;
|
||||
PyObject *key = NULL, *value = NULL;
|
||||
_PyUnicodeWriter writer;
|
||||
int first;
|
||||
|
||||
i = Py_ReprEnter((PyObject *)mp);
|
||||
if (i != 0) {
|
||||
|
@ -1407,74 +1407,73 @@ 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 + 4 + (2 + 4) * (mp->ma_used - 1) + 1;
|
||||
|
||||
colon = PyUnicode_FromString(": ");
|
||||
if (colon == NULL)
|
||||
goto Done;
|
||||
if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0)
|
||||
goto error;
|
||||
|
||||
/* 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;
|
||||
int res;
|
||||
|
||||
/* 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)
|
||||
goto Done;
|
||||
|
||||
PyUnicode_AppendAndDel(&s, PyObject_Repr(value));
|
||||
Py_DECREF(key);
|
||||
Py_DECREF(value);
|
||||
if (!first) {
|
||||
if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
|
||||
goto error;
|
||||
}
|
||||
first = 0;
|
||||
|
||||
s = PyObject_Repr(key);
|
||||
if (s == NULL)
|
||||
goto Done;
|
||||
status = PyList_Append(pieces, s);
|
||||
Py_DECREF(s); /* append created a new ref */
|
||||
if (status < 0)
|
||||
goto Done;
|
||||
goto error;
|
||||
res = _PyUnicodeWriter_WriteStr(&writer, s);
|
||||
Py_DECREF(s);
|
||||
if (res < 0)
|
||||
goto error;
|
||||
|
||||
if (_PyUnicodeWriter_WriteASCIIString(&writer, ": ", 2) < 0)
|
||||
goto error;
|
||||
|
||||
s = PyObject_Repr(value);
|
||||
if (s == NULL)
|
||||
goto error;
|
||||
res = _PyUnicodeWriter_WriteStr(&writer, s);
|
||||
Py_DECREF(s);
|
||||
if (res < 0)
|
||||
goto error;
|
||||
|
||||
Py_CLEAR(key);
|
||||
Py_CLEAR(value);
|
||||
}
|
||||
|
||||
/* Add "{}" decorations to the first and last items. */
|
||||
assert(PyList_GET_SIZE(pieces) > 0);
|
||||
s = PyUnicode_FromString("{");
|
||||
if (s == NULL)
|
||||
goto Done;
|
||||
temp = PyList_GET_ITEM(pieces, 0);
|
||||
PyUnicode_AppendAndDel(&s, temp);
|
||||
PyList_SET_ITEM(pieces, 0, s);
|
||||
if (s == NULL)
|
||||
goto Done;
|
||||
writer.overallocate = 0;
|
||||
if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0)
|
||||
goto error;
|
||||
|
||||
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);
|
||||
|
||||
Done:
|
||||
Py_XDECREF(pieces);
|
||||
Py_XDECREF(colon);
|
||||
Py_ReprLeave((PyObject *)mp);
|
||||
return result;
|
||||
|
||||
return _PyUnicodeWriter_Finish(&writer);
|
||||
|
||||
error:
|
||||
Py_ReprLeave((PyObject *)mp);
|
||||
_PyUnicodeWriter_Dealloc(&writer);
|
||||
Py_XDECREF(key);
|
||||
Py_XDECREF(value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Py_ssize_t
|
||||
|
|
Loading…
Reference in New Issue