]> granicus.if.org Git - python/commitdiff
SF patch #907403: Improvements to cStringIO.writelines()
authorRaymond Hettinger <python@rcn.com>
Mon, 8 Mar 2004 18:17:31 +0000 (18:17 +0000)
committerRaymond Hettinger <python@rcn.com>
Mon, 8 Mar 2004 18:17:31 +0000 (18:17 +0000)
The writelines() method now accepts any iterable argument and writes
the lines one at a time rather than using ''.join(lines) followed by
a single write.  Results in considerable memory savings and makes
the method suitable for use with generator expressions.

Lib/StringIO.py
Modules/cStringIO.c

index f35054e80060973af9269b5e79a1ef5472ef8763..9b79a88f0b9736353dcc0caf6153532388cd7715 100644 (file)
@@ -178,8 +178,10 @@ class StringIO:
             self.len = newpos
         self.pos = newpos
 
-    def writelines(self, list):
-        self.write(''.join(list))
+    def writelines(self, iterable):
+        write = self.write
+        for line in iterable:
+            write(line)
 
     def flush(self):
         _complain_ifclosed(self.closed)
index 4ec5e88c88046031da4f435389b358944780dcd8..1420bcebb9cb1e75046ab8867b640dc63333cced 100644 (file)
@@ -416,40 +416,35 @@ O_close(Oobject *self, PyObject *unused) {
         return Py_None;
 }
 
-
 PyDoc_STRVAR(O_writelines__doc__,
-"writelines(sequence_of_strings): write each string");
+"writelines(sequence_of_strings) -> None.  Write the strings to the file.\n"
+"\n"
+"Note that newlines are not added.  The sequence can be any iterable object\n"
+"producing strings. This is equivalent to calling write() for each string.");
 static PyObject *
 O_writelines(Oobject *self, PyObject *args) {
-        PyObject *tmp = 0;
-       static PyObject *joiner = NULL;
-
-       if (!joiner) {
-               PyObject *empty_string = PyString_FromString("");
-               if (empty_string == NULL)
+       PyObject *it, *s;
+       
+       it = PyObject_GetIter(args);
+       if (it == NULL)
+               return NULL;
+       while ((s = PyIter_Next(it)) != NULL) {
+               int n;
+               char *c;
+               if (PyString_AsStringAndSize(s, &c, &n) == -1) {
+                       Py_DECREF(it);
+                       Py_DECREF(s);
                        return NULL;
-               joiner = PyObject_GetAttrString(empty_string, "join");
-               Py_DECREF(empty_string);
-               if (joiner == NULL)
+               }
+               if (O_cwrite((PyObject *)self, c, n) == -1) {
+                       Py_DECREF(it);
+                       Py_DECREF(s);
                        return NULL;
+               }
+               Py_DECREF(s);
        }
-
-        if (PyObject_Size(args) < 0) return NULL;
-
-       args = PyTuple_Pack(1, args);
-       if (args == NULL)
-               return NULL;
-       tmp = PyObject_Call(joiner, args, NULL);
-       Py_DECREF(args);
-        UNLESS (tmp) return NULL;
-
-        args = PyTuple_Pack(1, tmp);
-        Py_DECREF(tmp);
-        UNLESS (args) return NULL;
-
-        tmp = O_write(self, args);
-        Py_DECREF(args);
-        return tmp;
+       Py_DECREF(it);
+       Py_RETURN_NONE;
 }
 
 static struct PyMethodDef O_methods[] = {