summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Hettinger <python@rcn.com>2004-03-08 18:17:31 (GMT)
committerRaymond Hettinger <python@rcn.com>2004-03-08 18:17:31 (GMT)
commit6ec099658ab49ed6d3c2861e437fe659e1c7037f (patch)
tree2a8f9f3e3192bba966382e4a473092d1f376f3f6
parent73360a3e61274ffcc4c9fc3d09746bd6603e92a5 (diff)
downloadcpython-6ec099658ab49ed6d3c2861e437fe659e1c7037f.zip
cpython-6ec099658ab49ed6d3c2861e437fe659e1c7037f.tar.gz
cpython-6ec099658ab49ed6d3c2861e437fe659e1c7037f.tar.bz2
SF patch #907403: Improvements to cStringIO.writelines()
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.
-rw-r--r--Lib/StringIO.py6
-rw-r--r--Modules/cStringIO.c51
2 files changed, 27 insertions, 30 deletions
diff --git a/Lib/StringIO.py b/Lib/StringIO.py
index f35054e..9b79a88 100644
--- a/Lib/StringIO.py
+++ b/Lib/StringIO.py
@@ -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)
diff --git a/Modules/cStringIO.c b/Modules/cStringIO.c
index 4ec5e88..1420bce 100644
--- a/Modules/cStringIO.c
+++ b/Modules/cStringIO.c
@@ -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[] = {