Batu Lab NotesPractical developer guides

Normalize line endings in a generated text artifact

By Batu ยท English technical notes

Also published in our Blogger archive.

Direct answer

For a generated artifact with an explicit LF convention, writing bytes avoids platform-dependent text newline translation. The byte literal in this example contains two lines, each terminated by an LF byte. Path.write_bytes writes those bytes directly, and reading the result confirms that no CRLF sequence was introduced.

This is a rule for newly generated output. The snippet does not load an existing document, preserve its original encoding, or convert mixed newline forms from an external source. If that is the requirement, define those decisions before implementing a conversion; a blind replacement can change content that is meaningful to another format.

The trailing newline is intentional and should be part of the artifact contract. For a larger renderer, construct the logical lines, join them with LF, encode with a declared encoding, and test exact bytes. Also choose an output collision policy: write_bytes replaces an existing file, so the temporary fixture here should not be adapted to an arbitrary destination without considering that behavior.

Complete example

from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as d:
    p = Path(d) / 'report.txt'
    p.write_bytes(b'alpha\nbeta\n')
    assert b'\r\n' not in p.read_bytes()
    result = 'newline=LF'
    print(result)

Expected stdout (for a platform supporting the demonstrated operation):

newline=LF

Sources

- pathlib.Path.write_bytes

Prepared with AI assistance. The example uses synthetic data; its stated limits apply.