[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.103,2.104 listobject.c,2.95,2.96 stringobject.c,2.118,2.119 tupleobject.c,2.52,2.53
Tim Peters
tim_one@users.sourceforge.net
Fri, 15 Jun 2001 22:11:20 -0700
Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv12913/python/dist/src/Objects
Modified Files:
dictobject.c listobject.c stringobject.c tupleobject.c
Log Message:
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.
Index: dictobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.103
retrieving revision 2.104
diff -C2 -r2.103 -r2.104
*** dictobject.c 2001/06/04 21:00:21 2.103
--- dictobject.c 2001/06/16 05:11:17 2.104
***************
*** 810,849 ****
dict_repr(dictobject *mp)
{
! auto PyObject *v;
! PyObject *sepa, *colon;
! register int i;
! register int any;
! i = Py_ReprEnter((PyObject*)mp);
if (i != 0) {
! if (i > 0)
! return PyString_FromString("{...}");
! return NULL;
}
! v = PyString_FromString("{");
! sepa = PyString_FromString(", ");
colon = PyString_FromString(": ");
! any = 0;
! for (i = 0; i <= mp->ma_mask && v; i++) {
! dictentry *ep = mp->ma_table + i;
! PyObject *pvalue = ep->me_value;
! if (pvalue != NULL) {
! /* Prevent PyObject_Repr from deleting value during
! key format */
! Py_INCREF(pvalue);
! if (any++)
! PyString_Concat(&v, sepa);
! PyString_ConcatAndDel(&v, PyObject_Repr(ep->me_key));
! PyString_Concat(&v, colon);
! PyString_ConcatAndDel(&v, PyObject_Repr(pvalue));
! Py_DECREF(pvalue);
! }
}
! PyString_ConcatAndDel(&v, PyString_FromString("}"));
! Py_ReprLeave((PyObject*)mp);
! Py_XDECREF(sepa);
Py_XDECREF(colon);
! return v;
}
--- 810,887 ----
dict_repr(dictobject *mp)
{
! int i, pos;
! PyObject *s, *temp, *colon = NULL;
! PyObject *pieces = NULL, *result = NULL;
! PyObject *key, *value;
! i = Py_ReprEnter((PyObject *)mp);
if (i != 0) {
! return i > 0 ? PyString_FromString("{...}") : NULL;
}
! if (mp->ma_used == 0) {
! result = PyString_FromString("{}");
! goto Done;
! }
!
! pieces = PyList_New(0);
! if (pieces == NULL)
! goto Done;
!
colon = PyString_FromString(": ");
! if (colon == NULL)
! goto Done;
!
! /* Do repr() on each key+value pair, and insert ": " between them.
! Note that repr may mutate the dict. */
! pos = 0;
! while (PyDict_Next((PyObject *)mp, &pos, &key, &value)) {
! int status;
! /* Prevent repr from deleting value during key format. */
! Py_INCREF(value);
! s = PyObject_Repr(key);
! PyString_Concat(&s, colon);
! PyString_ConcatAndDel(&s, PyObject_Repr(value));
! 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 = 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_XDECREF(colon);
! Py_ReprLeave((PyObject *)mp);
! return result;
}
Index: listobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v
retrieving revision 2.95
retrieving revision 2.96
diff -C2 -r2.95 -r2.96
*** listobject.c 2001/05/26 19:37:54 2.95
--- listobject.c 2001/06/16 05:11:17 2.96
***************
*** 247,270 ****
list_repr(PyListObject *v)
{
- PyObject *s, *comma;
int i;
i = Py_ReprEnter((PyObject*)v);
if (i != 0) {
! if (i > 0)
! return PyString_FromString("[...]");
! return 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]));
}
! Py_XDECREF(comma);
! PyString_ConcatAndDel(&s, PyString_FromString("]"));
Py_ReprLeave((PyObject *)v);
! return s;
}
--- 247,312 ----
list_repr(PyListObject *v)
{
int i;
+ PyObject *s, *temp;
+ PyObject *pieces = NULL, *result = NULL;
i = Py_ReprEnter((PyObject*)v);
if (i != 0) {
! return i > 0 ? PyString_FromString("[...]") : NULL;
}
!
! if (v->ob_size == 0) {
! result = PyString_FromString("[]");
! goto Done;
! }
!
! 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 result;
}
Index: stringobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v
retrieving revision 2.118
retrieving revision 2.119
diff -C2 -r2.118 -r2.119
*** stringobject.c 2001/06/12 13:14:10 2.118
--- stringobject.c 2001/06/16 05:11:17 2.119
***************
*** 1032,1035 ****
--- 1032,1052 ----
}
+ PyObject *_PyString_Join(PyObject *sep, PyObject *x)
+ {
+ PyObject* args;
+ PyObject* result = NULL;
+
+ assert(sep != NULL && PyString_Check(sep));
+ assert(x != NULL);
+ args = PyTuple_New(1);
+ if (args != NULL) {
+ Py_INCREF(x);
+ PyTuple_SET_ITEM(args, 0, x);
+ result = string_join((PyStringObject *)sep, args);
+ Py_DECREF(args);
+ }
+ return result;
+ }
+
static long
string_find_internal(PyStringObject *self, PyObject *args, int dir)
Index: tupleobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v
retrieving revision 2.52
retrieving revision 2.53
diff -C2 -r2.52 -r2.53
*** tupleobject.c 2001/05/29 07:58:45 2.52
--- tupleobject.c 2001/06/16 05:11:17 2.53
***************
*** 185,202 ****
tuplerepr(PyTupleObject *v)
{
! PyObject *s, *comma;
! int i;
! 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]));
}
! Py_DECREF(comma);
! if (v->ob_size == 1)
! PyString_ConcatAndDel(&s, PyString_FromString(","));
! PyString_ConcatAndDel(&s, PyString_FromString(")"));
! return s;
}
--- 185,238 ----
tuplerepr(PyTupleObject *v)
{
! int i, n;
! PyObject *s, *temp;
! PyObject *pieces, *result = NULL;
!
! n = v->ob_size;
! if (n == 0)
! return PyString_FromString("()");
!
! pieces = PyTuple_New(n);
! if (pieces == NULL)
! return NULL;
!
! /* Do repr() on each element. */
! for (i = 0; i < n; ++i) {
! s = PyObject_Repr(v->ob_item[i]);
! if (s == NULL)
! goto Done;
! PyTuple_SET_ITEM(pieces, i, s);
}
!
! /* Add "()" decorations to the first and last items. */
! assert(n > 0);
! s = PyString_FromString("(");
! if (s == NULL)
! goto Done;
! temp = PyTuple_GET_ITEM(pieces, 0);
! PyString_ConcatAndDel(&s, temp);
! PyTuple_SET_ITEM(pieces, 0, s);
! if (s == NULL)
! goto Done;
!
! s = PyString_FromString(n == 1 ? ",)" : ")");
! if (s == NULL)
! goto Done;
! temp = PyTuple_GET_ITEM(pieces, n-1);
! PyString_ConcatAndDel(&temp, s);
! PyTuple_SET_ITEM(pieces, n-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_DECREF(pieces);
! return result;
}