Index: Modules/_csv.c =================================================================== --- Modules/_csv.c (revision 70236) +++ Modules/_csv.c (working copy) @@ -749,7 +749,9 @@ Reader_iternext(ReaderObj *self) { PyObject *lineobj; + PyObject *unicodeobj = NULL; PyObject *fields = NULL; + char *bytestr; Py_UNICODE *line, c; Py_ssize_t linelen; @@ -764,9 +766,9 @@ "newline inside string"); return NULL; } - if (!PyUnicode_Check(lineobj)) { + if (!PyUnicode_Check(lineobj) && !PyBytes_Check(lineobj)) { PyErr_Format(error_obj, - "iterator should return strings, " + "iterator should return strings or bytes, " "not %.200s " "(did you open the file in text mode?)", lineobj->ob_type->tp_name @@ -775,8 +777,32 @@ return NULL; } ++self->line_num; - line = PyUnicode_AsUnicode(lineobj); - linelen = PyUnicode_GetSize(lineobj); + if PyUnicode_Check(lineobj) { + line = PyUnicode_AsUnicode(lineobj); + linelen = PyUnicode_GetSize(lineobj); + } + else if PyBytes_Check(lineobj) { + /* the following assumes utf-8 */ + linelen = PyBytes_Size(lineobj); + bytestr = PyBytes_AsString(lineobj); + if (bytestr == NULL) { + Py_DECREF(lineobj); + return NULL; + } + unicodeobj = PyUnicode_FromString(bytestr); + if (unicodeobj == NULL) { + Py_DECREF(lineobj); + return NULL; + } + line = PyUnicode_AsUnicode(unicodeobj); + + /* remove old lineobj and replace with unicodeobj. */ + Py_DECREF(lineobj); + lineobj = NULL; + lineobj = unicodeobj; + unicodeobj = NULL; + } + if (line == NULL || linelen < 0) { Py_DECREF(lineobj); return NULL;