Skip to content

Allow selecting rules with severity warning in preview#23846

Draft
dylwil3 wants to merge 10 commits intomainfrom
dylan/warnings
Draft

Allow selecting rules with severity warning in preview#23846
dylwil3 wants to merge 10 commits intomainfrom
dylan/warnings

Conversation

@dylwil3
Copy link
Collaborator

@dylwil3 dylwil3 commented Mar 9, 2026

This PR allows users to specify a set of rules to enable with severity level warning (in preview).

They may do so in the CLI using --warn and --extend-warn or in a configuration file via

[lint]
warn = [ ... ]

Closes #1256

Details on Resolving the Configuration

The precedence between select and ignore, within a configuration file, is as follows:

  1. More specific designations take precedence over less specific, e.g. --warn F --select F401 will give all Pyflakes diagnostics except F401 a severity of warning, and give F401 a severity of error.
  2. Between designations of equal specificity, warn takes precedence over select, e.g. --select F401 --warn F401 will resolve to --warn F401.

As in the case of select vs extend-select, specifying warn = [...] will overwrite any inherited configuration for warn. However, it will not overwrite an inherited configuration for select.

For example,

ruff check --warn ARG ex.py

will return diagnostics for all default rules with error severity and then also the ARG rules with severity warning.

In order to warn on a single rule, the user has to do something like this:

ruff check --select ARG --warn ARG ex.py

which looks a bit funny.

@dylwil3 dylwil3 added configuration Related to settings and configuration cli Related to the command-line interface preview Related to preview mode features labels Mar 9, 2026
@astral-sh-bot
Copy link

astral-sh-bot bot commented Mar 9, 2026

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@dylwil3 dylwil3 force-pushed the dylan/warnings branch 2 times, most recently from 7e2e587 to 7c9514a Compare March 13, 2026 14:17
@dylwil3 dylwil3 force-pushed the dylan/output-severity branch from 33fdbb8 to cb221a4 Compare March 13, 2026 14:18
@dylwil3 dylwil3 force-pushed the dylan/warnings branch 2 times, most recently from fd38c83 to 42d047a Compare March 13, 2026 14:27
@dylwil3 dylwil3 force-pushed the dylan/output-severity branch from cb221a4 to e11289c Compare March 13, 2026 14:43
dylwil3 added a commit that referenced this pull request Mar 13, 2026
This is just the "aesthetic" part of implementing `warning` severities.
Configuration changes are in
#23846

It's expected that the `preview` ecosystem check times out here.
Base automatically changed from dylan/output-severity to main March 13, 2026 14:56
@dylwil3 dylwil3 force-pushed the dylan/warnings branch 8 times, most recently from 16f5460 to cd03169 Compare March 13, 2026 21:14
Comment on lines +376 to +380
{
warn_user_once!(
"Enabling rules with severity 'warning' requires preview mode, otherwise all rules are interpreted with severity 'error'."
);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'd love feedback on whether or not this should be the behavior when preview is not enabled. Another option would be to interpret everything "correctly" but just warn the user that severities are in preview and experimental.

If we do like the idea of interpreting these as error there's some other design questions... for example, at the moment with preview disabled it will still "correctly" populate lint.warn if you do --show-settings. Is that we want?

Comment on lines 12 to 15
/// Maps rule codes to a boolean indicating if the rule should be fixed.
enabled: RuleSet,
warn: RuleSet,
should_fix: RuleSet,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think I'm implicitly assuming that warn is a subset of enabled. I believe this invariant is ensured because the public methods that mess with these fields do the right thing (e.g. RuleTable::warn below). But let me know if there's a better way to enforce this / organize this...

Copy link
Member

Choose a reason for hiding this comment

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

This makes sense to me.

Comment on lines +927 to +935
// Override warnings of weaker specificity
// For example:
// ```
// select = ["F401"]
// warn = ["F"]
// ```
// should warn on all Pyflakes rules
// except for `F401` where it should error.
warn_map_updates.insert(rule, false);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This prevents a bunch of the strange behavior we brought up in design discussions.

@dylwil3
Copy link
Collaborator Author

dylwil3 commented Mar 13, 2026

I think this is ready for the first round of review. Probably most important is to see:

  1. If we want any behavior changes compared to what you see in the CLI snapshots, and
  2. If we want to modify how this is gated behind preview.
  3. If there are any scenarios we want to add tests for.

Of course suggestions on improving the actual implementation are also welcome!

@dylwil3 dylwil3 changed the title [WIP] Allow selecting rules with severity warning in preview Allow selecting rules with severity warning in preview Mar 13, 2026
@dylwil3 dylwil3 marked this pull request as ready for review March 13, 2026 21:19
Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

I skimmed over the CLI tests and most output does make sense. I do think that the schema overall is a bit complicated to grasp what's going on, especially if nested configurations come into play. It's also easier to accidentially list a rule twice.

I wonder if we should take a step back and discuss how we want to role out human-readable names. For example, we could use the absence of select, extend-select, ignore and extend-ignore as opt-in to human readable names so that Ruff keeps using rule-codes in its output unless a user opted in to the new configuration (because they don't have a configuration or don't select any rules or use the new configuration schema).

What would be interesting to understand is if there are cases where we think a rule-table is less intuitive than todays select/warn/ignore.

success: false
exit_code: 1
----- stdout -----
try.py:1:8: error[F401] [*] `os` imported but unused
Copy link
Member

Choose a reason for hiding this comment

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

We should also test that some other F rule now has warning severity

----- stderr -----
"###
);
Ok(())
Copy link
Member

Choose a reason for hiding this comment

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

Can you add some more tests demonstrating:

  • extend-* combinations. Especially combinations of extend- and non-extend configurations
  • How select behaves when there are rules that default to warning severity.

Comment on lines 12 to 15
/// Maps rule codes to a boolean indicating if the rule should be fixed.
enabled: RuleSet,
warn: RuleSet,
should_fix: RuleSet,
Copy link
Member

Choose a reason for hiding this comment

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

This makes sense to me.

r#"
[lint]
preview = true
select = ["F401"]
Copy link
Member

Choose a reason for hiding this comment

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

Can you add a test that demonstrates the opposite: The outer configuration warning about F401 and the nested configuration selecting F401

@MichaReiser
Copy link
Member

I hope it's okay if I put this back to draft or is there something you want feedback on?

@MichaReiser MichaReiser marked this pull request as draft March 26, 2026 07:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli Related to the command-line interface configuration Related to settings and configuration preview Related to preview mode features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: Support a "warning" level for linting

4 participants