Skip to content

Commit e5008ca

Browse files
committed
Fix bug where selection included deprecated rules during preview (#9746)
Cherry-picked from #9714 which is being abandoned for now because we need to invest more into our redirection infrastructure before it is feasible. Fixes a bug in the implementation where we improperly included deprecated rules in `RuleSelector.rules()` when preview is on. Includes some clean-up of error messages and the implementation. # Conflicts: # crates/ruff/tests/integration_test.rs
1 parent 85a7edc commit e5008ca

File tree

4 files changed

+36
-33
lines changed

4 files changed

+36
-33
lines changed

crates/ruff/tests/integration_test.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ fn preview_enabled_direct() {
977977

978978
#[test]
979979
fn preview_disabled_direct() {
980-
// RUFF911 is preview not nursery so the selection should be empty
980+
// RUFF911 is preview so we should warn without selecting
981981
let mut cmd = RuffCheck::default()
982982
.args(["--select", "RUF911", "--output-format=concise"])
983983
.build();
@@ -987,7 +987,7 @@ fn preview_disabled_direct() {
987987
----- stdout -----
988988
989989
----- stderr -----
990-
warning: Selection `RUF911` has no effect because the `--preview` flag was not included.
990+
warning: Selection `RUF911` has no effect because preview is not enabled.
991991
"###);
992992
}
993993

@@ -1003,7 +1003,7 @@ fn preview_disabled_prefix_empty() {
10031003
----- stdout -----
10041004
10051005
----- stderr -----
1006-
warning: Selection `RUF91` has no effect because the `--preview` flag was not included.
1006+
warning: Selection `RUF91` has no effect because preview is not enabled.
10071007
"###);
10081008
}
10091009

@@ -1135,11 +1135,13 @@ def reciprocal(n):
11351135
try:
11361136
return 1 / n
11371137
except ZeroDivisionError:
1138-
raise ValueError
1138+
raise ValueError()
11391139
"###), @r###"
1140-
success: true
1141-
exit_code: 0
1140+
success: false
1141+
exit_code: 1
11421142
----- stdout -----
1143+
-:6:9: TRY200 Use `raise from` to specify exception cause
1144+
Found 1 error.
11431145
11441146
----- stderr -----
11451147
warning: Rule `TRY200` is deprecated and will be removed in a future release.
@@ -1212,15 +1214,15 @@ def reciprocal(n):
12121214
try:
12131215
return 1 / n
12141216
except ZeroDivisionError:
1215-
raise ValueError
1217+
raise ValueError()
12161218
"###), @r###"
12171219
success: false
12181220
exit_code: 2
12191221
----- stdout -----
12201222
12211223
----- stderr -----
12221224
ruff failed
1223-
Cause: Selection of deprecated rule `TRY200` is not allowed when preview mode is enabled.
1225+
Cause: Selection of deprecated rule `TRY200` is not allowed when preview is enabled.
12241226
"###);
12251227
}
12261228

@@ -1236,7 +1238,7 @@ def reciprocal(n):
12361238
try:
12371239
return 1 / n
12381240
except ZeroDivisionError:
1239-
raise ValueError
1241+
raise ValueError()
12401242
"###), @r###"
12411243
success: true
12421244
exit_code: 0
@@ -1259,15 +1261,15 @@ def reciprocal(n):
12591261
try:
12601262
return 1 / n
12611263
except ZeroDivisionError:
1262-
raise ValueError
1264+
raise ValueError()
12631265
"###), @r###"
12641266
success: false
12651267
exit_code: 2
12661268
----- stdout -----
12671269
12681270
----- stderr -----
12691271
ruff failed
1270-
Cause: Selection of deprecated rules is not allowed when preview mode is enabled. Remove selection of:
1272+
Cause: Selection of deprecated rules is not allowed when preview is enabled. Remove selection of:
12711273
- ANN102
12721274
- ANN101
12731275

crates/ruff_linter/src/rule_selector.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl Visitor<'_> for SelectorVisitor {
172172
}
173173

174174
impl RuleSelector {
175-
/// Return all matching rules, regardless of whether they're in preview.
175+
/// Return all matching rules, regardless of rule group filters like preview and deprecated.
176176
pub fn all_rules(&self) -> impl Iterator<Item = Rule> + '_ {
177177
match self {
178178
RuleSelector::All => RuleSelectorIter::All(Rule::iter()),
@@ -198,7 +198,7 @@ impl RuleSelector {
198198
}
199199
}
200200

201-
/// Returns rules matching the selector, taking into account preview options enabled.
201+
/// Returns rules matching the selector, taking into account rule groups like preview and deprecated.
202202
pub fn rules<'a>(&'a self, preview: &PreviewOptions) -> impl Iterator<Item = Rule> + 'a {
203203
let preview_enabled = preview.mode.is_enabled();
204204
let preview_require_explicit = preview.require_explicit;
@@ -207,16 +207,21 @@ impl RuleSelector {
207207
// Always include stable rules
208208
rule.is_stable()
209209
// Backwards compatibility allows selection of nursery rules by exact code or dedicated group
210-
|| ((matches!(self, RuleSelector::Rule { .. }) || matches!(self, RuleSelector::Nursery { .. })) && rule.is_nursery())
210+
|| ((self.is_exact() || matches!(self, RuleSelector::Nursery { .. })) && rule.is_nursery())
211211
// Enabling preview includes all preview or nursery rules unless explicit selection
212212
// is turned on
213-
|| (preview_enabled && (matches!(self, RuleSelector::Rule { .. }) || !preview_require_explicit))
213+
|| ((rule.is_preview() || rule.is_nursery()) && preview_enabled && (self.is_exact() || !preview_require_explicit))
214214
// Deprecated rules are excluded in preview mode unless explicitly selected
215-
|| (rule.is_deprecated() && (!preview_enabled || matches!(self, RuleSelector::Rule { .. })))
215+
|| (rule.is_deprecated() && (!preview_enabled || self.is_exact()))
216216
// Removed rules are included if explicitly selected but will error downstream
217-
|| (rule.is_removed() && matches!(self, RuleSelector::Rule { .. }))
217+
|| (rule.is_removed() && self.is_exact())
218218
})
219219
}
220+
221+
/// Returns true if this selector is exact i.e. selects a single rule by code
222+
pub fn is_exact(&self) -> bool {
223+
matches!(self, Self::Rule { .. })
224+
}
220225
}
221226

