Did Python ever care about line endings in source code?

I’ve been cleaning up a lot of old duplicate questions on Stack Overflow about various random IndentationErrors (mostly trivial matters for which we have two or three really solid canonicals), and one thing I’ve noticed is multiple people reporting that they fixed an IndentationError (or in some cases a more general SyntaxError) by fixing line endings to use the platform default (e.g. replacing CRLF sequences with LF on Linux).

I haven’t been able to reproduce that - i.e., code with the “wrong” line endings seems to work fine:

$ cat crlf.py 
if 1:
    if 2:
        pass
$ xxd crlf.py 
00000000: 6966 2031 3a0d 0a20 2020 2069 6620 323a  if 1:..    if 2:
00000010: 0d0a 2020 2020 2020 2020 7061 7373 0d0a  ..        pass..
$ python2.7 crlf.py 
$ python3.8 crlf.py 
$ python3.11 crlf.py 

But I just wanted to make sure: did Python ever reject code as improperly indented or syntactically incorrect, due to having the wrong line endings? Or is there some specific arrangement of the code that would make it care about the line endings? Or are these people all just mistaken (i.e., they incidentally fixed mixed tab and space indentation at the same time)?

I have the vaguest memory of running into issues on Windows related to line endings years and years ago, but I can’t get it to replicate, even with python 3.0:

py = "if 1:\r\n    if 2:\n        print('hello')\r"
py2 = "if 1:\n\r    if 2:\n        print('hello')"

b = bytes(py, 'utf-8')
b2 = bytes(py2, 'utf-8')

with open('test.py', 'wb') as f:
    f.write(b)

with open('test2.py', 'wb') as f:
    f.write(b2)
D:\src\scratch>python test.py
hello

D:\src\scratch>python test2.py 
hello

Maybe a python 2 issue?

This problem was generally solved in Python 2.3 . You can read it in more detail here: What’s New in Python 2.3 — Python 3.12.1 documentation

3 Likes

Ah, it was part of the same change supporting universal newlines for files. Makes sense; the import/exec code could take advantage of the same functionality.

My recollection was that it was the shebang that caused grief, as bash doesn’t handle the CR properly:

$ cat test.py
#!/usr/bin/env python3
print('hello world')

$ unix2dos test.py
$ ./test.py
/usr/bin/env: ‘python3\r’: No such file or directory
1 Like

It’s the kernel not the shell that interprets the shebang.
Which is why you can use the system call exec to run a script.