Skip to content

Keep long comments off the opening line and within line_length - #2645

Open
SemTiOne wants to merge 3 commits into
PyCQA:mainfrom
SemTiOne:issue/2124
Open

Keep long comments off the opening line and within line_length#2645
SemTiOne wants to merge 3 commits into
PyCQA:mainfrom
SemTiOne:issue/2124

Conversation

@SemTiOne

@SemTiOne SemTiOne commented Aug 29, 2026

Copy link
Copy Markdown

vertical_hanging_indent now renders each comment fragment on its own # line instead of merging them onto the from ... import ( line with "; ".

@Manny7717 Manny7717 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verified locally on head 67213aa (tests/unit: 627 passed / 2 failed / 1 skipped — the 2 failures are the known pre-existing FileNotFoundError env noise (issue_909/938), byte-identical on main; main baseline is 623 passed, so the +4 are exactly this PR's new tests, zero regressions).

Fix behavior confirmed:

  • Issue #2124 shape (black profile, long comment inside a multi-line from-import): the comment now moves to its own line under the opening paren instead of being merged onto from ... import (isort.code output verified, and the result is idempotent (re-running produces identical output).
  • Functional comments are correctly exempt: # noqa: F401 and # type: ignore stay on the opening line (verified end-to-end — moving them would break their meaning).
  • Short comments still stay on the opening line (existing behavior preserved, covered by test_vertical_hanging_indent_short_comment_stays_on_opening_line).
  • wrap.import_statement(explode=True) now passes the real line_length instead of 1; checked the vertical_hanging_indent interface — line_length is only consumed by the new branch, so no other explode-mode behavior changes.
  • isort self-lint (--profile hug --check --diff isort/ tests/) and ruff on the changed files: clean.

Non-blocking nit: the functional-comment detection uses a loose substring ("noqa" in text or "type:" in text). A comment that merely mentions these tokens (e.g. # check type: int ...) is treated as functional and stays on the over-long opening line. This errs in the safe direction (it's the old behavior), so not a blocker — but anchoring the check to a directive-shaped pattern (e.g. comment starting with # noqa / # type: ignore) would make it tighter. No change requested.

Comment thread isort/wrap_modes.py Outdated

@Manny7717 Manny7717 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Re-verified on 9683ad6 — my wrap_modes.py:178 nit is fully addressed.

Verification (local):

  1. Regression proven: test_vertical_hanging_indent_non_directive_type_comment_moves_off FAILS on 67213aa (old substring "type:" in _comment_text kept a check type: int comment on the opening line) and PASSES on 9683ad6. Exactly the false-positive I flagged.
  2. Functional exemptions intact (executed probes): long noqa: F401 ... comment stays on the opening line (from os.path import ( # noqa: ...); long type: ignore ... stays as well. Non-directive check type: int and plain long comments move off to their own line under the paren.
  3. No regressions: full unit suite on head = 628 passed / 2 failed — the 2 failures (issue_909/938 FileNotFoundError) are the documented pre-existing env noise, byte-identical on base. Base = 627 passed / 3 failed (env noise + the new regression test). Zero new failures.

The comment.strip().lower().startswith(("noqa", "type: ignore")) per-comment check is a strictly better heuristic than the substring match, and the test pins the non-directive case so it can't regress.

@DanielNoord DanielNoord left a comment

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.

After seeing the code I am not sure that this is a bug. Not sorting the imports also isn't the correct behaviour. Perhaps there is just no solution for this?

@SemTiOne

SemTiOne commented Sep 1, 2026

Copy link
Copy Markdown
Author

Isn't issue #2124 about the merged comment violating line_length? The user had two separate comment lines that got collapsed onto from ... import ( and blew past 88 chars.

With the fix:

from os.path import (
    # this is a really really really really really really really really
    # really really really really really really long comment
    getsize,
    join,
)

--- line lengths ---
1:  21 | from os.path import (
2:  71 |     # this is a really really really really really really really really
3:  60 |     # really really really really really really long comment
4:  12 |     getsize,
5:   9 |     join,
6:   1 | )
--- max: 71 ---
--- idempotent: True ---

@SemTiOne
SemTiOne requested a review from DanielNoord September 1, 2026 02:01

@Manny7717 Manny7717 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Re-approving on the new head 94104cf ("Render each comment fragment on its own line"). This commit answers the maintainer's concern that a long merged comment could still violate line_length: each comment fragment now renders on its own # line under the paren via line_separator.join(add_to_line([fragment], ...)).

Verified locally on 94104cf:

  • New test test_vertical_hanging_indent_multi_fragment_comments_each_on_own_line passes; every output line asserted <= 88 chars.
  • End-to-end: two long comment fragments under VHI (multi_line_output=3, line_length=88) render on separate indented lines, imports sorted, idempotent (re-run byte-identical).
  • Short comments unchanged (stay on opening line when they fit); functional comments (noqa/type: ignore) still exempt.
  • Full unit suite: 629 passed / 2 failed (issue_909/938 FileNotFoundError env noise, identical on main) / 1 skipped - zero regressions, exactly +1 test.

Note on the maintainer thread: per-fragment rendering is the right resolution - the previous behavior (all fragments joined onto one line) could still blow past line_length, which is the actual #2124 complaint. Approved.

@SemTiOne SemTiOne changed the title Keep long comments off the opening line Keep long comments off the opening line and within line_length Sep 1, 2026
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.

Line Length Ignores Comments

3 participants