summaryrefslogtreecommitdiff
path: root/Objects/listobject.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-06-16 05:11:17 +0000
committerTim Peters <tim.peters@gmail.com>2001-06-16 05:11:17 +0000
commita7259597f1f9ef389012010d7b8a02ebcf7396e7 (patch)
tree7ada9cc6a3f30bc41999ba56da018ccd55342df8 /Objects/listobject.c
parent239508cd1087a521ebe40fabc96c66dcb11c3f8c (diff)
downloadcpython-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.c68
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