Skip to content

Allow human-readable names in rule selectors - #25887

Merged
ntBre merged 7 commits into
mainfrom
brent/human-readable-selectors
Jun 25, 2026
Merged

Allow human-readable names in rule selectors#25887
ntBre merged 7 commits into
mainfrom
brent/human-readable-selectors

Conversation

@ntBre

@ntBre ntBre commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR enables using rule names as selectors in preview by also attempting to parse a selector as a human-readable name in UnresolvedRuleSelector::resolve. If this succeeds and preview is enabled, the rule is activated, and if preview is disabled you get a custom error message.

Test Plan

A few new CLI tests. I figured the tests from #26113 cover the shared behavior for the other selectors well enough and just focused on select as an example for both the CLI and config file.

@ntBre ntBre added preview Related to preview mode features rule-selection Related to enabling or disabling rules labels Jun 11, 2026
@astral-sh-bot

astral-sh-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Comment thread crates/ruff_linter/src/settings/types.rs Outdated
@ntBre
ntBre marked this pull request as ready for review June 12, 2026 16:01
@ntBre
ntBre requested a review from MichaReiser June 12, 2026 16:02

@MichaReiser MichaReiser left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm leaning towards splitting this PR and I even suggest to go one step further than what you did, by fully deferring rule parsing.

ty accepts all rule names on the CLI or in configurations. They're only validated when turning the configuration into a settings struct and ty emits a warning for every unknown rule.

#14443 is a ruff issue that asks for the same.

That's why I wonder what it would mean if we fix #14443 first by using an UnresolvedRuleName(String, source?) and only parse the rule to a RuleSelector in into_settings. I believe this should also allow you to merge the RuleSelector::Rule variants again.

Do you want to give this a try. I'm sure there's something that will make this unreasonably hard :)

@ntBre

ntBre commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

Sure, I can give that a try!

@ntBre
ntBre marked this pull request as draft June 15, 2026 13:59
ntBre added a commit that referenced this pull request Jun 24, 2026
Summary
--

This PR fixes #14443 by deferring rule parsing. This allows
deserializing configuration files and
CLI arguments with unknown rule selectors and enables us to emit a
warning instead of a hard error
when encountering an unknown selector. This will also help with #25887
because we can also defer
parsing until we have an accurate `preview` setting for checking whether
human-readable names should
be allowed. I've left some of this infrastructure in place in this PR,
with the `preview` argument
currently unused.

Test Plan
--

Existing tests updated to show warnings instead of errors
ntBre added 4 commits June 24, 2026 15:34
check preview in other cases

warn everywhere

test all the flags

tidy

link to this pr on preview feature

the per-file-ignore changes especially should be fully reverted
@ntBre
ntBre force-pushed the brent/human-readable-selectors branch from 9d4018f to 672f9b6 Compare June 24, 2026 20:22

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.

This is not strictly necessary, it just gives a nicer conversion than this awkward parsing round trip from the previous commit:

if is_human_readable_names_enabled(preview) {
return Ok(RuleSelector::from_str(&rule.noqa_code().to_string()).unwrap());
}

Comment thread docs/linter.md
Comment on lines +144 to +145
When [preview mode](preview.md) is enabled, rule selectors also accept the human-readable name of a
rule (e.g., `unused-import`).

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.

Codex wanted to make this much more prominent in the CLI and other docs, but I thought that seemed a bit premature and that this was a better starting point.

@ntBre
ntBre marked this pull request as ready for review June 24, 2026 20:34
@ntBre
ntBre requested a review from MichaReiser June 24, 2026 20:37

@MichaReiser MichaReiser left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice, this looks much "simpler" now.

I suggest we change RuleSelector::Rule to store a rule now, where we already resolve it anyway.

Do we need to update options.rs and mention that human-readable names are now accepted in many places under preview?

Comment thread crates/ruff_macros/src/map_codes.rs Outdated
Comment on lines +299 to +302
let prefix = get_prefix_ident(&code.value());
rule_selector_match_arms.extend(quote! {
#(#attrs)* Rule::#rule_name => RuleCodePrefix::#linter(#linter::#prefix),
});

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Instead of adding another match over all codes, could we change RuleSelector::Rule to store a Rule instead? I'm not sure what the reason was originally for storing only the selector prefix. But it might just have been because we used RuleSelector for deserialization, which we now no longer do.

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.

Yeah, this was very doable. Thanks!

Comment thread crates/ruff/tests/cli/lint.rs Outdated

----- stderr -----
ruff failed
Cause: Rule name `unused-import` used as selector with preview disabled in `select` from [TMP]/ruff.toml

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Cause: Rule name `unused-import` used as selector with preview disabled in `select` from [TMP]/ruff.toml
Cause: Rule name `unused-import` used as selector with preview disabled in `select` from `[TMP]/ruff.toml`

Comment thread crates/ruff/tests/cli/lint.rs Outdated

----- stderr -----
ruff failed
Cause: Rule name `unused-import` used as selector with preview disabled in `select` from the CLI

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I find this a bit hard to understand. Maybe something like? Invalid --select unused-import. Selecting rules by their name requires enabling preview mode.

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 like the look of --select unused-import, but I don't think we can use --select since we also consider --config select=... as coming from the CLI. I like moving the preview part to the end, though. I went with:

Invalid selector `unused-import` in `select` from the CLI. Selecting rules by name requires preview mode

@ntBre

ntBre commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Do we need to update options.rs and mention that human-readable names are now accepted in many places under preview?

As I mentioned in my review comment, I thought it might be better to leave this out for now in favor of the single linter.md callout since it requires a lot of awkward "in preview" phrasing. I'm happy to do it if you prefer, though. I do want users to know about it.

@ntBre
ntBre merged commit f703f21 into main Jun 25, 2026
76 of 77 checks passed
@ntBre
ntBre deleted the brent/human-readable-selectors branch June 25, 2026 15:34
charliermarsh pushed a commit that referenced this pull request Jun 25, 2026
Summary
--

I didn't think to rebase #26240 after merging #25887 and there was a
conflict in the schema. This should fix the current failure on main.

Test Plan
--

CI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Related to preview mode features rule-selection Related to enabling or disabling rules

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants