Skip to content

Commit 3202ce8

Browse files
hansu650DanielNoord
authored andcommitted
Preserve CRLF blank lines during float-to-top preprocessing
Assisted-by: OpenAI Codex
1 parent 13758cf commit 3202ce8

2 files changed

Lines changed: 60 additions & 5 deletions

File tree

‎isort/core.py‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ def _float_to_top(
101101
parsed = parse.file_contents(current, config=config)
102102
verbose_output += parsed.verbose_output
103103
extra_space = ""
104-
while before and before[-1] == "\n":
105-
extra_space += "\n"
106-
before = before[:-1]
107-
extra_space = extra_space.replace("\n", "", 1)
104+
while before.endswith(("\n", "\r")):
105+
extra_space += parsed.line_separator
106+
before = before[:-2] if before.endswith("\r\n") else before[:-1]
107+
extra_space = extra_space.replace(parsed.line_separator, "", 1)
108108
sorted_output = output.sorted_imports(
109109
parsed, config, extension, import_type="import"
110110
)

‎tests/unit/test_regressions.py‎

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import isort
99
import isort.sections
10-
from isort.core import STRING_PREFIXES
10+
from isort.core import STRING_PREFIXES, _float_to_top
1111
from isort.main import main
1212
from isort.wrap_modes import WrapModes
1313

@@ -919,6 +919,61 @@ def test_isort_float_to_top_respects_isort_off_with_crlf_issue_2528():
919919
)
920920

921921

922+
@pytest.mark.parametrize("line_ending", ["\n", "\r\n"])
923+
@pytest.mark.parametrize(
924+
"boundary",
925+
[
926+
"# isort: split\n",
927+
"import z # isort: split\n",
928+
"# isort: off\nimport z\nimport a\n# isort: on\n",
929+
],
930+
)
931+
def test_float_to_top_check_accepts_unchanged_sections_issue_2681(line_ending, boundary):
932+
source = ("import os\n\n" + boundary + "\nimport sys\n").replace("\n", line_ending)
933+
934+
assert isort.code(source, float_to_top=True) == source
935+
assert isort.check_code(source, float_to_top=True, show_diff=True)
936+
937+
938+
@pytest.mark.parametrize("line_ending", ["\n", "\r\n"])
939+
@pytest.mark.parametrize("blank_lines", [0, 1, 3])
940+
def test_float_to_top_preserves_boundary_spacing_issue_2681(line_ending, blank_lines):
941+
source = ("import os\n" + "\n" * blank_lines + "# isort: split\n").replace("\n", line_ending)
942+
result = _float_to_top(StringIO(source), [], isort.Config(float_to_top=True), "py")
943+
944+
assert result.input_stream.read() == source
945+
assert not result.made_changes
946+
947+
948+
@pytest.mark.parametrize("line_ending", ["\n", "\r\n"])
949+
def test_float_to_top_check_detects_unsorted_sections_issue_2681(line_ending):
950+
source = "import sys\nimport os\n\n# isort: split\n\nimport a\n".replace("\n", line_ending)
951+
expected = "import os\nimport sys\n\n# isort: split\n\nimport a\n".replace("\n", line_ending)
952+
953+
assert not isort.check_code(source, float_to_top=True)
954+
assert isort.code(source, float_to_top=True) == expected
955+
assert isort.check_code(expected, float_to_top=True)
956+
957+
958+
@pytest.mark.parametrize("configured_ending", ["\n", "\r\n"])
959+
def test_float_to_top_configured_line_ending_issue_2681(configured_ending):
960+
source = "import os\r\n\r\n# isort: split\r\n\r\nimport sys\r\n"
961+
expected = source.replace("\r\n", configured_ending)
962+
result = isort.code(source, float_to_top=True, line_ending=configured_ending)
963+
964+
assert result == expected
965+
assert isort.check_code(result, float_to_top=True, line_ending=configured_ending)
966+
967+
968+
def test_float_to_top_cli_check_accepts_crlf_issue_2681(tmp_path):
969+
path = tmp_path / "example.py"
970+
source = b"import os\r\n\r\n# isort: split\r\n\r\nimport sys\r\n"
971+
path.write_bytes(source)
972+
973+
main(["--float-to-top", "--check-only", str(path)])
974+
assert path.read_bytes() == source
975+
976+
922977
def test_isort_doesnt_float_to_top_correctly_when_imports_not_at_top_issue_1382():
923978
"""isort should float existing imports to the top, if they are currently below the top.
924979
See: https://github.com/PyCQA/isort/issues/1382

0 commit comments

Comments
 (0)