From 029fb448885e51c9472eae59ebfdaf90a3259613 Mon Sep 17 00:00:00 2001 From: Dayananda KS Date: Sun, 17 May 2026 16:49:33 +0530 Subject: [PATCH] fix: preserve LF line endings when reading from stdin on Windows 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 #2453 --- isort/main.py | 13 ++++++++++++- tests/unit/test_regressions.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/isort/main.py b/isort/main.py index 9369ddd1..c0ce1ef0 100644 --- a/isort/main.py +++ b/isort/main.py @@ -1060,7 +1060,18 @@ def main(argv: Sequence[str] | None = None, stdin: TextIOWrapper | None = None) if show_files: sys.exit("Error: can't show files for streaming input.") - input_stream = sys.stdin if stdin is None else stdin + if stdin is None: + 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") + else: + input_stream = stdin if check: incorrectly_sorted = not api.check_stream( input_stream=input_stream, diff --git a/tests/unit/test_regressions.py b/tests/unit/test_regressions.py index bd0e538d..d65dd10f 100644 --- a/tests/unit/test_regressions.py +++ b/tests/unit/test_regressions.py @@ -1985,3 +1985,19 @@ def test_comment_on_opening_line_of_aliased_import_does_not_move(): isort.code(short_line, profile="black") == "from mod import attr as alias # type: ignore[attr-defined] # My comment\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) + result = output_stream.getvalue() + assert "\r\n" not in result, "LF input should not be converted to CRLF"