Skip to content

fix: preserve LF line endings when reading from stdin on Windows#2543

Open
dayananda-ks wants to merge 1 commit into
PyCQA:mainfrom
dayananda-ks:fix-2453-line-ending-stdin
Open

fix: preserve LF line endings when reading from stdin on Windows#2543
dayananda-ks wants to merge 1 commit into
PyCQA:mainfrom
dayananda-ks:fix-2453-line-ending-stdin

Conversation

@dayananda-ks
Copy link
Copy Markdown

Problem

Fixes #2453

When passing a file with Unix-style LF line endings to isort
via stdin on Windows, it always converts them to CRLF.

Root Cause

Python opens stdin in text mode on Windows, which auto-converts
\n to \r\n before isort can detect the original line endings.

Fix

Read stdin in binary mode first to detect the original line
endings, then decode for processing.

Testing

Added a regression test test_lf_line_endings_preserved_from_stdin_issue_2453
that verifies LF line endings are preserved.

When piping a file with LF line endings into isort on Windows,
the output was always converted to CRLF. This fix reads stdin
in binary mode first to detect original line endings before
Python's text mode conversion happens.

fixes PyCQA#2453
Copilot AI review requested due to automatic review settings May 17, 2026 11:22
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a regression test and updates the CLI streaming-input path to better preserve original line endings when formatting code from stdin (notably for Windows LF-only input).

Changes:

  • Added a unit test for preserving LF line endings when processing stdin content.
  • Updated isort.main.main() to read stdin as raw bytes and re-wrap it as a TextIOWrapper to avoid platform newline surprises.
  • Introduced detection of stdin line endings (\r\n, \r, \n) for potential downstream handling.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
tests/unit/test_regressions.py Adds a regression test asserting LF input is not converted to CRLF.
isort/main.py Changes stdin handling to read raw bytes from sys.stdin.buffer and wrap them for processing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread isort/main.py
Comment on lines +1063 to +1064
if stdin is None:
raw = sys.stdin.buffer.read()
Comment thread isort/main.py
Comment on lines +1064 to +1072
raw = sys.stdin.buffer.read()
if b"\r\n" in raw:
line_ending = "\r\n"
elif b"\r" in raw:
line_ending = "\r"
else:
line_ending = "\n"
import io
input_stream = io.TextIOWrapper(io.BytesIO(raw), encoding=sys.stdin.encoding or "utf-8")
Comment thread isort/main.py
Comment on lines +1065 to +1070
if b"\r\n" in raw:
line_ending = "\r\n"
elif b"\r" in raw:
line_ending = "\r"
else:
line_ending = "\n"
Comment on lines +1990 to +2001
def test_lf_line_endings_preserved_from_stdin_issue_2453():
"""LF line endings should be preserved when reading from stdin on Windows.
See: https://github.com/PyCQA/isort/issues/2453
"""
import io
lf_content = "import os\nimport re\n"
input_stream = io.TextIOWrapper(
io.BytesIO(lf_content.encode("utf-8")), encoding="utf-8"
)
output_stream = io.StringIO()
from isort import core
core.process(input_stream, output_stream)
Copy link
Copy Markdown
Member

@DanielNoord DanielNoord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Copilot review points out some flaws. Do you mind looking into these? :)

@dayananda-ks
Copy link
Copy Markdown
Author

Thank you for the review! I'll update the test to go through
the CLI stdin path in isort/main.py instead of core.process() directly.
Working on it now! 😊

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.

line-ending detection doesn't work on Windows and --help explain how to use --line-ending

3 participants