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)
|
dict_repr(PyDictObject *mp)
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject *s, *temp, *colon = NULL;
|
PyObject *key = NULL, *value = NULL;
|
||||||
PyObject *pieces = NULL, *result = NULL;
|
_PyUnicodeWriter writer;
|
||||||
PyObject *key, *value;
|
int first;
|
||||||
|
|
||||||
i = Py_ReprEnter((PyObject *)mp);
|
i = Py_ReprEnter((PyObject *)mp);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
@ -1407,74 +1407,73 @@ dict_repr(PyDictObject *mp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mp->ma_used == 0) {
|
if (mp->ma_used == 0) {
|
||||||
result = PyUnicode_FromString("{}");
|
Py_ReprLeave((PyObject *)mp);
|
||||||
goto Done;
|
return PyUnicode_FromString("{}");
|
||||||
}
|
}
|
||||||
|
|
||||||
pieces = PyList_New(0);
|
_PyUnicodeWriter_Init(&writer);
|
||||||
if (pieces == NULL)
|
writer.overallocate = 1;
|
||||||
goto Done;
|
/* "{" + "1: 2" + ", 3: 4" * (len - 1) + "}" */
|
||||||
|
writer.min_length = 1 + 4 + (2 + 4) * (mp->ma_used - 1) + 1;
|
||||||
|
|
||||||
colon = PyUnicode_FromString(": ");
|
if (_PyUnicodeWriter_WriteChar(&writer, '{') < 0)
|
||||||
if (colon == NULL)
|
goto error;
|
||||||
goto Done;
|
|
||||||
|
|
||||||
/* Do repr() on each key+value pair, and insert ": " between them.
|
/* Do repr() on each key+value pair, and insert ": " between them.
|
||||||
Note that repr may mutate the dict. */
|
Note that repr may mutate the dict. */
|
||||||
i = 0;
|
i = 0;
|
||||||
|
first = 1;
|
||||||
while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
|
while (PyDict_Next((PyObject *)mp, &i, &key, &value)) {
|
||||||
int status;
|
PyObject *s;
|
||||||
|
int res;
|
||||||
|
|
||||||
/* Prevent repr from deleting key or value during key format. */
|
/* Prevent repr from deleting key or value during key format. */
|
||||||
Py_INCREF(key);
|
Py_INCREF(key);
|
||||||
Py_INCREF(value);
|
Py_INCREF(value);
|
||||||
s = PyObject_Repr(key);
|
|
||||||
PyUnicode_Append(&s, colon);
|
|
||||||
if (s == NULL)
|
|
||||||
goto Done;
|
|
||||||
|
|
||||||
PyUnicode_AppendAndDel(&s, PyObject_Repr(value));
|
if (!first) {
|
||||||
Py_DECREF(key);
|
if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
|
||||||
Py_DECREF(value);
|
goto error;
|
||||||
|
}
|
||||||
|
first = 0;
|
||||||
|
|
||||||
|
s = PyObject_Repr(key);
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
goto Done;
|
goto error;
|
||||||
status = PyList_Append(pieces, s);
|
res = _PyUnicodeWriter_WriteStr(&writer, s);
|
||||||
Py_DECREF(s); /* append created a new ref */
|
Py_DECREF(s);
|
||||||
if (status < 0)
|
if (res < 0)
|
||||||
goto Done;
|
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. */
|
writer.overallocate = 0;
|
||||||
assert(PyList_GET_SIZE(pieces) > 0);
|
if (_PyUnicodeWriter_WriteChar(&writer, '}') < 0)
|
||||||
s = PyUnicode_FromString("{");
|
goto error;
|
||||||
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;
|
|
||||||
|
|
||||||
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);
|
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
|
static Py_ssize_t
|
||||||
|
Loading…
x
Reference in New Issue
Block a user