diff --git a/isort/core.py b/isort/core.py index 46bd77f1..a1ad5e6c 100644 --- a/isort/core.py +++ b/isort/core.py @@ -373,12 +373,15 @@ def process( not_imports = True if not_imports: + above_import_section: str = "" if not was_in_quote and config.lines_before_imports > -1: if line.strip() == "" and not end_of_file: lines_before += line continue if not import_section: output_stream.write("".join(lines_before)) + else: + above_import_section = "".join(lines_before) lines_before = [] raw_import_section: str = import_section @@ -451,7 +454,7 @@ def process( ) made_changes = made_changes or _has_changed( - before=raw_import_section, + before=above_import_section + raw_import_section, after=sorted_import_section, line_separator=line_separator, ignore_whitespace=config.ignore_whitespace, @@ -522,4 +525,4 @@ def _has_changed(before: str, after: str, line_separator: str, ignore_whitespace remove_whitespace(before, line_separator=line_separator).strip() != remove_whitespace(after, line_separator=line_separator).strip() ) - return before.strip() != after.strip() + return before.rstrip() != after.rstrip() diff --git a/tests/unit/test_isort.py b/tests/unit/test_isort.py index 3271ab53..9575c5a1 100644 --- a/tests/unit/test_isort.py +++ b/tests/unit/test_isort.py @@ -1703,6 +1703,31 @@ def test_custom_lines_before_import_section(has_body: bool) -> None: ) +def test_check_code_detects_lines_before_import_changes() -> None: + """check_code must return False when lines_before_imports requires adding or removing blank + lines before the import section, even if the imports themselves are already sorted. + + Regression test for https://github.com/PyCQA/isort/issues/2242 + """ + ln = "\n" + sorted_imports = "from a import b, x\n" + body = "\nfoo = 'bar'\n" + + # Adding a blank line before imports (0 present, 1 required) + code_without_blank = sorted_imports + body + assert isort.code(code_without_blank, lines_before_imports=1) == ln + code_without_blank + assert not isort.check_code(code_without_blank, lines_before_imports=1) + + # Removing a blank line before imports (1 present, 0 required) + code_with_blank = ln + sorted_imports + body + assert isort.code(code_with_blank, lines_before_imports=0) == sorted_imports + body + assert not isort.check_code(code_with_blank, lines_before_imports=0) + + # Already correct: no change needed + assert isort.check_code(code_without_blank, lines_before_imports=0) + assert isort.check_code(code_with_blank, lines_before_imports=1) + + def test_custom_lines_after_import_section() -> None: """Test the case where the number of lines to output after imports has been explicitly set.""" test_input = "from a import b\nfoo = 'bar'\n"