Skip to content

lexer: a line break in a string is \n whatever the file's line endings - #182

Merged
simontreanor merged 1 commit into
mainfrom
crlf-string-literals
Oct 17, 2026
Merged

simontreanor merged 1 commit into
mainfrom
crlf-string-literals

Conversation

@simontreanor

Copy link
Copy Markdown
Owner

Found by the pre-release Python 3.12 check for 0.10.0: the one remaining difference between the Windows and Linux runs of examples/hello.pyfun was a carriage return inside a multi-line string.

The bug: a Pyfun file saved with Windows line endings put a \r before every newline of a multi-line string. """a<CRLF>b""" had length 4, where Python's universal newlines give 3. It predates this release, and students on Windows would carry it into every triple-quoted string they print, write to a file or compare.

The fix: push_char, which takes every literal character of a plain, raw and interpolated string, turns \r\n and a lone \r into \n, as Python does. An escaped \r is still a carriage return. Spans are untouched, since only the literal's content changes.

Checked: a lexer test covers each string form, a lone \r, and the escape. cargo fmt, cargo clippy --all-targets (clean), cargo test (every binary) and docs/verify_lessons.py pass, and every e2e program under Python 3.12 now matches Windows/3.14 except glibc's math.cbrt(27.0) (286 of 287, a known libm difference the test already tolerates).

A Pyfun file saved with Windows line endings put a carriage return before
every newline of a multi-line string: `"""a<CRLF>b"""` had length 4 where
Python's universal newlines give 3. Students on Windows would carry it into
every triple-quoted string they print, write to a file or compare. It showed
up as the one difference between the Windows and Linux runs of
examples/hello.pyfun in the pre-release Python 3.12 check.

push_char, which takes every literal character of a plain, raw and
interpolated string, now turns `\r\n` and a lone `\r` into `\n`, as Python
does. An escaped `\r` is still a carriage return. Spans are untouched, since
only the literal's content changes.
@simontreanor
simontreanor merged commit 311d91d into main Oct 17, 2026
22 checks passed
@simontreanor
simontreanor deleted the crlf-string-literals branch October 17, 2026 23:58
@simontreanor simontreanor mentioned this pull request Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant