diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF025.py b/crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C420.py similarity index 100% rename from crates/ruff_linter/resources/test/fixtures/ruff/RUF025.py rename to crates/ruff_linter/resources/test/fixtures/flake8_comprehensions/C420.py diff --git a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs index d21dc3ccb10cc..5b1c304e40228 100644 --- a/crates/ruff_linter/src/checkers/ast/analyze/expression.rs +++ b/crates/ruff_linter/src/checkers/ast/analyze/expression.rs @@ -1490,7 +1490,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { } if checker.enabled(Rule::UnnecessaryDictComprehensionForIterable) { - ruff::rules::unnecessary_dict_comprehension_for_iterable(checker, dict_comp); + flake8_comprehensions::rules::unnecessary_dict_comprehension_for_iterable( + checker, dict_comp, + ); } if checker.enabled(Rule::FunctionUsesLoopVariable) { diff --git a/crates/ruff_linter/src/codes.rs b/crates/ruff_linter/src/codes.rs index 9eb22cf306923..3ba1bd8b9e4af 100644 --- a/crates/ruff_linter/src/codes.rs +++ b/crates/ruff_linter/src/codes.rs @@ -4,12 +4,12 @@ /// `--select`. For pylint this is e.g. C0414 and E0118 but also C and E01. use std::fmt::Formatter; +use strum_macros::{AsRefStr, EnumIter}; + use crate::registry::{AsRule, Linter}; use crate::rule_selector::is_single_rule_selector; use crate::rules; -use strum_macros::{AsRefStr, EnumIter}; - #[derive(PartialEq, Eq, PartialOrd, Ord)] pub struct NoqaCode(&'static str, &'static str); @@ -374,6 +374,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Flake8Comprehensions, "17") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryMap), (Flake8Comprehensions, "18") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryLiteralWithinDictCall), (Flake8Comprehensions, "19") => (RuleGroup::Stable, rules::flake8_comprehensions::rules::UnnecessaryComprehensionInCall), + (Flake8Comprehensions, "20") => (RuleGroup::Preview, rules::flake8_comprehensions::rules::UnnecessaryDictComprehensionForIterable), // flake8-debugger (Flake8Debugger, "0") => (RuleGroup::Stable, rules::flake8_debugger::rules::Debugger), @@ -945,7 +946,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> { (Ruff, "022") => (RuleGroup::Preview, rules::ruff::rules::UnsortedDunderAll), (Ruff, "023") => (RuleGroup::Preview, rules::ruff::rules::UnsortedDunderSlots), (Ruff, "024") => (RuleGroup::Stable, rules::ruff::rules::MutableFromkeysValue), - (Ruff, "025") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryDictComprehensionForIterable), (Ruff, "026") => (RuleGroup::Stable, rules::ruff::rules::DefaultFactoryKwarg), (Ruff, "027") => (RuleGroup::Preview, rules::ruff::rules::MissingFStringSyntax), (Ruff, "028") => (RuleGroup::Preview, rules::ruff::rules::InvalidFormatterSuppressionComment), diff --git a/crates/ruff_linter/src/rule_redirects.rs b/crates/ruff_linter/src/rule_redirects.rs index 2f174e80d009a..665edc004fa52 100644 --- a/crates/ruff_linter/src/rule_redirects.rs +++ b/crates/ruff_linter/src/rule_redirects.rs @@ -123,5 +123,7 @@ static REDIRECTS: Lazy> = Lazy::new(|| { ("RUF96", "RUF95"), // See: https://github.com/astral-sh/ruff/issues/10791 ("PLW0117", "PLW0177"), + // See: https://github.com/astral-sh/ruff/issues/12110 + ("RUF025", "C420"), ]) }); diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs index f1c765dff0646..4eec7773787a5 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs @@ -21,6 +21,7 @@ mod tests { #[test_case(Rule::UnnecessaryComprehension, Path::new("C416.py"))] #[test_case(Rule::UnnecessaryComprehensionInCall, Path::new("C419.py"))] #[test_case(Rule::UnnecessaryComprehensionInCall, Path::new("C419_2.py"))] + #[test_case(Rule::UnnecessaryDictComprehensionForIterable, Path::new("C420.py"))] #[test_case(Rule::UnnecessaryDoubleCastOrProcess, Path::new("C414.py"))] #[test_case(Rule::UnnecessaryGeneratorDict, Path::new("C402.py"))] #[test_case(Rule::UnnecessaryGeneratorList, Path::new("C400.py"))] diff --git a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/mod.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/mod.rs index ff54ed3c38137..f939c774dbe82 100644 --- a/crates/ruff_linter/src/rules/flake8_comprehensions/rules/mod.rs +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/mod.rs @@ -2,6 +2,7 @@ pub(crate) use unnecessary_call_around_sorted::*; pub(crate) use unnecessary_collection_call::*; pub(crate) use unnecessary_comprehension::*; pub(crate) use unnecessary_comprehension_in_call::*; +pub(crate) use unnecessary_dict_comprehension_for_iterable::*; pub(crate) use unnecessary_double_cast_or_process::*; pub(crate) use unnecessary_generator_dict::*; pub(crate) use unnecessary_generator_list::*; @@ -22,6 +23,7 @@ mod unnecessary_call_around_sorted; mod unnecessary_collection_call; mod unnecessary_comprehension; mod unnecessary_comprehension_in_call; +mod unnecessary_dict_comprehension_for_iterable; mod unnecessary_double_cast_or_process; mod unnecessary_generator_dict; mod unnecessary_generator_list; diff --git a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_dict_comprehension_for_iterable.rs b/crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_dict_comprehension_for_iterable.rs similarity index 100% rename from crates/ruff_linter/src/rules/ruff/rules/unnecessary_dict_comprehension_for_iterable.rs rename to crates/ruff_linter/src/rules/flake8_comprehensions/rules/unnecessary_dict_comprehension_for_iterable.rs diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF025_RUF025.py.snap b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C420_C420.py.snap similarity index 69% rename from crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF025_RUF025.py.snap rename to crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C420_C420.py.snap index 519fb1b801390..c1b1ee2942ee9 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__RUF025_RUF025.py.snap +++ b/crates/ruff_linter/src/rules/flake8_comprehensions/snapshots/ruff_linter__rules__flake8_comprehensions__tests__C420_C420.py.snap @@ -1,12 +1,12 @@ --- -source: crates/ruff_linter/src/rules/ruff/mod.rs +source: crates/ruff_linter/src/rules/flake8_comprehensions/mod.rs --- -RUF025.py:6:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:6:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 4 | def func(): 5 | numbers = [1, 2, 3] 6 | {n: None for n in numbers} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable, value)`) @@ -20,11 +20,11 @@ RUF025.py:6:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict 8 8 | 9 9 | def func(): -RUF025.py:10:23: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:10:23: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 9 | def func(): 10 | for key, value in {n: 1 for n in [1, 2, 3]}.items(): # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ C420 11 | pass | = help: Replace with `dict.fromkeys(iterable)`) @@ -39,11 +39,11 @@ RUF025.py:10:23: RUF025 [*] Unnecessary dict comprehension for iterable; use `di 12 12 | 13 13 | -RUF025.py:15:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:15:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 14 | def func(): 15 | {n: 1.1 for n in [1, 2, 3]} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -57,12 +57,12 @@ RUF025.py:15:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 17 17 | 18 18 | def func(): -RUF025.py:26:7: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:26:7: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 24 | return data 25 | 26 | f({c: "a" for c in "12345"}) # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -76,11 +76,11 @@ RUF025.py:26:7: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 28 28 | 29 29 | def func(): -RUF025.py:30:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:30:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 29 | def func(): 30 | {n: True for n in [1, 2, 2]} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -94,11 +94,11 @@ RUF025.py:30:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 32 32 | 33 33 | def func(): -RUF025.py:34:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:34:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 33 | def func(): 34 | {n: b"hello" for n in (1, 2, 2)} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -112,11 +112,11 @@ RUF025.py:34:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 36 36 | 37 37 | def func(): -RUF025.py:38:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:38:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 37 | def func(): 38 | {n: ... for n in [1, 2, 3]} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -130,11 +130,11 @@ RUF025.py:38:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 40 40 | 41 41 | def func(): -RUF025.py:42:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:42:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 41 | def func(): 42 | {n: False for n in {1: "a", 2: "b"}} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -148,11 +148,11 @@ RUF025.py:42:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 44 44 | 45 45 | def func(): -RUF025.py:46:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:46:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 45 | def func(): 46 | {(a, b): 1 for (a, b) in [(1, 2), (3, 4)]} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -166,11 +166,11 @@ RUF025.py:46:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 48 48 | 49 49 | def func(): -RUF025.py:54:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:54:5: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 53 | a = f() 54 | {n: a for n in [1, 2, 3]} # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -184,12 +184,12 @@ RUF025.py:54:5: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 56 56 | 57 57 | def func(): -RUF025.py:59:6: RUF025 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead +C420.py:59:6: C420 [*] Unnecessary dict comprehension for iterable; use `dict.fromkeys` instead | 57 | def func(): 58 | values = ["a", "b", "c"] 59 | [{n: values for n in [1, 2, 3]}] # RUF025 - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF025 + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C420 | = help: Replace with `dict.fromkeys(iterable)`) @@ -202,5 +202,3 @@ RUF025.py:59:6: RUF025 [*] Unnecessary dict comprehension for iterable; use `dic 60 60 | 61 61 | 62 62 | # Non-violation cases: RUF025 - - diff --git a/crates/ruff_linter/src/rules/ruff/mod.rs b/crates/ruff_linter/src/rules/ruff/mod.rs index bc78b0bda5033..e3f6ee3b12d20 100644 --- a/crates/ruff_linter/src/rules/ruff/mod.rs +++ b/crates/ruff_linter/src/rules/ruff/mod.rs @@ -47,7 +47,6 @@ mod tests { #[test_case(Rule::UnsortedDunderAll, Path::new("RUF022.py"))] #[test_case(Rule::UnsortedDunderSlots, Path::new("RUF023.py"))] #[test_case(Rule::MutableFromkeysValue, Path::new("RUF024.py"))] - #[test_case(Rule::UnnecessaryDictComprehensionForIterable, Path::new("RUF025.py"))] #[test_case(Rule::DefaultFactoryKwarg, Path::new("RUF026.py"))] #[test_case(Rule::MissingFStringSyntax, Path::new("RUF027_0.py"))] #[test_case(Rule::MissingFStringSyntax, Path::new("RUF027_1.py"))] diff --git a/crates/ruff_linter/src/rules/ruff/rules/mod.rs b/crates/ruff_linter/src/rules/ruff/rules/mod.rs index ee615a48d0dff..90bab89acd8b8 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/mod.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/mod.rs @@ -23,7 +23,6 @@ pub(crate) use sort_dunder_slots::*; pub(crate) use static_key_dict_comprehension::*; #[cfg(any(feature = "test-rules", test))] pub(crate) use test_rules::*; -pub(crate) use unnecessary_dict_comprehension_for_iterable::*; pub(crate) use unnecessary_iterable_allocation_for_first_element::*; pub(crate) use unnecessary_key_check::*; pub(crate) use unused_async::*; @@ -59,7 +58,6 @@ mod static_key_dict_comprehension; mod suppression_comment_visitor; #[cfg(any(feature = "test-rules", test))] pub(crate) mod test_rules; -mod unnecessary_dict_comprehension_for_iterable; mod unnecessary_iterable_allocation_for_first_element; mod unnecessary_key_check; mod unused_async; diff --git a/ruff.schema.json b/ruff.schema.json index 71bf642a01f68..51bebabdff83f 100644 --- a/ruff.schema.json +++ b/ruff.schema.json @@ -2793,6 +2793,8 @@ "C417", "C418", "C419", + "C42", + "C420", "C9", "C90", "C901", @@ -3684,7 +3686,6 @@ "RUF022", "RUF023", "RUF024", - "RUF025", "RUF026", "RUF027", "RUF028",