diff --git a/crates/ruff/src/commands/rule.rs b/crates/ruff/src/commands/rule.rs index 9a14f180e4e87..0b0c1ca840788 100644 --- a/crates/ruff/src/commands/rule.rs +++ b/crates/ruff/src/commands/rule.rs @@ -36,7 +36,7 @@ impl<'a> Explanation<'a> { message_formats: rule.message_formats(), fix, explanation: rule.explanation(), - preview: rule.is_preview() || rule.is_nursery(), + preview: rule.is_preview(), } } } @@ -62,7 +62,7 @@ fn format_rule_text(rule: Rule) -> String { output.push('\n'); } - if rule.is_preview() || rule.is_nursery() { + if rule.is_preview() { output.push_str( r"This rule is in preview and is not stable. The `--preview` flag is required for use.", ); diff --git a/crates/ruff/tests/integration_test.rs b/crates/ruff/tests/integration_test.rs index 60abf067cac99..b86abe90ea31f 100644 --- a/crates/ruff/tests/integration_test.rs +++ b/crates/ruff/tests/integration_test.rs @@ -889,111 +889,6 @@ fn show_statistics_json() { "###); } -#[test] -fn nursery_prefix() { - // Should only detect RUF90X, but not the unstable test rules - let mut cmd = RuffCheck::default() - .args(["--select", "RUF9", "--output-format=concise"]) - .build(); - assert_cmd_snapshot!(cmd, @r###" - success: false - exit_code: 1 - ----- stdout ----- - -:1:1: RUF900 Hey this is a stable test rule. - -: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. - -:1:1: RUF920 Hey this is a deprecated test rule. - -:1:1: RUF921 Hey this is another deprecated test rule. - -:1:1: RUF950 Hey this is a test rule that was redirected from another. - Found 7 errors. - [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). - - ----- stderr ----- - "###); -} - -#[test] -fn nursery_all() { - // Should detect RUF90X, but not the unstable test rules - let mut cmd = RuffCheck::default() - .args(["--select", "ALL", "--output-format=concise"]) - .build(); - assert_cmd_snapshot!(cmd, @r###" - success: false - exit_code: 1 - ----- stdout ----- - -:1:1: D100 Missing docstring in public module - -:1:1: RUF900 Hey this is a stable test rule. - -: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. - -:1:1: RUF920 Hey this is a deprecated test rule. - -:1:1: RUF921 Hey this is another deprecated test rule. - -:1:1: RUF950 Hey this is a test rule that was redirected from another. - Found 8 errors. - [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). - - ----- stderr ----- - warning: `one-blank-line-before-class` (D203) and `no-blank-line-before-class` (D211) are incompatible. Ignoring `one-blank-line-before-class`. - warning: `multi-line-summary-first-line` (D212) and `multi-line-summary-second-line` (D213) are incompatible. Ignoring `multi-line-summary-second-line`. - "###); -} - -#[test] -fn nursery_direct() { - // Should fail when a nursery rule is selected without the preview flag - // Before Ruff v0.2.0 this would warn - let mut cmd = RuffCheck::default() - .args(["--select", "RUF912", "--output-format=concise"]) - .build(); - assert_cmd_snapshot!(cmd, @r###" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - ruff failed - Cause: Selection of unstable rule `RUF912` without the `--preview` flag is not allowed. - "###); -} - -#[test] -fn nursery_group_selector() { - // The NURSERY selector is removed but parses in the CLI for a nicer error message - // Before Ruff v0.2.0 this would warn - let mut cmd = RuffCheck::default() - .args(["--select", "NURSERY", "--output-format=concise"]) - .build(); - assert_cmd_snapshot!(cmd, @r###" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - ruff failed - Cause: The `NURSERY` selector was removed. Use the `--preview` flag instead. - "###); -} - -#[test] -fn nursery_group_selector_preview_enabled() { - // When preview mode is enabled, we shouldn't suggest using the `--preview` flag. - // Before Ruff v0.2.0 this would warn - let mut cmd = RuffCheck::default() - .args(["--select", "NURSERY", "--preview"]) - .build(); - assert_cmd_snapshot!(cmd, @r###" - success: false - exit_code: 2 - ----- stdout ----- - - ----- stderr ----- - ruff failed - Cause: The `NURSERY` selector was removed. Unstable rules should be selected individually or by their respective groups. - "###); -} - #[test] fn preview_enabled_prefix() { // All the RUF9XX test rules should be triggered @@ -1009,9 +904,8 @@ fn preview_enabled_prefix() { -: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. -:1:1: RUF911 Hey this is a preview test rule. - -:1:1: RUF912 Hey this is a nursery test rule. -:1:1: RUF950 Hey this is a test rule that was redirected from another. - Found 7 errors. + Found 6 errors. [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). ----- stderr ----- @@ -1034,9 +928,8 @@ fn preview_enabled_all() { -: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. -:1:1: RUF911 Hey this is a preview test rule. - -:1:1: RUF912 Hey this is a nursery test rule. -:1:1: RUF950 Hey this is a test rule that was redirected from another. - Found 9 errors. + Found 8 errors. [*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option). ----- stderr ----- @@ -1174,9 +1067,8 @@ fn preview_enabled_group_ignore() { -: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. -:1:1: RUF911 Hey this is a preview test rule. - -:1:1: RUF912 Hey this is a nursery test rule. -:1:1: RUF950 Hey this is a test rule that was redirected from another. - Found 7 errors. + 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_dev/src/generate_docs.rs b/crates/ruff_dev/src/generate_docs.rs index 987b485db94cc..90c88cda5c2be 100644 --- a/crates/ruff_dev/src/generate_docs.rs +++ b/crates/ruff_dev/src/generate_docs.rs @@ -64,7 +64,7 @@ pub(crate) fn main(args: &Args) -> Result<()> { output.push('\n'); } - if rule.is_preview() || rule.is_nursery() { + if rule.is_preview() { output.push_str( r"This rule is unstable and in [preview](../preview.md). The `--preview` flag is required for use.", ); diff --git a/crates/ruff_dev/src/generate_rules_table.rs b/crates/ruff_dev/src/generate_rules_table.rs index 453700c1e8b03..15d3984ca9364 100644 --- a/crates/ruff_dev/src/generate_rules_table.rs +++ b/crates/ruff_dev/src/generate_rules_table.rs @@ -34,7 +34,7 @@ fn generate_table(table_out: &mut String, rules: impl IntoIterator, format!("{WARNING_SYMBOL}") } #[allow(deprecated)] - RuleGroup::Preview | RuleGroup::Nursery => { + RuleGroup::Preview => { format!("{PREVIEW_SYMBOL}") } RuleGroup::Stable => { diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 14bd9e6848cce..5cfea34a370d4 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -57,9 +57,6 @@ pub enum RuleGroup { Deprecated, /// The rule has been removed, errors will be displayed on use. Removed, - /// Legacy category for unstable rules, supports backwards compatible selection. - #[deprecated(note = "Use `RuleGroup::Preview` for new rules instead")] - Nursery, } #[ruff_macros::map_codes] @@ -71,72 +68,39 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { Some(match (linter, code) { // pycodestyle errors (Pycodestyle, "E101") => (RuleGroup::Stable, rules::pycodestyle::rules::MixedSpacesAndTabs), - #[allow(deprecated)] - (Pycodestyle, "E111") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultiple), - #[allow(deprecated)] - (Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock), - #[allow(deprecated)] - (Pycodestyle, "E113") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::UnexpectedIndentation), - #[allow(deprecated)] - (Pycodestyle, "E114") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultipleComment), - #[allow(deprecated)] - (Pycodestyle, "E115") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlockComment), - #[allow(deprecated)] - (Pycodestyle, "E116") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::UnexpectedIndentationComment), - #[allow(deprecated)] - (Pycodestyle, "E117") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::OverIndented), - #[allow(deprecated)] - (Pycodestyle, "E201") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceAfterOpenBracket), - #[allow(deprecated)] - (Pycodestyle, "E202") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeCloseBracket), - #[allow(deprecated)] - (Pycodestyle, "E203") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforePunctuation), - #[allow(deprecated)] - (Pycodestyle, "E211") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeParameters), - #[allow(deprecated)] - (Pycodestyle, "E221") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeOperator), - #[allow(deprecated)] - (Pycodestyle, "E222") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterOperator), - #[allow(deprecated)] - (Pycodestyle, "E223") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabBeforeOperator), - #[allow(deprecated)] - (Pycodestyle, "E224") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabAfterOperator), - #[allow(deprecated)] - (Pycodestyle, "E225") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundOperator), - #[allow(deprecated)] - (Pycodestyle, "E226") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundArithmeticOperator), - #[allow(deprecated)] - (Pycodestyle, "E227") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundBitwiseOrShiftOperator), - #[allow(deprecated)] - (Pycodestyle, "E228") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundModuloOperator), - #[allow(deprecated)] - (Pycodestyle, "E231") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespace), - #[allow(deprecated)] - (Pycodestyle, "E241") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterComma), - #[allow(deprecated)] - (Pycodestyle, "E242") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabAfterComma), - #[allow(deprecated)] - (Pycodestyle, "E251") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::UnexpectedSpacesAroundKeywordParameterEquals), - #[allow(deprecated)] - (Pycodestyle, "E252") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundParameterEquals), - #[allow(deprecated)] - (Pycodestyle, "E261") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TooFewSpacesBeforeInlineComment), - #[allow(deprecated)] - (Pycodestyle, "E262") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoSpaceAfterInlineComment), - #[allow(deprecated)] - (Pycodestyle, "E265") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoSpaceAfterBlockComment), - #[allow(deprecated)] - (Pycodestyle, "E266") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleLeadingHashesForBlockComment), - #[allow(deprecated)] - (Pycodestyle, "E271") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterKeyword), - #[allow(deprecated)] - (Pycodestyle, "E272") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeKeyword), - #[allow(deprecated)] - (Pycodestyle, "E273") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabAfterKeyword), - #[allow(deprecated)] - (Pycodestyle, "E274") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::TabBeforeKeyword), - #[allow(deprecated)] - (Pycodestyle, "E275") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAfterKeyword), + (Pycodestyle, "E111") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultiple), + (Pycodestyle, "E112") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlock), + (Pycodestyle, "E113") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::UnexpectedIndentation), + (Pycodestyle, "E114") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::IndentationWithInvalidMultipleComment), + (Pycodestyle, "E115") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlockComment), + (Pycodestyle, "E116") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::UnexpectedIndentationComment), + (Pycodestyle, "E117") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::OverIndented), + (Pycodestyle, "E201") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceAfterOpenBracket), + (Pycodestyle, "E202") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeCloseBracket), + (Pycodestyle, "E203") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceBeforePunctuation), + (Pycodestyle, "E211") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::WhitespaceBeforeParameters), + (Pycodestyle, "E221") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeOperator), + (Pycodestyle, "E222") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterOperator), + (Pycodestyle, "E223") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabBeforeOperator), + (Pycodestyle, "E224") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabAfterOperator), + (Pycodestyle, "E225") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundOperator), + (Pycodestyle, "E226") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundArithmeticOperator), + (Pycodestyle, "E227") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundBitwiseOrShiftOperator), + (Pycodestyle, "E228") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundModuloOperator), + (Pycodestyle, "E231") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespace), + (Pycodestyle, "E241") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterComma), + (Pycodestyle, "E242") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabAfterComma), + (Pycodestyle, "E251") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::UnexpectedSpacesAroundKeywordParameterEquals), + (Pycodestyle, "E252") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAroundParameterEquals), + (Pycodestyle, "E261") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TooFewSpacesBeforeInlineComment), + (Pycodestyle, "E262") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoSpaceAfterInlineComment), + (Pycodestyle, "E265") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoSpaceAfterBlockComment), + (Pycodestyle, "E266") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleLeadingHashesForBlockComment), + (Pycodestyle, "E271") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesAfterKeyword), + (Pycodestyle, "E272") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MultipleSpacesBeforeKeyword), + (Pycodestyle, "E273") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabAfterKeyword), + (Pycodestyle, "E274") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::TabBeforeKeyword), + (Pycodestyle, "E275") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::MissingWhitespaceAfterKeyword), (Pycodestyle, "E301") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLineBetweenMethods), (Pycodestyle, "E302") => (RuleGroup::Preview, rules::pycodestyle::rules::BlankLinesTopLevel), (Pycodestyle, "E303") => (RuleGroup::Preview, rules::pycodestyle::rules::TooManyBlankLines), @@ -226,8 +190,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "C0208") => (RuleGroup::Stable, rules::pylint::rules::IterationOverSet), (Pylint, "C0414") => (RuleGroup::Stable, rules::pylint::rules::UselessImportAlias), (Pylint, "C0415") => (RuleGroup::Preview, rules::pylint::rules::ImportOutsideTopLevel), - #[allow(deprecated)] - (Pylint, "C1901") => (RuleGroup::Nursery, rules::pylint::rules::CompareToEmptyString), + (Pylint, "C1901") => (RuleGroup::Preview, rules::pylint::rules::CompareToEmptyString), (Pylint, "C2401") => (RuleGroup::Preview, rules::pylint::rules::NonAsciiName), (Pylint, "C2403") => (RuleGroup::Preview, rules::pylint::rules::NonAsciiImportName), (Pylint, "C2701") => (RuleGroup::Preview, rules::pylint::rules::ImportPrivateName), @@ -300,8 +263,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "R5501") => (RuleGroup::Stable, rules::pylint::rules::CollapsibleElseIf), (Pylint, "R6104") => (RuleGroup::Preview, rules::pylint::rules::NonAugmentedAssignment), (Pylint, "R6201") => (RuleGroup::Preview, rules::pylint::rules::LiteralMembership), - #[allow(deprecated)] - (Pylint, "R6301") => (RuleGroup::Nursery, rules::pylint::rules::NoSelfUse), + (Pylint, "R6301") => (RuleGroup::Preview, rules::pylint::rules::NoSelfUse), (Pylint, "W0108") => (RuleGroup::Preview, rules::pylint::rules::UnnecessaryLambda), (Pylint, "W0177") => (RuleGroup::Preview, rules::pylint::rules::NanComparison), (Pylint, "W0120") => (RuleGroup::Stable, rules::pylint::rules::UselessElseOnLoop), @@ -323,12 +285,10 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Pylint, "W1509") => (RuleGroup::Stable, rules::pylint::rules::SubprocessPopenPreexecFn), (Pylint, "W1510") => (RuleGroup::Stable, rules::pylint::rules::SubprocessRunWithoutCheck), (Pylint, "W1514") => (RuleGroup::Preview, rules::pylint::rules::UnspecifiedEncoding), - #[allow(deprecated)] - (Pylint, "W1641") => (RuleGroup::Nursery, rules::pylint::rules::EqWithoutHash), + (Pylint, "W1641") => (RuleGroup::Preview, rules::pylint::rules::EqWithoutHash), (Pylint, "W2101") => (RuleGroup::Preview, rules::pylint::rules::UselessWithLock), (Pylint, "W2901") => (RuleGroup::Stable, rules::pylint::rules::RedefinedLoopName), - #[allow(deprecated)] - (Pylint, "W3201") => (RuleGroup::Nursery, rules::pylint::rules::BadDunderMethodName), + (Pylint, "W3201") => (RuleGroup::Preview, rules::pylint::rules::BadDunderMethodName), (Pylint, "W3301") => (RuleGroup::Stable, rules::pylint::rules::NestedMinMax), // flake8-async @@ -515,8 +475,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Simplify, "911") => (RuleGroup::Stable, rules::flake8_simplify::rules::ZipDictKeysAndValues), // flake8-copyright - #[allow(deprecated)] - (Flake8Copyright, "001") => (RuleGroup::Nursery, rules::flake8_copyright::rules::MissingCopyrightNotice), + (Flake8Copyright, "001") => (RuleGroup::Preview, rules::flake8_copyright::rules::MissingCopyrightNotice), // pyupgrade (Pyupgrade, "001") => (RuleGroup::Stable, rules::pyupgrade::rules::UselessMetaclassType), @@ -992,9 +951,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { #[cfg(any(feature = "test-rules", test))] (Ruff, "911") => (RuleGroup::Preview, rules::ruff::rules::PreviewTestRule), #[cfg(any(feature = "test-rules", test))] - #[allow(deprecated)] - (Ruff, "912") => (RuleGroup::Nursery, rules::ruff::rules::NurseryTestRule), - #[cfg(any(feature = "test-rules", test))] (Ruff, "920") => (RuleGroup::Deprecated, rules::ruff::rules::DeprecatedTestRule), #[cfg(any(feature = "test-rules", test))] (Ruff, "921") => (RuleGroup::Deprecated, rules::ruff::rules::AnotherDeprecatedTestRule), @@ -1059,15 +1015,12 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Refurb, "103") => (RuleGroup::Preview, rules::refurb::rules::WriteWholeFile), (Refurb, "105") => (RuleGroup::Preview, rules::refurb::rules::PrintEmptyString), (Refurb, "110") => (RuleGroup::Preview, rules::refurb::rules::IfExpInsteadOfOrOperator), - #[allow(deprecated)] - (Refurb, "113") => (RuleGroup::Nursery, rules::refurb::rules::RepeatedAppend), + (Refurb, "113") => (RuleGroup::Preview, rules::refurb::rules::RepeatedAppend), (Refurb, "116") => (RuleGroup::Preview, rules::refurb::rules::FStringNumberFormat), (Refurb, "118") => (RuleGroup::Preview, rules::refurb::rules::ReimplementedOperator), (Refurb, "129") => (RuleGroup::Preview, rules::refurb::rules::ReadlinesInFor), - #[allow(deprecated)] - (Refurb, "131") => (RuleGroup::Nursery, rules::refurb::rules::DeleteFullSlice), - #[allow(deprecated)] - (Refurb, "132") => (RuleGroup::Nursery, rules::refurb::rules::CheckAndRemoveFromSet), + (Refurb, "131") => (RuleGroup::Preview, rules::refurb::rules::DeleteFullSlice), + (Refurb, "132") => (RuleGroup::Preview, rules::refurb::rules::CheckAndRemoveFromSet), (Refurb, "136") => (RuleGroup::Preview, rules::refurb::rules::IfExprMinMax), (Refurb, "140") => (RuleGroup::Preview, rules::refurb::rules::ReimplementedStarmap), (Refurb, "142") => (RuleGroup::Preview, rules::refurb::rules::ForLoopSetMutations), diff --git a/crates/ruff_linter/src/linter.rs b/crates/ruff_linter/src/linter.rs index 1717d5116d1b2..08192b55b6fb4 100644 --- a/crates/ruff_linter/src/linter.rs +++ b/crates/ruff_linter/src/linter.rs @@ -244,9 +244,6 @@ pub fn check_path( Rule::StableTestRuleDisplayOnlyFix => { test_rules::StableTestRuleDisplayOnlyFix::diagnostic(locator, comment_ranges) } - Rule::NurseryTestRule => { - test_rules::NurseryTestRule::diagnostic(locator, comment_ranges) - } Rule::PreviewTestRule => { test_rules::PreviewTestRule::diagnostic(locator, comment_ranges) } diff --git a/crates/ruff_linter/src/rule_selector.rs b/crates/ruff_linter/src/rule_selector.rs index 9598addb22f6e..707fb4893c483 100644 --- a/crates/ruff_linter/src/rule_selector.rs +++ b/crates/ruff_linter/src/rule_selector.rs @@ -15,9 +15,6 @@ use crate::settings::types::PreviewMode; pub enum RuleSelector { /// Select all rules (includes rules in preview if enabled) All, - /// Legacy category to select all rules in the "nursery" which predated preview mode - #[deprecated(note = "The nursery was replaced with 'preview mode' which has no selector")] - Nursery, /// Legacy category to select both the `mccabe` and `flake8-comprehensions` linters /// via a single selector. C, @@ -65,8 +62,6 @@ impl FromStr for RuleSelector { // **Changes should be reflected in `parse_no_redirect` as well** match s { "ALL" => Ok(Self::All), - #[allow(deprecated)] - "NURSERY" => Ok(Self::Nursery), "C" => Ok(Self::C), "T" => Ok(Self::T), _ => { @@ -130,8 +125,6 @@ impl RuleSelector { pub fn prefix_and_code(&self) -> (&'static str, &'static str) { match self { RuleSelector::All => ("", "ALL"), - #[allow(deprecated)] - RuleSelector::Nursery => ("", "NURSERY"), RuleSelector::C => ("", "C"), RuleSelector::T => ("", "T"), RuleSelector::Prefix { prefix, .. } | RuleSelector::Rule { prefix, .. } => { @@ -191,10 +184,6 @@ impl RuleSelector { match self { RuleSelector::All => RuleSelectorIter::All(Rule::iter()), - #[allow(deprecated)] - RuleSelector::Nursery => { - RuleSelectorIter::Nursery(Rule::iter().filter(Rule::is_nursery)) - } RuleSelector::C => RuleSelectorIter::Chain( Linter::Flake8Comprehensions .rules() @@ -216,15 +205,11 @@ impl RuleSelector { pub fn rules<'a>(&'a self, preview: &PreviewOptions) -> impl Iterator + 'a { let preview_enabled = preview.mode.is_enabled(); let preview_require_explicit = preview.require_explicit; - #[allow(deprecated)] self.all_rules().filter(move |rule| { // Always include stable rules rule.is_stable() - // Backwards compatibility allows selection of nursery rules by exact code or dedicated group - || ((self.is_exact() || matches!(self, RuleSelector::Nursery { .. })) && rule.is_nursery()) - // Enabling preview includes all preview or nursery rules unless explicit selection - // is turned on - || ((rule.is_preview() || rule.is_nursery()) && preview_enabled && (self.is_exact() || !preview_require_explicit)) + // Enabling preview includes all preview rules unless explicit selection is turned on + || (rule.is_preview() && preview_enabled && (self.is_exact() || !preview_require_explicit)) // Deprecated rules are excluded in preview mode unless explicitly selected || (rule.is_deprecated() && (!preview_enabled || self.is_exact())) // Removed rules are included if explicitly selected but will error downstream @@ -240,7 +225,6 @@ impl RuleSelector { pub enum RuleSelectorIter { All(RuleIter), - Nursery(std::iter::Filter bool>), Chain(std::iter::Chain, std::vec::IntoIter>), Vec(std::vec::IntoIter), } @@ -251,7 +235,6 @@ impl Iterator for RuleSelectorIter { fn next(&mut self) -> Option { match self { RuleSelectorIter::All(iter) => iter.next(), - RuleSelectorIter::Nursery(iter) => iter.next(), RuleSelectorIter::Chain(iter) => iter.next(), RuleSelectorIter::Vec(iter) => iter.next(), } @@ -288,7 +271,7 @@ mod schema { instance_type: Some(InstanceType::String.into()), enum_values: Some( [ - // Include the non-standard "ALL" and "NURSERY" selectors. + // Include the non-standard "ALL" selectors. "ALL".to_string(), // Include the legacy "C" and "T" selectors. "C".to_string(), @@ -345,8 +328,6 @@ impl RuleSelector { pub fn specificity(&self) -> Specificity { match self { RuleSelector::All => Specificity::All, - #[allow(deprecated)] - RuleSelector::Nursery => Specificity::All, RuleSelector::T => Specificity::LinterGroup, RuleSelector::C => Specificity::LinterGroup, RuleSelector::Linter(..) => Specificity::Linter, @@ -369,8 +350,6 @@ impl RuleSelector { // **Changes should be reflected in `from_str` as well** match s { "ALL" => Ok(Self::All), - #[allow(deprecated)] - "NURSERY" => Ok(Self::Nursery), "C" => Ok(Self::C), "T" => Ok(Self::T), _ => { 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 b9e9cea7c0af6..730db5408f0e9 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/test_rules.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/test_rules.rs @@ -38,7 +38,6 @@ pub(crate) const TEST_RULES: &[Rule] = &[ Rule::StableTestRuleUnsafeFix, Rule::StableTestRuleDisplayOnlyFix, Rule::PreviewTestRule, - Rule::NurseryTestRule, Rule::DeprecatedTestRule, Rule::AnotherDeprecatedTestRule, Rule::RemovedTestRule, @@ -262,42 +261,6 @@ impl TestRule for PreviewTestRule { } } -/// ## What it does -/// Fake rule for testing. -/// -/// ## Why is this bad? -/// Tests must pass! -/// -/// ## Example -/// ```python -/// foo -/// ``` -/// -/// Use instead: -/// ```python -/// bar -/// ``` -#[violation] -pub struct NurseryTestRule; - -impl Violation for NurseryTestRule { - const FIX_AVAILABILITY: FixAvailability = FixAvailability::None; - - #[derive_message_formats] - fn message(&self) -> String { - format!("Hey this is a nursery test rule.") - } -} - -impl TestRule for NurseryTestRule { - fn diagnostic(_locator: &Locator, _comment_ranges: &CommentRanges) -> Option { - Some(Diagnostic::new( - NurseryTestRule, - ruff_text_size::TextRange::default(), - )) - } -} - /// ## What it does /// Fake rule for testing. /// diff --git a/crates/ruff_macros/src/map_codes.rs b/crates/ruff_macros/src/map_codes.rs index 5601fa717aef5..b1534a4bcb6b7 100644 --- a/crates/ruff_macros/src/map_codes.rs +++ b/crates/ruff_macros/src/map_codes.rs @@ -11,7 +11,7 @@ use syn::{ use crate::rule_code_prefix::{get_prefix_ident, intersection_all}; /// A rule entry in the big match statement such a -/// `(Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),` +/// `(Pycodestyle, "E112") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),` #[derive(Clone)] struct Rule { /// The actual name of the rule, e.g., `NoIndentedBlock`. @@ -20,7 +20,7 @@ struct Rule { linter: Ident, /// The code associated with the rule, e.g., `"E112"`. code: LitStr, - /// The rule group identifier, e.g., `RuleGroup::Nursery`. + /// The rule group identifier, e.g., `RuleGroup::Preview`. group: Path, /// The path to the struct implementing the rule, e.g. /// `rules::pycodestyle::rules::logical_lines::NoIndentedBlock` @@ -321,11 +321,6 @@ See also https://github.com/astral-sh/ruff/issues/2186. matches!(self.group(), RuleGroup::Stable) } - #[allow(deprecated)] - pub fn is_nursery(&self) -> bool { - matches!(self.group(), RuleGroup::Nursery) - } - pub fn is_deprecated(&self) -> bool { matches!(self.group(), RuleGroup::Deprecated) } @@ -373,13 +368,13 @@ fn generate_iter_impl( quote! { impl Linter { - /// Rules not in the nursery. + /// Rules not in the preview. pub fn rules(self: &Linter) -> ::std::vec::IntoIter { match self { #linter_rules_match_arms } } - /// All rules, including those in the nursery. + /// All rules, including those in the preview. pub fn all_rules(self: &Linter) -> ::std::vec::IntoIter { match self { #linter_all_rules_match_arms @@ -481,7 +476,7 @@ fn register_rules<'a>(input: impl Iterator) -> TokenStream { } impl Parse for Rule { - /// Parses a match arm such as `(Pycodestyle, "E112") => (RuleGroup::Nursery, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),` + /// Parses a match arm such as `(Pycodestyle, "E112") => (RuleGroup::Preview, rules::pycodestyle::rules::logical_lines::NoIndentedBlock),` fn parse(input: syn::parse::ParseStream) -> syn::Result { let attrs = Attribute::parse_outer(input)?; let pat_tuple; diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index f05c266d4d03b..d982b497a312e 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -101,7 +101,7 @@ fn format_rule_text(rule: Rule) -> String { output.push('\n'); } - if rule.is_preview() || rule.is_nursery() { + if rule.is_preview() { output.push_str(r"This rule is in preview and is not stable."); output.push('\n'); output.push('\n'); diff --git a/crates/ruff_workspace/src/configuration.rs b/crates/ruff_workspace/src/configuration.rs index a278f77307a5f..d1d30a44ec241 100644 --- a/crates/ruff_workspace/src/configuration.rs +++ b/crates/ruff_workspace/src/configuration.rs @@ -763,7 +763,6 @@ impl LintConfiguration { // Store selectors for displaying warnings let mut redirects = FxHashMap::default(); - let mut deprecated_nursery_selectors = FxHashSet::default(); let mut deprecated_selectors = FxHashSet::default(); let mut removed_selectors = FxHashSet::default(); let mut ignored_preview_selectors = FxHashSet::default(); @@ -888,27 +887,11 @@ impl LintConfiguration { // Check for selections that require a warning for (kind, selector) in selection.selectors_by_kind() { - #[allow(deprecated)] - if matches!(selector, RuleSelector::Nursery) { - let suggestion = if preview.mode.is_disabled() { - " Use the `--preview` flag instead." - } else { - " Unstable rules should be selected individually or by their respective groups." - }; - return Err(anyhow!("The `NURSERY` selector was removed.{suggestion}")); - }; - // Some of these checks are only for `Kind::Enable` which means only `--select` will warn // and use with, e.g., `--ignore` or `--fixable` is okay // Unstable rules if preview.mode.is_disabled() && kind.is_enable() { - if selector.is_exact() { - if selector.all_rules().all(|rule| rule.is_nursery()) { - deprecated_nursery_selectors.insert(selector); - } - } - // Check if the selector is empty because preview mode is disabled if selector.rules(&preview).next().is_none() && selector @@ -985,29 +968,6 @@ impl LintConfiguration { ); } - let deprecated_nursery_selectors = deprecated_nursery_selectors - .iter() - .sorted() - .collect::>(); - match deprecated_nursery_selectors.as_slice() { - [] => (), - [selection] => { - let (prefix, code) = selection.prefix_and_code(); - return Err(anyhow!("Selection of unstable rule `{prefix}{code}` without the `--preview` flag is not allowed.")); - } - [..] => { - let mut message = "Selection of unstable rules without the `--preview` flag is not allowed. Enable preview or remove selection of:".to_string(); - for selection in deprecated_nursery_selectors { - let (prefix, code) = selection.prefix_and_code(); - message.push_str("\n\t- "); - message.push_str(prefix); - message.push_str(code); - } - message.push('\n'); - return Err(anyhow!(message)); - } - } - if preview.mode.is_disabled() { for selection in deprecated_selectors.iter().sorted() { let (prefix, code) = selection.prefix_and_code(); @@ -1882,64 +1842,6 @@ mod tests { Ok(()) } - #[test] - fn nursery_select_code() -> Result<()> { - // We do not allow selection of nursery rules when preview is disabled - assert!(resolve_rules( - [RuleSelection { - select: Some(vec![Flake8Copyright::_001.into()]), - ..RuleSelection::default() - }], - Some(PreviewOptions { - mode: PreviewMode::Disabled, - ..PreviewOptions::default() - }), - ) - .is_err()); - - let actual = resolve_rules( - [RuleSelection { - select: Some(vec![Flake8Copyright::_001.into()]), - ..RuleSelection::default() - }], - Some(PreviewOptions { - mode: PreviewMode::Enabled, - ..PreviewOptions::default() - }), - )?; - let expected = RuleSet::from_rule(Rule::MissingCopyrightNotice); - assert_eq!(actual, expected); - Ok(()) - } - - #[test] - #[allow(deprecated)] - fn select_nursery() { - // We no longer allow use of the NURSERY selector and should error in both cases - assert!(resolve_rules( - [RuleSelection { - select: Some(vec![RuleSelector::Nursery]), - ..RuleSelection::default() - }], - Some(PreviewOptions { - mode: PreviewMode::Disabled, - ..PreviewOptions::default() - }), - ) - .is_err()); - assert!(resolve_rules( - [RuleSelection { - select: Some(vec![RuleSelector::Nursery]), - ..RuleSelection::default() - }], - Some(PreviewOptions { - mode: PreviewMode::Enabled, - ..PreviewOptions::default() - }), - ) - .is_err()); - } - #[test] fn select_docstring_convention_override() -> Result<()> { fn assert_override(