-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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 and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Invalid rule provided
as rule RUF102 with --fix
#17138
Conversation
|
code | total | + violation | - violation | + fix | - fix |
---|---|---|---|---|---|
RUF102 | 2 | 2 | 0 | 0 | 0 |
Sorry for the CI issues, I thought that clippy runs with checking the pre-commit hooks.
|
); | ||
|
||
let original_text = locator.slice(line.range()); | ||
if let Some(comment_start) = original_text.find('#') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work with # test # noqa: invalid
? Could we use line.directive.range
(assuming directive
is the Codes
variant) here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the directive suggestion. It's much cleaner (adressed in f7014db).
Regarding multiple comments on a line it removes the invalid parts
# test # noqa: INVALID111
→# test
# test # noqa: INVALID111, VALID111
→# test # noqa: VALID111
I've added tests for this in 5cc8305.
I guess this is the desired behaviour. Having stale comments isn't nice, but auto removing ones that should stay is worse. What do you think.
Note: I'm writing it with uppercase ASCII plus a number because otherwise it's not parsed as a rule code; in this case the comment remains untouched.
@@ -314,6 +315,20 @@ mod tests { | |||
Ok(()) | |||
} | |||
|
|||
#[test] | |||
fn ruf102() -> Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIt:
fn ruf102() -> Result<()> { | |
fn invalid_rule_code_external_rules() -> Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adressed in 3050304
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for incorporating external. This mostly looks good. The main thing we've to figure out is how to handle noqa comments where more than one code is invalid. Maybe @dylwil3 has an opinion on this?
/// ```python | ||
/// import os # noqa: E402 | ||
/// ``` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adressed in 2fe49fb
let invalid_codes = directive | ||
.iter() | ||
.map(crate::noqa::Code::as_str) | ||
.collect::<Vec<_>>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we reuse the collected invalid_code_refs
and pass them to this function instead of collecting them again?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to loop over the directive
if we want to preserve the total order rule with only filtering codes for single code fixes.
for invalid_code in invalid_codes { | ||
let mut diagnostic = Diagnostic::new( | ||
InvalidRuleCode { | ||
rule_code: invalid_code.as_str().to_string(), | ||
}, | ||
invalid_code.range(), | ||
); | ||
|
||
diagnostic.set_fix(fix.clone()); | ||
diagnostics.push(diagnostic); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And another case for multispan diagnostics...
I think I'd be surprised that applying the fix for a specific code replaces all invalid codes and not just the one where I positioned my cursor on.
That's why I think we should either:
- Only create one diagnostic that fixes all invalid codes at once (multispan diagnostics would be great)
- Create a diagnostic for each invalid code, the fix only removes that one code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure what you mean by multispan diagnostics or what the exact requirements are. Is that already established in Ruff or something you plan on integrating.
In 921f066 i fixed the handling to create one diagnostic for each invalid code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm unsure what you mean by multispan diagnostics or what the exact requirements are. Is that already established in Ruff or something you plan on integrating.
Sorry, it's something we plan on implementing. This was mainly directed at @ntBre
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sorry I should have acknowledged and resolved this. I'm keeping a list of places to use multispan diagnostics once they're added to Ruff!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could create a tracking issue for it which can then be referenced by the reviewers and the references itself becomes a list of known places which can be improved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yes, of course!
|
This comment was marked as resolved.
This comment was marked as resolved.
after changing the test name
We previously accepted reordering of the codes which is not desirable. also added a test for a succeeding comment.
* main: [red-knot] Empty tuple is always-falsy (#17213) Run fuzzer with `--preview` (#17210) Bump 0.11.4 (#17212) [syntax-errors] Allow `yield` in base classes and annotations (#17206) Don't skip visiting non-tuple slice in `typing.Annotated` subscripts (#17201) [red-knot] mypy_primer: do not specify Python version (#17200) [red-knot] Add `Type.definition` method (#17153) Implement `Invalid rule provided` as rule RUF102 with `--fix` (#17138) [red-knot] Add basic on-hover to playground and LSP (#17057) [red-knot] don't remove negations when simplifying constrained typevars (#17189) [minor] Fix extra semicolon for clippy (#17188) [syntax-errors] Invalid syntax in annotations (#17101) [syntax-errors] Duplicate attributes in match class pattern (#17186) [syntax-errors] Fix multiple assignment for class keyword argument (#17184) use astral-sh/cargo-dist instead (#17187) Enable overindented docs lint (#17182)
Thanks for merging @MichaReiser ! If you have the bandwith, I would love a short explanation on your rationale in e1998a1 (no worries if not). I agree that it reads much nicer, so I'm curious if you have any tips / resources on how you think about intended changes so i can deliver more quality out of the gate :) |
Closes #17084
Summary
This PR adds a new rule (RUF102) to detect and fix invalid rule codes in
noqa
comments.Invalid rule codes in
noqa
directives serve no purpose and may indicate outdated code suppressions.This extends the previous behaviour originating from
crates/ruff_linter/src/noqa.rs
which would only emit a warnigs.With this rule a
--fix
is available.The rule:
noqa
directives to identify invalid rule codesExample cases:
# noqa: XYZ111
→ Remove entire comment (keep empty line)# noqa: XYZ222, XYZ333
→ Remove entire comment (keep empty line)# noqa: F401, INVALID123
→ Keep only valid codes (# noqa: F401
)Test Plan
crates/ruff_linter/resources/test/fixtures/ruff/RUF102.py
covering different example cases.Notes
# noqa: NON_EXISTENT, ANOTHER_INVALID
causes aLexicalError
and the diagnostic is not propagated and we cannot handle the diagnostic. I am also unsure what properfix
handling would be and making the user aware we don't understand the codes is probably the best bet.Questions