Writing to io.BytesIO in csv fails in python3

I am trying to write python 2/3 compatible code to write strings to a CSV file object. This code:

line_as_list = [line.encode() for line in line_as_list] writer_file = io.BytesIO() writer = csv.writer(writer_file, dialect=dialect, delimiter=self.delimiter) for line in line_as_list: assert isinstance(line,bytes) writer.writerow(line) 

Gives this error for Python3:

 > writer.writerow(line) E TypeError: a bytes-like object is required, not 'str' 

But assert has no type problems, so why does csv create an error?

Can't I use BytesIO only for Python 2 and 3? Where is the problem here?

+8
python string csv bytesio
source share
1 answer

In Python3, csv.writer expects a file-like object to be opened in text mode. In Python2, csv.writer expects a file-like object to be opened in binary mode.

So in Python3, use io.StringIO , and in Python2 use io.BytesIO :

 import io import csv import sys PY3 = sys.version_info[0] == 3 line_as_list = [u'foo', u'bar'] encoding = 'utf-8' if PY3: writer_file = io.StringIO() else: writer_file = io.BytesIO() line_as_list = [line.encode(encoding) for line in line_as_list] writer = csv.writer(writer_file, dialect='excel', delimiter=',') writer.writerow(line_as_list) content = writer_file.getvalue() if PY3: content = content.encode(encoding) print(type(content)) print(repr(content)) 

In Python3, the above print code

 <class 'bytes'> b'foo,bar\r\n' 

In Python2, the above code prints

 <type 'str'> 'foo,bar\r\n' 
+8
source share

All Articles