Skip to content

Commit 836d2ea

Browse files
committed
Restore RUF011 documentation (#9758)
For consistency with other redirected rules as in #9755 Follow-up to #9428
1 parent 994514d commit 836d2ea

File tree

6 files changed

+66
-10
lines changed

6 files changed

+66
-10
lines changed

crates/ruff/tests/integration_test.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1228,8 +1228,8 @@ fn deprecated_multiple_direct() {
12281228
Found 2 errors.
12291229
12301230
----- stderr -----
1231-
warning: Rule `RUF921` is deprecated and will be removed in a future release.
12321231
warning: Rule `RUF920` is deprecated and will be removed in a future release.
1232+
warning: Rule `RUF921` is deprecated and will be removed in a future release.
12331233
"###);
12341234
}
12351235

@@ -1297,8 +1297,8 @@ fn deprecated_multiple_direct_preview_enabled() {
12971297
----- stderr -----
12981298
ruff failed
12991299
Cause: Selection of deprecated rules is not allowed when preview is enabled. Remove selection of:
1300-
- RUF921
13011300
- RUF920
1301+
- RUF921
13021302
13031303
"###);
13041304
}

crates/ruff_linter/src/codes.rs

+1
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
922922
(Ruff, "008") => (RuleGroup::Stable, rules::ruff::rules::MutableDataclassDefault),
923923
(Ruff, "009") => (RuleGroup::Stable, rules::ruff::rules::FunctionCallInDataclassDefaultArgument),
924924
(Ruff, "010") => (RuleGroup::Stable, rules::ruff::rules::ExplicitFStringTypeConversion),
925+
(Ruff, "011") => (RuleGroup::Removed, rules::ruff::rules::RuffStaticKeyDictComprehension),
925926
(Ruff, "012") => (RuleGroup::Stable, rules::ruff::rules::MutableClassDefault),
926927
(Ruff, "013") => (RuleGroup::Stable, rules::ruff::rules::ImplicitOptional),
927928
(Ruff, "015") => (RuleGroup::Stable, rules::ruff::rules::UnnecessaryIterableAllocationForFirstElement),

crates/ruff_linter/src/rule_selector.rs

+14
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,20 @@ impl From<Linter> for RuleSelector {
4444
}
4545
}
4646

47+
impl Ord for RuleSelector {
48+
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
49+
// TODO(zanieb): We ought to put "ALL" and "Linter" selectors
50+
// above those that are rule specific but it's not critical for now
51+
self.prefix_and_code().cmp(&other.prefix_and_code())
52+
}
53+
}
54+
55+
impl PartialOrd for RuleSelector {
56+
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
57+
Some(self.cmp(other))
58+
}
59+
}
60+
4761
impl FromStr for RuleSelector {
4862
type Err = ParseError;
4963

crates/ruff_linter/src/rules/ruff/rules/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub(crate) use parenthesize_logical_operators::*;
1717
pub(crate) use quadratic_list_summation::*;
1818
pub(crate) use sort_dunder_all::*;
1919
pub(crate) use sort_dunder_slots::*;
20+
pub(crate) use static_key_dict_comprehension::*;
2021
#[cfg(feature = "test-rules")]
2122
pub(crate) use test_rules::*;
2223
pub(crate) use unnecessary_dict_comprehension_for_iterable::*;
@@ -42,9 +43,11 @@ mod mutable_fromkeys_value;
4243
mod never_union;
4344
mod pairwise_over_zipped;
4445
mod parenthesize_logical_operators;
46+
mod quadratic_list_summation;
4547
mod sequence_sorting;
4648
mod sort_dunder_all;
4749
mod sort_dunder_slots;
50+
mod static_key_dict_comprehension;
4851
#[cfg(feature = "test-rules")]
4952
pub(crate) mod test_rules;
5053
mod unnecessary_dict_comprehension_for_iterable;
@@ -58,5 +61,3 @@ pub(crate) enum Context {
5861
Docstring,
5962
Comment,
6063
}
61-
62-
mod quadratic_list_summation;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use ruff_diagnostics::Violation;
2+
use ruff_macros::{derive_message_formats, violation};
3+
4+
/// ## Removed
5+
/// This rule was implemented in `flake8-bugbear` and has been remapped to [B035]
6+
///
7+
/// ## What it does
8+
/// Checks for dictionary comprehensions that use a static key, like a string
9+
/// literal or a variable defined outside the comprehension.
10+
///
11+
/// ## Why is this bad?
12+
/// Using a static key (like a string literal) in a dictionary comprehension
13+
/// is usually a mistake, as it will result in a dictionary with only one key,
14+
/// despite the comprehension iterating over multiple values.
15+
///
16+
/// ## Example
17+
/// ```python
18+
/// data = ["some", "Data"]
19+
/// {"key": value.upper() for value in data}
20+
/// ```
21+
///
22+
/// Use instead:
23+
/// ```python
24+
/// data = ["some", "Data"]
25+
/// {value: value.upper() for value in data}
26+
/// ```
27+
///
28+
/// [B035]: https://docs.astral.sh/ruff/rules/static-key-dict-comprehension/
29+
#[violation]
30+
pub struct RuffStaticKeyDictComprehension;
31+
32+
impl Violation for RuffStaticKeyDictComprehension {
33+
#[derive_message_formats]
34+
fn message(&self) -> String {
35+
format!("Dictionary comprehension uses static key")
36+
}
37+
}

crates/ruff_workspace/src/configuration.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ impl LintConfiguration {
951951
}
952952
}
953953

