Skip to content

[isort] Exclude pragma comments from line length calculation (I001) - #27313

Merged
ntBre merged 8 commits into
astral-sh:mainfrom
ericbuehl:eb-pragma-line-length
Sep 2, 2026
Merged

ntBre merged 8 commits into
astral-sh:mainfrom
ericbuehl:eb-pragma-line-length

Conversation

@ericbuehl

@ericbuehl ericbuehl commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

multiple issues arise of line length limits conflicting with per-line suppressions. it was proposed that pragmas should not be included in line length calculation. this is an attempt at that

fixes #12179
fixes #20042
fixes #27059

Test Plan

  • added/amended existing test cases
  • verified expected behavior on large existing codebase that has several existing line-wrapping issues. all are now automatically fixed by ruff

@astral-sh-bot

astral-sh-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+58 -1 violations, +0 -0 fixes in 4 projects; 55 projects unchanged)

python/typeshed (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview --select E,F,FA,I,PYI,RUF,UP,W

+ stubs/pika/pika/adapters/twisted_connection.pyi:4:1: unsorted-imports [*] Import block is un-sorted or un-formatted

python-poetry/poetry (+1 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ src/poetry/console/commands/export.py:1:1: unsorted-imports [*] Import block is un-sorted or un-formatted

reflex-dev/reflex (+3 -0 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ packages/reflex-hosting-cli/src/reflex_cli/v2/cli.py:909:17: unsorted-imports [*] Import block is un-sorted or un-formatted
+ packages/reflex-hosting-cli/src/reflex_cli/v2/secrets.py:165:17: unsorted-imports [*] Import block is un-sorted or un-formatted
+ tests/units/test_model.py:1:1: unsorted-imports [*] Import block is un-sorted or un-formatted

home-assistant/core (+53 -1 violations, +0 -0 fixes)

ruff check --no-cache --exit-zero --no-fix --output-format concise --preview

+ homeassistant/components/backup/__init__.py:102:9: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/cloud/google_config.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/config/automation.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/config/script.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/demo/alarm_control_panel.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/device_automation/__init__.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/energy/sensor.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
- homeassistant/components/esphome/manager.py:132:92: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
+ homeassistant/components/esphome/manager.py:132:92: unused-noqa [*] Unused `noqa` directive (unused: `I001`)
+ homeassistant/components/ffmpeg_noise/binary_sensor.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/geo_location/__init__.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/google_assistant/helpers.py:652:13: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/homeassistant_hardware/util.py:318:5: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/homekit_controller/config_flow.py:358:9: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/http/view.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/intent/timers.py:460:13: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/number/__init__.py:3:1: unsorted-imports [*] Import block is un-sorted or un-formatted
+ homeassistant/components/recorder/auto_repairs/schema.py:248:9: unsorted-imports [*] Import block is un-sorted or un-formatted
... 37 additional changes omitted for rule unsorted-imports
... 36 additional changes omitted for project

Changes by rule (3 rules affected)

code total + violation - violation + fix - fix
unsorted-imports 57 57 0 0 0
unused-noqa 1 1 0 0 0
noqa-comments 1 0 1 0 0

@Sanjays2402

Copy link
Copy Markdown
Contributor

the all-or-nothing is_pragma_comment check misses mixed comments — something like import x # keep this # noqa: TID251 reads as non-pragma, so its full width still counts and the import wraps, moving the noqa off the statement. thats the same failure this is fixing. E501s own preview path handles it with find_trailing_pragma_offset to strip only the pragma suffix. worth reusing that here?

/// )
/// ```
fn add_comment_width(line_width: LineWidthBuilder, comment: &str) -> LineWidthBuilder {
if is_pragma_comment(comment) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the width you skip here can come back as an E501: overlong.rs only strips a pragma when the line has exactly one comment (let [comment_range] = comment_ranges.comments_in_range(...)), but format_single_line concatenates every atop/inline/trailing comment onto the one line. so from m import x # explain # noqa: TID251 now stays unwrapped at, say, 95 chars and then line-too-long flags it because two comments in the range means no stripping at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I added a test case which I think should demonstrate your concern

@ericbuehl
ericbuehl requested a review from Sanjays2402 July 31, 2026 01:05
Comment thread crates/ruff_linter/src/rules/isort/format.rs Outdated
@ericbuehl
ericbuehl requested a review from MichaReiser July 31, 2026 18:16
Comment thread crates/ruff_linter/src/rules/isort/format.rs
@ntBre ntBre added isort Related to import sorting preview Related to preview mode features labels Jul 31, 2026
@ericbuehl
ericbuehl requested a review from ntBre July 31, 2026 20:30
@ericbuehl

Copy link
Copy Markdown
Contributor Author

@Sanjays2402 @ntBre @MichaReiser how does this look? anything else we should do?

@ntBre

ntBre commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

I think it's just waiting for me/us to have a chance to review :) I remember it looking good last time I skimmed through. I am a bit confused by the ecosystem report, which is still showing stable changes, but Codex says it's just stale. I'll try to retrigger it when I review again.

@ntBre ntBre left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you! This is awesome, really well-written tests and comments, and it resolves several issues at once. Sorry for the delay!

I took care of the merge conflict, which will hopefully also trigger a fresh ecosystem run demonstrating that this is only a preview change.

@ntBre ntBre changed the title exclude pragma from line length calculation [isort] Exclude pragma comments from line length calculation (I001) Sep 2, 2026
@ntBre
ntBre merged commit 2e730ef into astral-sh:main Sep 2, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

isort Related to import sorting preview Related to preview mode features

Projects

None yet

4 participants