Python 2 CSV writer produces wrong line terminator on Windows

According to the its documentation csv.writer should use ‘rn’ as lineterminator by default.

import csv

with open("test.csv", "w") as f:
    writer = csv.writer(f)

    rows = [(0,1,2,3,4),
           (-0,-1,-2,-3,-4),
           ("a","b","c","d","e"),
           ("A","B","C","D","E")]           

    print writer.dialect.lineterminator.replace("r", "\r").replace("n", "\n")
    writer.writerows(rows)
    print writer.dialect.lineterminator.replace("r", "\r").replace("n", "\n")

This prints

rn
rn

as expected. But, the created csv-file uses the lineterminator ‘rrn’

0,1,2,3,4

0,-1,-2,-3,-4

a,b,c,d,e

A,B,C,D,E

Is this a bug or is there something wrong in my usage of csv.writer?

Python version:

ActivePython 2.6.2.2 (ActiveState
Software Inc.) based on Python 2.6.2
(r262:71600, Apr 21 2009, 15:05:37)
[MSC v.1500 32 bit (Intel)] on win32

on Windows Vista

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

In Python 2.x, always open your file in binary mode, as documented. csv writes rn as you expected, but then the underlying Windows text file mechanism cuts in and changes that n to rn … total effect: rrn

From the csv.writer documentation:

If csvfile is a file object, it must be opened with the 'b' flag on platforms where that makes a difference.

There seems to be some reticence about actually uttering the name of the main culprit 🙂

Edit: As mentioned by @jebob in the comments to this answer and based on @Dave Burton’s answer, to handle this case in both Python 2 and 3, you should do the following:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')

Method 2

Unfortunately, it’s a bit different with the csv module for Python 3, but this code will work on both Python 2 and Python 3:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')

Method 3

To change the line terminator in Python 2.7 csv writer use

writer = csv.writer(f, delimiter = '|', lineterminator='n')

This is a much simpler way to change the default delimiter from rn.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x