diff --git a/crates/ruff/tests/integration_test.rs b/crates/ruff/tests/integration_test.rs index 6a0fde5a2b65f..864df1f2b8804 100644 --- a/crates/ruff/tests/integration_test.rs +++ b/crates/ruff/tests/integration_test.rs @@ -824,7 +824,9 @@ fn nursery_prefix() { -:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix. -:1:1: RUF902 Hey this is a stable test rule with an unsafe fix. -:1:1: RUF903 Hey this is a stable test rule with a display only fix. - Found 4 errors. + -:1:1: RUF920 Hey this is a deprecated test rule. + -:1:1: RUF921 Hey this is another deprecated test rule. + Found 6 errors. [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). ----- stderr ----- @@ -846,7 +848,9 @@ fn nursery_all() { -:1:1: RUF901 [*] Hey this is a stable test rule with a safe fix. -:1:1: RUF902 Hey this is a stable test rule with an unsafe fix. -:1:1: RUF903 Hey this is a stable test rule with a display only fix. - Found 5 errors. + -:1:1: RUF920 Hey this is a deprecated test rule. + -:1:1: RUF921 Hey this is another deprecated test rule. + Found 7 errors. [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). ----- stderr ----- @@ -1094,7 +1098,7 @@ fn preview_enabled_group_ignore() { #[test] fn removed_direct() { // Selection of a removed rule should fail - let mut cmd = RuffCheck::default().args(["--select", "PLR1706"]).build(); + let mut cmd = RuffCheck::default().args(["--select", "RUF931"]).build(); assert_cmd_snapshot!(cmd, @r###" success: false exit_code: 2 @@ -1102,7 +1106,28 @@ fn removed_direct() { ----- stderr ----- ruff failed - Cause: Rule `PLR1706` was removed and cannot be selected. + Cause: Rule `RUF931` was removed and cannot be selected. + "###); +} + +#[test] +fn removed_direct_multiple() { + // Selection of multiple removed rule should fail with a message + // including all the rules + let mut cmd = RuffCheck::default() + .args(["--select", "RUF930", "--select", "RUF931"]) + .build(); + assert_cmd_snapshot!(cmd, @r###" + success: false + exit_code: 2 + ----- stdout ----- + + ----- stderr ----- + ruff failed + Cause: The following rules have been removed and cannot be selected: + - RUF930 + - RUF931 + "###); } @@ -1110,12 +1135,8 @@ fn removed_direct() { fn removed_indirect() { // Selection _including_ a removed rule without matching should not fail // nor should the rule be used - let mut cmd = RuffCheck::default().args(["--select", "PLR"]).build(); - assert_cmd_snapshot!(cmd.pass_stdin(r###" -# This would have been a PLR1706 violation -x, y = 1, 2 -maximum = x >= y and x or y -"""###), @r###" + let mut cmd = RuffCheck::default().args(["--select", "RUF93"]).build(); + assert_cmd_snapshot!(cmd, @r###" success: true exit_code: 0 ----- stdout ----- @@ -1128,74 +1149,49 @@ maximum = x >= y and x or y fn deprecated_direct() { // Selection of a deprecated rule without preview enabled should still work // but a warning should be displayed - let mut cmd = RuffCheck::default().args(["--select", "TRY200"]).build(); - assert_cmd_snapshot!(cmd - .pass_stdin(r###" -def reciprocal(n): - try: - return 1 / n - except ZeroDivisionError: - raise ValueError() -"###), @r###" + let mut cmd = RuffCheck::default().args(["--select", "RUF920"]).build(); + assert_cmd_snapshot!(cmd, @r###" success: false exit_code: 1 ----- stdout ----- - -:6:9: TRY200 Use `raise from` to specify exception cause + -:1:1: RUF920 Hey this is a deprecated test rule. Found 1 error. ----- stderr ----- - warning: Rule `TRY200` is deprecated and will be removed in a future release. + warning: Rule `RUF920` is deprecated and will be removed in a future release. "###); } #[test] fn deprecated_multiple_direct() { let mut cmd = RuffCheck::default() - .args(["--select", "ANN101", "--select", "ANN102"]) + .args(["--select", "RUF920", "--select", "RUF921"]) .build(); - assert_cmd_snapshot!(cmd - .pass_stdin(r###" -class Foo: - def a(self): - pass - - @classmethod - def b(cls): - pass -"###), @r###" + assert_cmd_snapshot!(cmd, @r###" success: false exit_code: 1 ----- stdout ----- - -:3:11: ANN101 Missing type annotation for `self` in method - -:7:11: ANN102 Missing type annotation for `cls` in classmethod + -:1:1: RUF920 Hey this is a deprecated test rule. + -:1:1: RUF921 Hey this is another deprecated test rule. Found 2 errors. ----- stderr ----- - warning: Rule `ANN102` is deprecated and will be removed in a future release. - warning: Rule `ANN101` is deprecated and will be removed in a future release. + warning: Rule `RUF921` is deprecated and will be removed in a future release. + warning: Rule `RUF920` is deprecated and will be removed in a future release. "###); } #[test] fn deprecated_indirect() { - // `ANN` includes deprecated rules `ANN101` and `ANN102` but should not warn + // `RUF92` includes deprecated rules but should not warn // since it is not a "direct" selection - let mut cmd = RuffCheck::default().args(["--select", "ANN1"]).build(); - assert_cmd_snapshot!(cmd - .pass_stdin(r###" -class Foo: - def a(self): - pass - - @classmethod - def b(cls): - pass -"###), @r###" + let mut cmd = RuffCheck::default().args(["--select", "RUF92"]).build(); + assert_cmd_snapshot!(cmd, @r###" success: false exit_code: 1 ----- stdout ----- - -:3:11: ANN101 Missing type annotation for `self` in method - -:7:11: ANN102 Missing type annotation for `cls` in classmethod + -:1:1: RUF920 Hey this is a deprecated test rule. + -:1:1: RUF921 Hey this is another deprecated test rule. Found 2 errors. ----- stderr ----- @@ -1206,40 +1202,26 @@ class Foo: fn deprecated_direct_preview_enabled() { // Direct selection of a deprecated rule in preview should fail let mut cmd = RuffCheck::default() - .args(["--select", "TRY200", "--preview"]) + .args(["--select", "RUF920", "--preview"]) .build(); - assert_cmd_snapshot!(cmd - .pass_stdin(r###" -def reciprocal(n): - try: - return 1 / n - except ZeroDivisionError: - raise ValueError() -"###), @r###" + assert_cmd_snapshot!(cmd, @r###" success: false exit_code: 2 ----- stdout ----- ----- stderr ----- ruff failed - Cause: Selection of deprecated rule `TRY200` is not allowed when preview is enabled. + Cause: Selection of deprecated rule `RUF920` is not allowed when preview is enabled. "###); } #[test] fn deprecated_indirect_preview_enabled() { - // `TRY200` is deprecated and should be off by default in preview. + // `RUF920` is deprecated and should be off by default in preview. let mut cmd = RuffCheck::default() - .args(["--select", "TRY", "--preview"]) + .args(["--select", "RUF92", "--preview"]) .build(); - assert_cmd_snapshot!(cmd - .pass_stdin(r###" -def reciprocal(n): - try: - return 1 / n - except ZeroDivisionError: - raise ValueError() -"###), @r###" + assert_cmd_snapshot!(cmd, @r###" success: true exit_code: 0 ----- stdout ----- @@ -1253,16 +1235,9 @@ fn deprecated_multiple_direct_preview_enabled() { // Direct selection of the deprecated rules in preview should fail with // a message listing all of the rule codes let mut cmd = RuffCheck::default() - .args(["--select", "ANN101", "--select", "ANN102", "--preview"]) + .args(["--select", "RUF920", "--select", "RUF921", "--preview"]) .build(); - assert_cmd_snapshot!(cmd - .pass_stdin(r###" -def reciprocal(n): - try: - return 1 / n - except ZeroDivisionError: - raise ValueError() -"###), @r###" + assert_cmd_snapshot!(cmd, @r###" success: false exit_code: 2 ----- stdout ----- @@ -1270,8 +1245,8 @@ def reciprocal(n): ----- stderr ----- ruff failed Cause: Selection of deprecated rules is not allowed when preview is enabled. Remove selection of: - - ANN102 - - ANN101 + - RUF921 + - RUF920 "###); } @@ -1793,7 +1768,9 @@ extend-safe-fixes = ["RUF9"] -:1:1: RUF901 Hey this is a stable test rule with a safe fix. -:1:1: RUF902 [*] Hey this is a stable test rule with an unsafe fix. -:1:1: RUF903 Hey this is a stable test rule with a display only fix. - Found 4 errors. + -:1:1: RUF920 Hey this is a deprecated test rule. + -:1:1: RUF921 Hey this is another deprecated test rule. + Found 6 errors. [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). ----- stderr ----- diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 6ba3d90e664bc..e54d7eff4f592 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -951,6 +951,14 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { #[cfg(feature = "test-rules")] #[allow(deprecated)] (Ruff, "912") => (RuleGroup::Nursery, rules::ruff::rules::NurseryTestRule), + #[cfg(feature = "test-rules")] + (Ruff, "920") => (RuleGroup::Deprecated, rules::ruff::rules::DeprecatedTestRule), + #[cfg(feature = "test-rules")] + (Ruff, "921") => (RuleGroup::Deprecated, rules::ruff::rules::AnotherDeprecatedTestRule), + #[cfg(feature = "test-rules")] + (Ruff, "930") => (RuleGroup::Removed, rules::ruff::rules::RemovedTestRule), + #[cfg(feature = "test-rules")] + (Ruff, "931") => (RuleGroup::Removed, rules::ruff::rules::AnotherRemovedTestRule), // flake8-django diff --git a/crates/ruff_linter/src/linter.rs b/crates/ruff_linter/src/linter.rs index 003edc4446198..0ce297b596481 100644 --- a/crates/ruff_linter/src/linter.rs +++ b/crates/ruff_linter/src/linter.rs @@ -236,6 +236,16 @@ pub fn check_path( } Rule::NurseryTestRule => test_rules::NurseryTestRule::diagnostic(locator, indexer), Rule::PreviewTestRule => test_rules::PreviewTestRule::diagnostic(locator, indexer), + Rule::DeprecatedTestRule => { + test_rules::DeprecatedTestRule::diagnostic(locator, indexer) + } + Rule::AnotherDeprecatedTestRule => { + test_rules::AnotherDeprecatedTestRule::diagnostic(locator, indexer) + } + Rule::RemovedTestRule => test_rules::RemovedTestRule::diagnostic(locator, indexer), + Rule::AnotherRemovedTestRule => { + test_rules::AnotherRemovedTestRule::diagnostic(locator, indexer) + } _ => unreachable!("All test rules must have an implementation"), }; if let Some(diagnostic) = diagnostic { diff --git a/crates/ruff_linter/src/rules/ruff/rules/test_rules.rs b/crates/ruff_linter/src/rules/ruff/rules/test_rules.rs index 5a78526f663dc..f846f9ff3aaee 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/test_rules.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/test_rules.rs @@ -39,6 +39,10 @@ pub(crate) const TEST_RULES: &[Rule] = &[ Rule::StableTestRuleDisplayOnlyFix, Rule::PreviewTestRule, Rule::NurseryTestRule, + Rule::DeprecatedTestRule, + Rule::AnotherDeprecatedTestRule, + Rule::RemovedTestRule, + Rule::AnotherRemovedTestRule, ]; pub(crate) trait TestRule { @@ -254,6 +258,7 @@ impl TestRule for PreviewTestRule { )) } } + /// ## What it does /// Fake rule for testing. /// @@ -289,3 +294,147 @@ impl TestRule for NurseryTestRule { )) } } + +/// ## What it does +/// Fake rule for testing. +/// +/// ## Why is this bad? +/// Tests must pass! +/// +/// ## Example +/// ```python +/// foo +/// ``` +/// +/// Use instead: +/// ```python +/// bar +/// ``` +#[violation] +pub struct DeprecatedTestRule; + +impl Violation for DeprecatedTestRule { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::None; + + #[derive_message_formats] + fn message(&self) -> String { + format!("Hey this is a deprecated test rule.") + } +} + +impl TestRule for DeprecatedTestRule { + fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option { + Some(Diagnostic::new( + DeprecatedTestRule, + ruff_text_size::TextRange::default(), + )) + } +} + +/// ## What it does +/// Fake rule for testing. +/// +/// ## Why is this bad? +/// Tests must pass! +/// +/// ## Example +/// ```python +/// foo +/// ``` +/// +/// Use instead: +/// ```python +/// bar +/// ``` +#[violation] +pub struct AnotherDeprecatedTestRule; + +impl Violation for AnotherDeprecatedTestRule { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::None; + + #[derive_message_formats] + fn message(&self) -> String { + format!("Hey this is another deprecated test rule.") + } +} + +impl TestRule for AnotherDeprecatedTestRule { + fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option { + Some(Diagnostic::new( + AnotherDeprecatedTestRule, + ruff_text_size::TextRange::default(), + )) + } +} + +/// ## What it does +/// Fake rule for testing. +/// +/// ## Why is this bad? +/// Tests must pass! +/// +/// ## Example +/// ```python +/// foo +/// ``` +/// +/// Use instead: +/// ```python +/// bar +/// ``` +#[violation] +pub struct RemovedTestRule; + +impl Violation for RemovedTestRule { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::None; + + #[derive_message_formats] + fn message(&self) -> String { + format!("Hey this is a removed test rule.") + } +} + +impl TestRule for RemovedTestRule { + fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option { + Some(Diagnostic::new( + RemovedTestRule, + ruff_text_size::TextRange::default(), + )) + } +} + +/// ## What it does +/// Fake rule for testing. +/// +/// ## Why is this bad? +/// Tests must pass! +/// +/// ## Example +/// ```python +/// foo +/// ``` +/// +/// Use instead: +/// ```python +/// bar +/// ``` +#[violation] +pub struct AnotherRemovedTestRule; + +impl Violation for AnotherRemovedTestRule { + const FIX_AVAILABILITY: FixAvailability = FixAvailability::None; + + #[derive_message_formats] + fn message(&self) -> String { + format!("Hey this is a another removed test rule.") + } +} + +impl TestRule for AnotherRemovedTestRule { + fn diagnostic(_locator: &Locator, _indexer: &Indexer) -> Option { + Some(Diagnostic::new( + AnotherRemovedTestRule, + ruff_text_size::TextRange::default(), + )) + } +} diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index 1014a32c4acf6..4bb0996f81da3 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -909,7 +909,15 @@ impl LintConfiguration { } // Check if the selector is empty because preview mode is disabled - if selector.rules(&PreviewOptions::default()).next().is_none() { + if selector.rules(&preview).next().is_none() + && selector + .rules(&PreviewOptions { + mode: PreviewMode::Enabled, + require_explicit: preview.require_explicit, + }) + .next() + .is_some() + { ignored_preview_selectors.insert(selector); } }