]> granicus.if.org Git - python/commitdiff
two changes to string_join:
authorJeremy Hylton <jeremy@alum.mit.edu>
Mon, 10 Jul 2000 21:30:28 +0000 (21:30 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Mon, 10 Jul 2000 21:30:28 +0000 (21:30 +0000)
implementation -- use PySequence_Fast interface to iterate over elements
interface -- if instance object reports wrong length, ignore it;
   previous version raised an IndexError if reported length was too high

Objects/stringobject.c

index 9677d4bd250656caa54d6ba3b47eb0c696edf0d5..fd0a570c5f2f8c78b171d1f6628b5e2de466905b 100644 (file)
@@ -744,106 +744,66 @@ string_join(PyStringObject *self, PyObject *args)
        int seqlen = 0;
        int sz = 100;
        int i, slen;
-       PyObject *seq;
+       PyObject *orig, *seq, *item;
 
-       if (!PyArg_ParseTuple(args, "O:join", &seq))
+       if (!PyArg_ParseTuple(args, "O:join", &orig))
                return NULL;
 
-       seqlen = PySequence_Length(seq);
-       if (seqlen < 0 && PyErr_Occurred())
+       seq = PySequence_Fast(orig, "");
+       if (seq == NULL) {
+               if (PyErr_ExceptionMatches(PyExc_TypeError))
+                       PyErr_Format(PyExc_TypeError,
+                                    "sequence expected, %.80s found",
+                                    orig->ob_type->tp_name);
                return NULL;
+       }
 
+       seqlen = PySequence_Length(seq);
        if (seqlen == 1) {
-               /* Optimization if there's only one item */
-               PyObject *item = PySequence_GetItem(seq, 0);
-               if (item == NULL)
-                   return NULL;
-               if (!PyString_Check(item) && 
-                   !PyUnicode_Check(item)) {
-                       PyErr_SetString(PyExc_TypeError,
-                             "first argument must be sequence of strings");
-                       Py_DECREF(item);
-                       return NULL;
-               }
+               item = PySequence_Fast_GET_ITEM(seq, 0);
+               Py_INCREF(item);
                return item;
        }
+
        if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
                return NULL;
        p = PyString_AsString(res);
 
-       /* optimize for lists.  all others (tuples and arbitrary sequences)
-        * just use the abstract interface.
-        */
-       if (PyList_Check(seq)) {
-               for (i = 0; i < seqlen; i++) {
-                       PyObject *item = PyList_GET_ITEM(seq, i);
-                       if (!PyString_Check(item)){
-                               if (PyUnicode_Check(item)) {
-                                       Py_DECREF(res);
-                                       return PyUnicode_Join(
-                                                        (PyObject *)self, 
-                                                        seq);
-                               }
-                               PyErr_Format(PyExc_TypeError,
-                                            "sequence item %i not a string",
-                                            i);
-                               goto finally;
-                       }
-                       slen = PyString_GET_SIZE(item);
-                       while (reslen + slen + seplen >= sz) {
-                               if (_PyString_Resize(&res, sz*2))
-                                       goto finally;
-                               sz *= 2;
-                               p = PyString_AsString(res) + reslen;
-                       }
-                       if (i > 0) {
-                               memcpy(p, sep, seplen);
-                               p += seplen;
-                               reslen += seplen;
+       for (i = 0; i < seqlen; i++) {
+               item = PySequence_Fast_GET_ITEM(seq, i);
+               if (!PyString_Check(item)){
+                       if (PyUnicode_Check(item)) {
+                               Py_DECREF(res);
+                               Py_DECREF(item);
+                               return PyUnicode_Join((PyObject *)self, 
+                                                     seq);
                        }
-                       memcpy(p, PyString_AS_STRING(item), slen);
-                       p += slen;
-                       reslen += slen;
+                       PyErr_Format(PyExc_TypeError,
+                            "sequence item %i: expected string, %.80s found",
+                                    i, item->ob_type->tp_name);
+                       Py_DECREF(item);
+                       Py_DECREF(seq);
+                       goto finally;
                }
-       }
-       else {
-               for (i = 0; i < seqlen; i++) {
-                       PyObject *item = PySequence_GetItem(seq, i);
-                       if (!item)
-                               goto finally;
-                       if (!PyString_Check(item)){
-                               if (PyUnicode_Check(item)) {
-                                       Py_DECREF(res);
-                                       Py_DECREF(item);
-                                       return PyUnicode_Join(
-                                                        (PyObject *)self, 
-                                                        seq);
-                               }
+               slen = PyString_GET_SIZE(item);
+               while (reslen + slen + seplen >= sz) {
+                       if (_PyString_Resize(&res, sz*2)) {
                                Py_DECREF(item);
-                               PyErr_Format(PyExc_TypeError,
-                                            "sequence item %i not a string",
-                                            i);
+                               Py_DECREF(seq);
                                goto finally;
                        }
-                       slen = PyString_GET_SIZE(item);
-                       while (reslen + slen + seplen >= sz) {
-                               if (_PyString_Resize(&res, sz*2)) {
-                                       Py_DECREF(item);
-                                       goto finally;
-                               }
-                               sz *= 2;
-                               p = PyString_AsString(res) + reslen;
-                       }
-                       if (i > 0) {
-                               memcpy(p, sep, seplen);
-                               p += seplen;
-                               reslen += seplen;
-                       }
-                       memcpy(p, PyString_AS_STRING(item), slen);
-                       Py_DECREF(item);
-                       p += slen;
-                       reslen += slen;
+                       sz *= 2;
+                       p = PyString_AsString(res) + reslen;
+               }
+               if (i > 0) {
+                       memcpy(p, sep, seplen);
+                       p += seplen;
+                       reslen += seplen;
                }
+               memcpy(p, PyString_AS_STRING(item), slen);
+               Py_DECREF(item);
+               p += slen;
+               reslen += slen;
        }
        if (_PyString_Resize(&res, reslen))
                goto finally;