From bd9ebbd5f802cf78bbc48fe8544d370638fb38a3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 19:01:35 +0000 Subject: [PATCH 1/2] Initial plan From 422305933918b8f9ef0f986515b83d0b54b1f8c1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 31 Mar 2026 19:21:37 +0000 Subject: [PATCH 2/2] Fix: Input with semicolon after multi-line import is corrupted (#2417) Agent-Logs-Url: https://github.com/PyCQA/isort/sessions/2299f790-3e0b-4eb8-8c69-7ddd12b28d5a Co-authored-by: DanielNoord <13665637+DanielNoord@users.noreply.github.com> --- isort/parse.py | 13 +++++++++++++ tests/unit/test_regressions.py | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/isort/parse.py b/isort/parse.py index 5928b392..d3e16645 100644 --- a/isort/parse.py +++ b/isort/parse.py @@ -218,6 +218,19 @@ def _get_next_line() -> tuple[str, str | None]: ): nested_comments[stripped_line] = extra_line.comment + # If a semicolon was introduced by a backslash-continued line (i.e., the + # original statement had no semicolon but the merged import_string does), + # treat the entire multi-line construct as non-import code and output as-is. + # This mirrors what skip_line() does for single-line semicolons. + # Note: statement_index was set to `index` *after* its increment at the top + # of the outer while loop, so statement_index - 1 is the index of the first + # line of this statement in in_lines. + import_string_code = import_string.split("#")[0] + statement_code = statement.split("#")[0] + if ";" in import_string_code and ";" not in statement_code: + out_lines.extend(in_lines[statement_index - 1 : index]) + continue + if type_of_import == "from": import_string = normalize_from_import_string(import_string) if "import " not in import_string: diff --git a/tests/unit/test_regressions.py b/tests/unit/test_regressions.py index bd0e538d..487caee6 100644 --- a/tests/unit/test_regressions.py +++ b/tests/unit/test_regressions.py @@ -1985,3 +1985,16 @@ 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_semicolon_after_backslash_continuation_not_corrupted(): + """Ensure isort doesn't corrupt imports when a backslash-continued line ends with a + semicolon followed by additional code, e.g.: + + from os import \\ + name; print(name) + + See: https://github.com/PyCQA/isort/issues/2417 + """ + test_input = "from os import \\\n name; print(name)\n" + assert isort.code(test_input) == test_input