Skip to content

exclude pragma from line length calculation - #27313

Open
ericbuehl wants to merge 3 commits into
astral-sh:mainfrom
ericbuehl:eb-pragma-line-length
Open

exclude pragma from line length calculation#27313
ericbuehl wants to merge 3 commits into
astral-sh:mainfrom
ericbuehl:eb-pragma-line-length

Conversation

@ericbuehl

Copy link
Copy Markdown

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

#12901
#12179
#20042
#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 linter changes. (+58 -0 violations, +0 -0 fixes in 4 projects; 53 projects unchanged)

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

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

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

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

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

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

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

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

+ homeassistant/components/backup/__init__.py:102:9: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/cloud/google_config.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/config/automation.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/config/script.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/demo/alarm_control_panel.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/device_automation/__init__.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/energy/sensor.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/esphome/manager.py:130:92: RUF100 [*] Unused `noqa` directive (unused: `I001`)
+ homeassistant/components/ffmpeg_noise/binary_sensor.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/geo_location/__init__.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/google_assistant/helpers.py:659:13: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/homeassistant_hardware/util.py:318:5: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/homekit_controller/config_flow.py:358:9: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/http/view.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/intent/timers.py:461:13: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/number/__init__.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/recorder/auto_repairs/schema.py:248:9: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/recorder/util.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/scrape/config_flow.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/sonos/media_player.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/sun/__init__.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/utility_meter/sensor.py:3:1: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/websocket_api/commands.py:1189:5: I001 [*] Import block is un-sorted or un-formatted
+ homeassistant/components/zeroconf/__init__.py:3:1: I001 [*] Import block is un-sorted or un-formatted
... 30 additional changes omitted for rule I001
... 29 additional changes omitted for project

Changes by rule (2 rules affected)

code total + violation - violation + fix - fix
I001 57 57 0 0 0
RUF100 1 1 0 0 0

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+58 -1 violations, +0 -0 fixes in 4 projects; 53 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:554:17: unsorted-imports [*] Import block is un-sorted or un-formatted
+ packages/reflex-hosting-cli/src/reflex_cli/v2/secrets.py:161: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:130:92: noqa-comments [*] `noqa` comment used instead of `ruff: ignore`
+ homeassistant/components/esphome/manager.py:130: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:659: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:461: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
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
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.

2 participants