Skip to content

[pylint] Mark fixes unsafe when deleting comments (PLR5501, PLW0120) - #29414

Merged
ntBre merged 2 commits into
astral-sh:mainfrom
fixfon:t3/keep-else-line-comment-pylint
Oct 16, 2026
Merged

ntBre merged 2 commits into
astral-sh:mainfrom
fixfon:t3/keep-else-line-comment-pylint

Conversation

@fixfon

@fixfon fixfon commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #29395.

Both fixes rewrote the else: line and silently dropped any comment after the colon. Following review, the fix no longer tries to move that comment. Instead, PLR5501 and PLW0120 now mark the fix as unsafe when the else: line has a comment that would be deleted, the same approach as UP035 (#29413). Without such a comment the fix stays safe. Inline bodies like else: x = 1 # c also stay safe, since only else: is removed and the comment belongs to the statement.

Both rules got a "Fix safety" section in their docs. The existing PLW0120 snapshots only gain the unsafe-fix note, because their fixtures use else: # [useless-else-on-loop]. New fixture cases cover the unsafe and safe paths for both rules.

I used an AI assistant while working on this and reviewed the changes myself.

@astral-sh-bot
astral-sh-bot Bot requested a review from ntBre October 15, 2026 07:00
@astral-sh-bot

astral-sh-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

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

prefecthq/prefect (+0 -0 violations, +0 -2 fixes)

- src/prefect/utilities/pydantic.py:274:5: PLW0120 [*] `else` clause on loop without a `break` statement; remove the `else` and dedent its contents
+ src/prefect/utilities/pydantic.py:274:5: PLW0120 `else` clause on loop without a `break` statement; remove the `else` and dedent its contents

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
PLW0120 2 0 0 0 2

Linter (preview)

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

prefecthq/prefect (+1 -1 violations, +0 -0 fixes)

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

- src/prefect/utilities/pydantic.py:274:5: useless-else-on-loop [*] `else` clause on loop without a `break` statement; remove the `else` and dedent its contents
+ src/prefect/utilities/pydantic.py:274:5: useless-else-on-loop `else` clause on loop without a `break` statement; remove the `else` and dedent its contents

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
useless-else-on-loop 2 1 1 0 0

@fixfon
fixfon force-pushed the t3/keep-else-line-comment-pylint branch from f754448 to 98d4494 Compare October 15, 2026 17:45
@ntBre

ntBre commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Thanks for looking into this! The changes aren't that involved, but I'm kind of leaning toward just marking the fixes unsafe if they would drop comments, instead of trying to retain them. The bit about breaking noqa comments by moving them seems especially unfortunate, even if that already happens in the RET rules. These also seem like fairly niche places to have comments, so just marking them unsafe seems fine.

…LR5501`, `PLW0120`)

Both fixes replace the `else:` line, so a trailing comment on it (e.g.,
`else:  # fallback`) was deleted while the fix was still marked safe.

Rather than moving the comment, mark the fix unsafe when the `else` line
has a comment, using the same `comment_ranges().intersects` check as
other rules, and document it in a "Fix safety" section. Fixes without a
comment on the `else` line, including an inline `else:` body whose
trailing comment belongs to the statement, stay safe.
@fixfon
fixfon force-pushed the t3/keep-else-line-comment-pylint branch from 98d4494 to aca8801 Compare October 16, 2026 21:47
@fixfon fixfon changed the title [pylint] Keep else: line comments in PLR5501 and PLW0120 fixes [pylint] Mark PLR5501 and PLW0120 fixes unsafe when they delete an else: line comment Oct 16, 2026
@fixfon

fixfon commented Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, that makes sense. I removed the comment-moving logic. Both PLR5501 and PLW0120 now mark the fix as unsafe when it would delete a comment on the else: line, and stay safe otherwise. The PLW0120 snapshots are back to their original output, apart from the added unsafe-fix note, since those fixtures have a comment on the else: line. I also added fixture cases for the unsafe and safe paths.

@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.

Thanks!

@ntBre ntBre added bug An issue describing something that isn't working, or a PR that fixes a bug fixes Related to suggested fixes for violations labels Oct 16, 2026
@ntBre ntBre changed the title [pylint] Mark PLR5501 and PLW0120 fixes unsafe when they delete an else: line comment [pylint] Mark fixes unsafe when deleting comments (PLR5501, PLW0120) Oct 16, 2026
@ntBre
ntBre merged commit 8d122c1 into astral-sh:main Oct 16, 2026
51 checks passed
rlichtenwalter added a commit to rlichtenwalter/dir2text that referenced this pull request Oct 30, 2026
This PR contains the following updates:

| Package | Type | Update | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|---|---|
| [DavidAnson/markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) | repository | minor | `v0.23.3` β†’ `v0.24.0` | ![age](https://developer.mend.io/api/mc/badges/age/github-tags/DavidAnson%2fmarkdownlint-cli2/v0.24.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/github-tags/DavidAnson%2fmarkdownlint-cli2/v0.23.3/v0.24.0?slim=true) |
| [ruff](https://docs.astral.sh/ruff) ([source](https://github.com/astral-sh/ruff), [changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)) | dependency-groups | patch | `==0.17.1` β†’ `==0.17.3` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/ruff/0.17.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/ruff/0.17.1/0.17.3?slim=true) |

Note: The `pre-commit` manager in Renovate is not supported by the `pre-commit` maintainers or community. Please do not report any problems there, instead [create a Discussion in the Renovate repository](https://github.com/renovatebot/renovate/discussions/new) if you have any questions.

---

### Release Notes

<details>
<summary>DavidAnson/markdownlint-cli2</summary>

### [`v0.24.0`](DavidAnson/markdownlint-cli2@v0.23.3...v0.24.0)

[Compare Source](DavidAnson/markdownlint-cli2@v0.23.3...v0.24.0)

</details>

<details>
<summary>astral-sh/ruff (ruff)</summary>

### [`v0.17.3`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#0173)

[Compare Source](astral-sh/ruff@0.17.2...0.17.3)

Released on 2026-10-26.

##### Preview features

- \[`suspicious`] Add `shared-clock-mock` ([#&#8203;29074](astral-sh/ruff#29074))

##### Bug fixes

- \[`pyupgrade`] Avoid incorrect conversions to f-strings (`UP032`) ([#&#8203;25485](astral-sh/ruff#25485))

##### Performance

- Buffer stdout in `ruff format` ([#&#8203;29631](astral-sh/ruff#29631))
- Specialize ASCII identifier lexing ([#&#8203;29503](astral-sh/ruff#29503))
- Speed up identifier and keyword lexing ([#&#8203;29463](astral-sh/ruff#29463))

##### Documentation

- \[`flake8-bandit`] Describe what the rule actually checks for `httpx` (`S113`) ([#&#8203;27936](astral-sh/ruff#27936))

##### Contributors

- [@&#8203;itsvedantkumar](https://github.com/itsvedantkumar)
- [@&#8203;charliermarsh](https://github.com/charliermarsh)
- [@&#8203;anishgirianish](https://github.com/anishgirianish)

### [`v0.17.2`](https://github.com/astral-sh/ruff/blob/HEAD/CHANGELOG.md#0172)

[Compare Source](astral-sh/ruff@0.17.1...0.17.2)

Released on 2026-10-22.

##### Preview features

- \[`complexity`] Add `unnecessary-regular-expression-compile` ([#&#8203;25533](astral-sh/ruff#25533))

##### Bug fixes

- Avoid syntax errors for type variables with starred constraints (`UP040`, `UP046`, `UP047`, `RUF053`) ([#&#8203;28362](astral-sh/ruff#28362))
- \[`pydocstyle`] Treat backslash-escaped `*args` and `**kwargs` as documented (`D417`) ([#&#8203;29536](astral-sh/ruff#29536))
- \[`pylint`] Avoid false positive on starred elements (`PLE0643`) ([#&#8203;29483](astral-sh/ruff#29483))
- \[`pylint`] Mark fixes unsafe when deleting comments (`PLR5501`, `PLW0120`) ([#&#8203;29414](astral-sh/ruff#29414))
- \[`pyupgrade`] Mark fix unsafe when deleting comments (`UP035`) ([#&#8203;29413](astral-sh/ruff#29413))

##### Performance

- Avoid intermediate names in lint name resolution ([#&#8203;29506](astral-sh/ruff#29506))
- Prefilter bidirectional Unicode checks by UTF-8 leading bytes ([#&#8203;29561](astral-sh/ruff#29561))
- Share postfix parsing and reduce expression copies ([#&#8203;29480](astral-sh/ruff#29480))

##### Configuration

- \[`pylint`] Add a configurable allowlist for `magic-value-comparison` (`PLR2004`) ([#&#8203;18961](astral-sh/ruff#18961))

##### Documentation

- Clarify documentation and correct stale guidance ([#&#8203;29374](astral-sh/ruff#29374))
- \[`pyupgrade`] Remove mentions of variance related to fix safety (`UP040`, `UP047`) ([#&#8203;29592](astral-sh/ruff#29592))

##### Contributors

- [@&#8203;fixfon](https://github.com/fixfon)
- [@&#8203;MichaReiser](https://github.com/MichaReiser)
- [@&#8203;zaniebot](https://github.com/zaniebot)
- [@&#8203;FrancescoPezzella](https://github.com/FrancescoPezzella)
- [@&#8203;anishgirianish](https://github.com/anishgirianish)
- [@&#8203;rajveer3x](https://github.com/rajveer3x)
- [@&#8203;charliermarsh](https://github.com/charliermarsh)
- [@&#8203;LckyLike](https://github.com/LckyLke)
- [@&#8203;DaniBodor](https://github.com/DaniBodor)

</details>

---

### Configuration

πŸ“… **Schedule**: (in timezone America/Denver)

- Branch creation
  - Between 02:00 AM and 06:59 AM, only on Tuesday (`* 2-6 * * 2`)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

πŸ‘» **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNDguMyIsInVwZGF0ZWRJblZlciI6IjQ0LjE0OC4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZSJdfQ==-->

Reviewed-on: https://git.lichtenwalter.site/rlichten/dir2text/pulls/100
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug An issue describing something that isn't working, or a PR that fixes a bug fixes Related to suggested fixes for violations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PLR5501 and PLW0120 safe fixes delete a trailing comment on the else: line

2 participants