222227
pub enum RuleSelectorIter {

crates/ruff_linter/src/rules/tryceratops/rules/reraise_no_cause.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::checkers::ast::Checker;
2525
/// try:
2626
/// return 1 / n
2727
/// except ZeroDivisionError:
28-
/// raise ValueError
28+
/// raise ValueError()
2929
/// ```
3030
///
3131
/// Use instead:
@@ -34,7 +34,7 @@ use crate::checkers::ast::Checker;
3434
/// try:
3535
/// return 1 / n
3636
/// except ZeroDivisionError as exc:
37-
/// raise ValueError from exc
37+
/// raise ValueError() from exc
3838
/// ```
3939
///
4040
/// ## References

crates/ruff_workspace/src/configuration.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -902,8 +902,8 @@ impl LintConfiguration {
902902

903903
// Unstable rules
904904
if preview.mode.is_disabled() && kind.is_enable() {
905-
if let RuleSelector::Rule { prefix, .. } = selector {
906-
if prefix.rules().any(|rule| rule.is_nursery()) {
905+
if selector.is_exact() {
906+
if selector.all_rules().all(|rule| rule.is_nursery()) {
907907
deprecated_nursery_selectors.insert(selector);
908908
}
909909
}
@@ -915,17 +915,15 @@ impl LintConfiguration {
915915
}
916916

917917
// Deprecated rules
918-
if kind.is_enable() {
919-
if let RuleSelector::Rule { prefix, .. } = selector {
920-
if prefix.rules().any(|rule| rule.is_deprecated()) {
921-
deprecated_selectors.insert(selector);
922-
}
918+
if kind.is_enable() && selector.is_exact() {
919+
if selector.all_rules().all(|rule| rule.is_deprecated()) {
920+
deprecated_selectors.insert(selector.clone());
923921
}
924922
}
925923

926924
// Removed rules
927-
if let RuleSelector::Rule { prefix, .. } = selector {
928-
if prefix.rules().any(|rule| rule.is_removed()) {
925+
if selector.is_exact() {
926+
if selector.all_rules().all(|rule| rule.is_removed()) {
929927
removed_selectors.insert(selector);
930928
}
931929
}
@@ -1007,10 +1005,10 @@ impl LintConfiguration {
10071005
[] => (),
10081006
[selection] => {
10091007
let (prefix, code) = selection.prefix_and_code();
1010-
return Err(anyhow!("Selection of deprecated rule `{prefix}{code}` is not allowed when preview mode is enabled."));
1008+
return Err(anyhow!("Selection of deprecated rule `{prefix}{code}` is not allowed when preview is enabled."));
10111009
}
10121010
[..] => {
1013-
let mut message = "Selection of deprecated rules is not allowed when preview mode is enabled. Remove selection of:".to_string();
1011+
let mut message = "Selection of deprecated rules is not allowed when preview is enabled. Remove selection of:".to_string();
10141012
for selection in deprecated_selectors {
10151013
let (prefix, code) = selection.prefix_and_code();
10161014
message.push_str("\n\t- ");
@@ -1025,9 +1023,7 @@ impl LintConfiguration {
10251023

10261024
for selection in ignored_preview_selectors {
10271025
let (prefix, code) = selection.prefix_and_code();
1028-
warn_user!(
1029-
"Selection `{prefix}{code}` has no effect because the `--preview` flag was not included.",
1030-
);
1026+
warn_user!("Selection `{prefix}{code}` has no effect because preview is not enabled.",);
10311027
}
10321028

10331029
let mut rules = RuleTable::empty();

0 commit comments

Comments
 (0)