954-
let removed_selectors = removed_selectors.iter().collect::<Vec<_>>();
954+
let removed_selectors = removed_selectors.iter().sorted().collect::<Vec<_>>();
955955
match removed_selectors.as_slice() {
956956
[] => (),
957957
[selection] => {
@@ -974,7 +974,7 @@ impl LintConfiguration {
974974
}
975975
}
976976

977-
for (from, target) in redirects {
977+
for (from, target) in redirects.iter().sorted_by_key(|item| item.0) {
978978
// TODO(martin): This belongs into the ruff crate.
979979
warn_user_once_by_id!(
980980
from,
@@ -984,7 +984,10 @@ impl LintConfiguration {
984984
);
985985
}
986986

987-
let deprecated_nursery_selectors = deprecated_nursery_selectors.iter().collect::<Vec<_>>();
987+
let deprecated_nursery_selectors = deprecated_nursery_selectors
988+
.iter()
989+
.sorted()
990+
.collect::<Vec<_>>();
988991
match deprecated_nursery_selectors.as_slice() {
989992
[] => (),
990993
[selection] => {
@@ -1005,14 +1008,14 @@ impl LintConfiguration {
10051008
}
10061009

10071010
if preview.mode.is_disabled() {
1008-
for selection in deprecated_selectors {
1011+
for selection in deprecated_selectors.iter().sorted() {
10091012
let (prefix, code) = selection.prefix_and_code();
10101013
warn_user!(
10111014
"Rule `{prefix}{code}` is deprecated and will be removed in a future release.",
10121015
);
10131016
}
10141017
} else {
1015-
let deprecated_selectors = deprecated_selectors.iter().collect::<Vec<_>>();
1018+
let deprecated_selectors = deprecated_selectors.iter().sorted().collect::<Vec<_>>();
10161019
match deprecated_selectors.as_slice() {
10171020
[] => (),
10181021
[selection] => {
@@ -1033,7 +1036,7 @@ impl LintConfiguration {
10331036
}
10341037
}
10351038

1036-
for selection in ignored_preview_selectors {
1039+
for selection in ignored_preview_selectors.iter().sorted() {
10371040
let (prefix, code) = selection.prefix_and_code();
10381041
warn_user!("Selection `{prefix}{code}` has no effect because preview is not enabled.",);
10391042
}

0 commit comments

Comments
 (0)