diff options
author | Tim Peters <tim.peters@gmail.com> | 2001-06-16 05:11:17 +0000 |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2001-06-16 05:11:17 +0000 |
commit | a7259597f1f9ef389012010d7b8a02ebcf7396e7 (patch) | |
tree | 7ada9cc6a3f30bc41999ba56da018ccd55342df8 /Objects/listobject.c | |
parent | 239508cd1087a521ebe40fabc96c66dcb11c3f8c (diff) | |
download | cpython-git-a7259597f1f9ef389012010d7b8a02ebcf7396e7.tar.gz |
SF bug 433228: repr(list) woes when len(list) big.
Gave Python linear-time repr() implementations for dicts, lists, strings.
This means, e.g., that repr(range(50000)) is no longer 50x slower than
pprint.pprint() in 2.2 <wink>.
I don't consider this a bugfix candidate, as it's a performance boost.
Added _PyString_Join() to the internal string API. If we want that in the
public API, fine, but then it requires runtime error checks instead of
asserts.
Diffstat (limited to 'Objects/listobject.c')
-rw-r--r-- | Objects/listobject.c | 68 |
1 files changed, 55 insertions, 13 deletions
diff --git a/Objects/listobject.c b/Objects/listobject.c index e595c85082..6fb3145d36 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -246,26 +246,68 @@ list_print(PyListObject *op, FILE *fp, int flags) static PyObject * list_repr(PyListObject *v) { - PyObject *s, *comma; int i; + PyObject *s, *temp; + PyObject *pieces = NULL, *result = NULL; i = Py_ReprEnter((PyObject*)v); if (i != 0) { - if (i > 0) - return PyString_FromString("[...]"); - return NULL; + return i > 0 ? PyString_FromString("[...]") : NULL; } - s = PyString_FromString("["); - comma = PyString_FromString(", "); - for (i = 0; i < v->ob_size && s != NULL; i++) { - if (i > 0) - PyString_Concat(&s, comma); - PyString_ConcatAndDel(&s, PyObject_Repr(v->ob_item[i])); + + if (v->ob_size == 0) { + result = PyString_FromString("[]"); + goto Done; } - Py_XDECREF(comma); - PyString_ConcatAndDel(&s, PyString_FromString("]")); + + pieces = PyList_New(0); + if (pieces == NULL) + goto Done; + + /* 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 < v->ob_size; ++i) { + int status; + s = PyObject_Repr(v->ob_item[i]); + 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 = PyString_FromString("["); + if (s == NULL) + goto Done; + temp = PyList_GET_ITEM(pieces, 0); + PyString_ConcatAndDel(&s, temp); + PyList_SET_ITEM(pieces, 0, s); + if (s == NULL) + goto Done; + + s = PyString_FromString("]"); + if (s == NULL) + goto Done; + temp = PyList_GET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1); + PyString_ConcatAndDel(&temp, s); + PyList_SET_ITEM(pieces, PyList_GET_SIZE(pieces) - 1, temp); + if (temp == NULL) + goto Done; + + /* Paste them all together with ", " between. */ + s = PyString_FromString(", "); + if (s == NULL) + goto Done; + result = _PyString_Join(s, pieces); + Py_DECREF(s); + +Done: + Py_XDECREF(pieces); Py_ReprLeave((PyObject *)v); - return s; + return result; } static int |