diff -r bfd35f76fd0b Lib/test/test_csv.py --- a/Lib/test/test_csv.py Tue Jan 06 01:22:54 2015 +0100 +++ b/Lib/test/test_csv.py Mon Jan 05 19:38:29 2015 -0800 @@ -1073,6 +1073,18 @@ self.assertEqual(fileobj.read(), expected) +class TestGenerator(unittest.TestCase): + def generator(self): + return (i for i in ['a', 'b', 'c']) + + def test_generator_write(self): + with TemporaryFile('w+', newline='') as fileobj: + writer = csv.writer(fileobj) + writer.writerow(self.generator()) + expected = ','.join(self.generator()) + '\r\n' + fileobj.seek(0) + self.assertEqual(fileobj.read(), expected) + def test_main(): mod = sys.modules[__name__] diff -r bfd35f76fd0b Modules/_csv.c --- a/Modules/_csv.c Tue Jan 06 01:22:54 2015 +0100 +++ b/Modules/_csv.c Mon Jan 05 19:38:29 2015 -0800 @@ -1193,12 +1193,18 @@ Py_ssize_t len, i; PyObject *line, *result; - if (!PySequence_Check(seq)) + if (PySequence_Check(seq)) + Py_INCREF(seq); + else if (PyIter_Check(seq)) + seq = PySequence_List(seq); + else return PyErr_Format(_csvstate_global->error_obj, "sequence expected"); len = PySequence_Length(seq); - if (len < 0) + if (len < 0) { + Py_DECREF(seq); return NULL; + } /* Join all fields in internal buffer. */ @@ -1209,8 +1215,10 @@ int quoted; field = PySequence_GetItem(seq, i); - if (field == NULL) + if (field == NULL) { + Py_DECREF(seq); return NULL; + } switch (dialect->quoting) { case QUOTE_NONNUMERIC: @@ -1237,14 +1245,19 @@ str = PyObject_Str(field); Py_DECREF(field); - if (str == NULL) + if (str == NULL) { + Py_DECREF(seq); return NULL; + } append_ok = join_append(self, str, "ed, len == 1); Py_DECREF(str); } - if (!append_ok) + if (!append_ok) { + Py_DECREF(seq); return NULL; + } } + Py_DECREF(seq); /* Add line terminator. */