Implement RUF028 to detect useless formatter suppression comments by snowsignal · Pull Request #9899 · astral-sh/ruff (original) (raw)
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Conversation55 Commits13 Checks0 Files changed
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
Fixes #6611
Summary
This lint rule spots comments that are intended to suppress or enable the formatter, but will be ignored by the Ruff formatter.
We borrow some functions the formatter uses for determining comment placement / putting them in context within an AST.
The analysis function uses an AST visitor to visit each comment and attach it to the AST. It then uses that context to check:
- Is this comment in an expression?
- Does this comment have bad placement? (e.g. a
# fmt: skip
above a function instead of at the end of a line) - Is this comment redundant?
- Does this comment actually suppress any code?
- Does this comment have ambiguous placement? (e.g. a
# fmt: off
above anelse:
block)
If any of these are true, a violation is thrown. The reported reason depends on the order of the above check-list: in other words, a # fmt: skip
comment on its own line within a list expression will be reported as being in an expression, since that reason takes priority.
The lint suggests removing the comment as an unsafe fix, regardless of the reason.
Test Plan
A snapshot test has been created.
Draft Checklist
- Snapshot test output isn't totally correct yet. We need to correctly resolving dangling comments at the end of indented bodies.
- A few more edge cases need to be added to ensure that all permutations are accounted for.
- We need to check if there's any other scenarios to report, and whether those need new error messages.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uhh, it seems there are many failing tests. I'm not sure what happened. It doesn't seem like you changed much on the formatter side.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work. You make it look less complicated than it is. There are some perf opportunities and simplifications that we can do to the code. But there are also still a few cases that are not handled correctly which make it difficult to assess if other cases are handled correctly. We should have a look at those.
I played around with it in the playground and found a few cases that need improvement:
def body(): # fmt: off test # fmt: on
test2
The rule reports that the last fmt: on
comment is unnecessary because formatting is already enabled. This is not the case, formatting was disabled
The rule reports that the fmt: off
in the if True
body is unused but that's a valid use.
One check the rule doesn't cover today but I'm okay leaving to an extension is missing fmt: on
comments to re-enable formatting without relying on the automatic re-enabling at the end of a block.
…esolved, particularly with dangling comments.
…ressed and several new problems are now reported. Edge cases involving dangling comments still need to be handled
…comments when determining suppression state
…le checks that need contextual information
ruff-ecosystem
results
Linter (stable)
ℹ️ ecosystem check encountered linter errors. (no lint changes; 1 project error)
indico/indico (error)
ruff failed
Cause: Rule `S410` was removed and cannot be selected.
Linter (preview)
ℹ️ ecosystem check detected linter changes. (+2 -0 violations, +0 -0 fixes in 1 projects; 1 project error; 41 projects unchanged)
DisnakeDev/disnake (+2 -0 violations, +0 -0 fixes)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
- disnake/ext/commands/params.py:481:9: RUF028 This suppression comment is invalid because it cannot be in an expression, pattern, argument list, or other non-statement
- disnake/ext/commands/params.py:498:9: RUF028 This suppression comment is invalid because it cannot be in an expression, pattern, argument list, or other non-statement
indico/indico (error)
ruff check --no-cache --exit-zero --ignore RUF9 --output-format concise --preview
ruff failed
Cause: Rule `S410` was removed and cannot be selected.
Changes by rule (1 rules affected)
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
RUF028 | 2 | 2 | 0 | 0 | 0 |
Formatter (stable)
ℹ️ ecosystem check encountered format errors. (no format changes; 2 project errors)
indico/indico (error)
ruff failed
Cause: Rule `S410` was removed and cannot be selected.
openai/openai-cookbook (error)
warning: Detected debug build without --no-cache.
error: Failed to read examples/How_to_handle_rate_limits.ipynb: Expected a Jupyter Notebook, which must be internally stored as JSON, but this file isn't valid JSON: trailing comma at line 47 column 4
Formatter (preview)
ℹ️ ecosystem check encountered format errors. (no format changes; 2 project errors)
indico/indico (error)
ruff format --preview
ruff failed
Cause: Rule `S410` was removed and cannot be selected.
openai/openai-cookbook (error)
ruff format --preview
warning: Detected debug build without --no-cache.
error: Failed to read examples/How_to_handle_rate_limits.ipynb: Expected a Jupyter Notebook, which must be internally stored as JSON, but this file isn't valid JSON: trailing comma at line 47 column 4
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like how you narrowed down the scope of the rule. This looks good to me. There's one issue around suppression comments in nodes that aren't expressions that we need solving but this is ready otherwise
…mments on function definitions
nkxxll pushed a commit to nkxxll/ruff that referenced this pull request
Fixes astral-sh#6611
Summary
This lint rule spots comments that are intended to suppress or enable the formatter, but will be ignored by the Ruff formatter.
We borrow some functions the formatter uses for determining comment placement / putting them in context within an AST.
The analysis function uses an AST visitor to visit each comment and attach it to the AST. It then uses that context to check:
- Is this comment in an expression?
- Does this comment have bad placement? (e.g. a
# fmt: skip
above a function instead of at the end of a line) - Is this comment redundant?
- Does this comment actually suppress any code?
- Does this comment have ambiguous placement? (e.g. a
# fmt: off
above anelse:
block)
If any of these are true, a violation is thrown. The reported reason
depends on the order of the above check-list: in other words, a # fmt: skip
comment on its own line within a list expression will be reported
as being in an expression, since that reason takes priority.
The lint suggests removing the comment as an unsafe fix, regardless of the reason.
Test Plan
A snapshot test has been created.
Labels
Related to preview mode features
Implementing or modifying a lint rule
2 participants