pythonpython-3.xiocarriage-returnlinefeed

writing chr(13) to file gives chr(10) when read


I have a simple piece of code that breaks my mind:

if __name__ == '__main__':
    writen_text = chr(13)
    file = open('bug', 'w')
    file.write(writen_text)
    file.close()
    file = open('bug')
    read_text = ''.join(file.readlines())
    print([ord(c) for c in writen_text])
    print([ord(c) for c in read_text])
    assert writen_text == read_text

The output is

[13]
[10]
Traceback (most recent call last):
  File "/bug.py", line 10, in <module>
    assert writen_text == read_text
AssertionError

What is this??? I just want to write a text to a file and read exactly this text without any changes

Python3.6.6, Ubuntu18.04, if it matters


Solution

  • If you notice, starting with chr(10) remains the same and passes your assertion test.

    So the real question is why is the chr(13) being changed into a chr(10)? In order to answer that, we have to look at what each of these characters actually represent. The chr(13) is a carriage return character while the chr(10) is a line feed character.

    You mentioned that you are using a Linux box. Linux, utilizing the Unix model, uses the Line Feed character and does not use the Carriage Return character in it's files. Therefore, when writing the CR character to the file, the system is translating it to the LF character used by the system. Then, you are reading the file (with the translated character) and thus failing your assertion.

    Here's a good post on the differences in types of returns.