Handling \r\n vs \n newlines in python on Mac vs Windows

89,264

Solution 1

'U' mode:

Python 2:

I guess it may depend on what you're reading from, but the built-in open() function takes a 'mode' parameter, and if you pass 'U' for the mode, Python 2 will take care of the newlines in a cross-platform way transparently. It requires that Python be built with universal newline support, but test it out!

https://docs.python.org/2/library/functions.html#open

Python 3:

In Python 3, the 'U' mode is the default behaviour, as the docs explain:

There is an additional mode character permitted, 'U', which no longer has any effect, and is considered deprecated. It previously enabled universal newlines in text mode, which became the default behaviour in Python 3.0. Refer to the documentation of the newline parameter for further details.

https://docs.python.org/3/library/functions.html#open

Solution 2

Different platforms have different codes for "new line". Windows have \r\n, Unix has \n, Old macs have \r and yes there are some systems that have \n\r too.

When you open a file in text mode in Python 3, it will convert all newlines to '\n' and be done with it.

infile = open("filename", 'r')

Text mode is default, so if you say nothing, it's text mode. But it's always better to be explicit:

infile = open("filename", 'rt')

If you don't want the translation of line endings to happen, open the file in binary mode:

infile = open("filename", 'rb')

In Python 2 it's different. There this conversion would only happen by default on Windows. If you wanted it to happen on other platforms, you could add the universal newline flag:

infile = open("filename", 'rU')

However, you say that you are on Python 3, and there it happens in text mode on all platforms, so adding the U flag should make no difference.

Solution 3

In Python 3, the Open() method has a newline parameter:

newline controls how universal newlines mode works (it only applies to text mode). It can be None, '', '\n', '\r', and '\r\n'. It works as follows:

When reading input from the stream, if newline is None, universal newlines mode is enabled. Lines in the input can end in '\n', '\r', or '\r\n', and these are translated into '\n' before being returned to the caller. If it is '', universal newlines mode is enabled, but line endings are returned to the caller untranslated. If it has any of the other legal values, input lines are only terminated by the given string, and the line ending is returned to the caller untranslated.

When writing output to the stream, if newline is None, any '\n' characters written are translated to the system default line separator, os.linesep. If newline is '' or '\n', no translation takes place. If newline is any of the other legal values, any '\n' characters written are translated to the given string.

The old way of using U mode specifier has been deprecated in favor of this new way.

'U' universal newlines mode (deprecated)

Solution 4

In Python 3, use the keyword argument "newline='\n'" in open() to use a specified line delimiter when writing text files. For more information, please see:

https://pythonconquerstheuniverse.wordpress.com/2011/05/08/newline-conversion-in-python-3/

http://docs.python.org/3/library/functions.html#open

Solution 5

On windows, they both are working fine if i try writing a file with either of the two(\r or \n) python interprets it as a line break in both the cases. While using "\r\n", it is interpreted as a double line break.(Python 3 on windows)

Share:
89,264
wrongusername
Author by

wrongusername

Updated on December 05, 2020

Comments

  • wrongusername
    wrongusername over 3 years

    I have a python script that gave different output when run on a Windows machine and when run on a Mac. On digging deeper, I discovered that it was because when Python read in line breaks on the Mac (from a file), it read in \r\n, while somehow in Windows the \r disappears.

    Thus, if I change every \n in the script to \r\n, it works fine on the Mac. But if I do that, it stops working on the Windows PC.

    Is there an easy way to fix this problem?

  • Falmarri
    Falmarri over 13 years
    This is also the default (as far as I know)
  • wrongusername
    wrongusername over 13 years
    Thanks! It works fine now! Oh and @Falmarri sorry, the only way I knew of how to read from a file was with 'r'. At least now I know better.
  • Falmarri
    Falmarri over 13 years
    Hmm, it sounds like that's not the default in python 3. That seems weird.
  • Lennart Regebro
    Lennart Regebro over 13 years
    @Falmarri: It is default in Python 3, and in fact, the U flag is deprecated in Python 3.
  • wrongusername
    wrongusername over 13 years
    @Lennart that's interesting... wonder how my mac screwed it up
  • Lennart Regebro
    Lennart Regebro over 13 years
    @wrongusername: Good question. It sounds like you are using Python 2, to be honest.
  • wrongusername
    wrongusername over 13 years
    @Lennart Heh it does sort of sound like it, but I am using format s on strings and prints with parentheses, so it's definitely Python 3
  • Lennart Regebro
    Lennart Regebro over 13 years
    @wrongusername: No, that works fine under Python 2.6 as well. You'll see the Python version when you start the python interpreter.
  • wrongusername
    wrongusername over 13 years
    @Lennart really? I thought string.format stuff were exclusive to python 3 (stackoverflow.com/questions/2450188/string-formatting-error‌​) and get syntax errors when I use print as a keyword? anyways, when I start up the python shell I get "Python 3.1.3 (r313:86882M, Nov 30 2010, 09:55:56) [GCC 4.0.1 (Apple Inc. build 5494)] on darwin"
  • Lennart Regebro
    Lennart Regebro over 13 years
    @wrongusername: Yes, you get errors when you use print as a keyword in Python 3. But you do not get errors because you stick two parenthesis around an expression in Python 2. Hence print(foo) works just fine in Python 2 and has always done. The \r should disappear on OS X as well, unless you open the file in binary mode.
  • sinekonata
    sinekonata over 11 years
    Thank you so much I had an idea it was like that, it took me a pretty long time to confirm it, but yeah my code worked on python 2.7 but glitched on python 3.2 because of that difference. I needed to "rb" it... thanks, very thorough explanation.
  • jfs
    jfs almost 11 years
    os.linesep is replaced by \n while reading in text mode on all platforms (not only Windows). If os.linesep == '\n' then it is the same as no conversion on Python 2.
  • Lennart Regebro
    Lennart Regebro almost 11 years
    @J.F.Sebastian: Which in practice means that it only happens on Windows (and Mac OS 9, but that's not supported since Python 2.4). While in Python 3 all newline combinations will be translated to '\n' on all platforms.
  • MikeB
    MikeB almost 7 years
    unfortunately, the documentation indicates that Universal Newlines mode is deprecated. It looks like exactly what I'd want, but doesn't seem to explain why it is deprecated or what the replacement mechanism might be.
  • Intelligent-Infrastructure
    Intelligent-Infrastructure about 6 years
    and how can you handle this if you use with codecs.open()?
  • Lennart Regebro
    Lennart Regebro about 6 years
    Codecs.open() also takes file mode flags.
  • Boris Verkhovskiy
    Boris Verkhovskiy about 5 years
    @MikeB the feature itself is not deprecated. It's the default. You don't need to do anything to enable it. When you open a file in text mode, it's opened in Universal Newlines mode. The thing that is deprecated is setting mode="U" specifically. If you want to disable Universal Newlines then you can pass newline="\n" or whatever. See this question.