Skip to content

Preserve form feed blank lines#2565

Open
lin-hongkuan wants to merge 1 commit into
PyCQA:mainfrom
lin-hongkuan:codex/preserve-form-feed-blank-lines
Open

Preserve form feed blank lines#2565
lin-hongkuan wants to merge 1 commit into
PyCQA:mainfrom
lin-hongkuan:codex/preserve-form-feed-blank-lines

Conversation

@lin-hongkuan

Copy link
Copy Markdown

str.splitlines() treats form feed (\f, U+000C) as a line boundary, so parsing a file with a form-feed-only blank line drops the character before output is generated. Later, the import-tail blank-line cleanup also treats any strip()-empty line as removable.

This changes parsing to split only on actual newline sequences (\r\n, \r, \n) and keeps import-tail cleanup from removing blank lines that contain form feed. That preserves valid Python blank lines while keeping the existing cleanup for ordinary whitespace-only lines.

fixes #2562

Tests:

  • py -3 -m pytest tests/unit/test_regressions.py::test_form_feed_blank_line_not_removed_issue_2562 tests/unit/test_api.py::test_sort_code_string_mixed_newlines tests/unit/test_isort.py::test_ensure_line_endings_are_preserved_issue_493 tests/unit/test_isort.py::test_line_endings_are_detected_ignoring_whitespace -q
  • py -3 -m pytest tests/unit/test_regressions.py tests/unit/test_api.py tests/unit/test_isort.py -q
  • py -3 -m ruff check isort/parse.py isort/output.py tests/unit/test_regressions.py --ignore PLC0207
  • py -3 -m mypy isort/parse.py isort/output.py

Note: a full tests/unit run produced 569 passed / 5 skipped before failing 4 environment-dependent tests unrelated to this change (example profile/sort plugin entry points and a Windows diff fixture side effect).

@bignose-debian

Copy link
Copy Markdown

@lin-hongkuan:

This changes parsing to split only on actual newline sequences (\r\n, \r, \n) and keeps import-tail cleanup from removing blank lines that contain form feed. That preserves valid Python blank lines while keeping the existing cleanup for ordinary whitespace-only lines.

Thank you for creating this well-targeted change.

@codecov

codecov Bot commented Jun 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.16%. Comparing base (0740d0c) to head (47cf7ae).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #2565   +/-   ##
=======================================
  Coverage   99.16%   99.16%           
=======================================
  Files          41       41           
  Lines        3101     3103    +2     
  Branches      671      670    -1     
=======================================
+ Hits         3075     3077    +2     
  Misses         14       14           
  Partials       12       12           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread CHANGELOG.md

### Unreleased

- Preserve form feed characters when they appear on otherwise blank lines (#2562)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this, we don't keep the changes here

Comment thread isort/output.py
Comment on lines +194 to +195
def _is_removable_blank_line(line: str) -> bool:
return "\f" not in line and line.strip() == ""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we use strip() here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ISort incorrectly removes some blank lines

3 participants