fix: preserve LF line endings when reading from stdin on Windows#2543
fix: preserve LF line endings when reading from stdin on Windows#2543dayananda-ks wants to merge 1 commit into
Conversation
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
There was a problem hiding this comment.
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 aTextIOWrapperto 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.
| if stdin is None: | ||
| raw = sys.stdin.buffer.read() |
| 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") |
| if b"\r\n" in raw: | ||
| line_ending = "\r\n" | ||
| elif b"\r" in raw: | ||
| line_ending = "\r" | ||
| else: | ||
| line_ending = "\n" |
| 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) |
DanielNoord
left a comment
There was a problem hiding this comment.
The Copilot review points out some flaws. Do you mind looking into these? :)
|
Thank you for the review! I'll update the test to go through |
|
@dayananda-ks Are you still working on this? |
|
Closing for now. Please reach out if you do want to work on this! |
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
\nto\r\nbefore 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_2453that verifies LF line endings are preserved.