Compare commits

...

4 Commits

Author SHA1 Message Date
Micha Reiser
a6d62c4a7f F841: Stabalize unpacking support 2024-08-12 12:26:17 +02:00
Charlie Marsh
4ec340a40e Re-code unnecessary-dict-comprehension-for-iterable (RUF025) as C420 (#12533)
Closes https://github.com/astral-sh/ruff/issues/12110.
2024-08-12 11:27:05 +02:00
edhinard
a0bb459df2 add conventional xml.etree.ElementTree import alias (#12455) 2024-08-12 11:23:34 +02:00
Micha Reiser
87ee0e06ac Start feature branch for Ruff 0.6 2024-08-12 11:06:27 +02:00
23 changed files with 634 additions and 133 deletions

View File

@@ -260,6 +260,7 @@ linter.flake8_import_conventions.aliases = {
seaborn = sns,
tensorflow = tf,
tkinter = tk,
xml.etree.ElementTree = ET,
}
linter.flake8_import_conventions.banned_aliases = {}
linter.flake8_import_conventions.banned_from = []

View File

@@ -1498,7 +1498,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) {

View File

@@ -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);
@@ -378,6 +378,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),
@@ -951,7 +952,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),

View File

@@ -123,5 +123,7 @@ static REDIRECTS: Lazy<HashMap<&'static str, &'static str>> = 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"),
])
});

View File

@@ -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"))]

View File

@@ -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;

View File

@@ -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

View File

@@ -24,6 +24,7 @@ const CONVENTIONAL_ALIASES: &[(&str, &str)] = &[
("plotly.express", "px"),
("polars", "pl"),
("pyarrow", "pa"),
("xml.etree.ElementTree", "ET"),
];
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, CacheKey)]

View File

@@ -208,7 +208,6 @@ mod tests {
Ok(())
}
#[test_case(Rule::UnusedVariable, Path::new("F841_4.py"))]
#[test_case(Rule::UnusedImport, Path::new("__init__.py"))]
#[test_case(Rule::UnusedImport, Path::new("F401_24/__init__.py"))]
#[test_case(Rule::UnusedImport, Path::new("F401_25__all_nonempty/__init__.py"))]
@@ -1285,33 +1284,6 @@ mod tests {
);
}
#[test]
fn used_as_star_unpack() {
// In stable, starred names in unpack are used if RHS is not a tuple/list literal.
// In preview, these should be marked as unused.
flakes(
r"
def f():
a, *b = range(10)
",
&[],
);
flakes(
r"
def f():
(*a, b) = range(10)
",
&[],
);
flakes(
r"
def f():
[a, *b, c] = range(10)
",
&[],
);
}
#[test]
fn keyword_only_args() {
// Keyword-only arg names are defined.

View File

@@ -261,7 +261,6 @@ pub(crate) fn unused_variable(checker: &Checker, scope: &Scope, diagnostics: &mu
if (binding.kind.is_assignment()
|| binding.kind.is_named_expr_assignment()
|| binding.kind.is_with_item_var())
&& (!binding.is_unpacked_assignment() || checker.settings.preview.is_enabled())
&& binding.is_unused()
&& !binding.is_nonlocal()
&& !binding.is_global()

View File

@@ -99,6 +99,84 @@ F841_0.py:21:9: F841 [*] Local variable `b` is assigned to but never used
23 23 | bar = (1, 2)
24 24 | (c, d) = bar
F841_0.py:24:6: F841 [*] Local variable `c` is assigned to but never used
|
23 | bar = (1, 2)
24 | (c, d) = bar
| ^ F841
25 |
26 | (x, y) = baz = bar
|
= help: Remove assignment to unused variable `c`
Unsafe fix
21 21 | (a, b) = (1, 2)
22 22 |
23 23 | bar = (1, 2)
24 |- (c, d) = bar
24 |+ (_c, d) = bar
25 25 |
26 26 | (x, y) = baz = bar
27 27 |
F841_0.py:24:9: F841 [*] Local variable `d` is assigned to but never used
|
23 | bar = (1, 2)
24 | (c, d) = bar
| ^ F841
25 |
26 | (x, y) = baz = bar
|
= help: Remove assignment to unused variable `d`
Unsafe fix
21 21 | (a, b) = (1, 2)
22 22 |
23 23 | bar = (1, 2)
24 |- (c, d) = bar
24 |+ (c, _d) = bar
25 25 |
26 26 | (x, y) = baz = bar
27 27 |
F841_0.py:26:6: F841 [*] Local variable `x` is assigned to but never used
|
24 | (c, d) = bar
25 |
26 | (x, y) = baz = bar
| ^ F841
|
= help: Remove assignment to unused variable `x`
Unsafe fix
23 23 | bar = (1, 2)
24 24 | (c, d) = bar
25 25 |
26 |- (x, y) = baz = bar
26 |+ (_x, y) = baz = bar
27 27 |
28 28 |
29 29 | def f():
F841_0.py:26:9: F841 [*] Local variable `y` is assigned to but never used
|
24 | (c, d) = bar
25 |
26 | (x, y) = baz = bar
| ^ F841
|
= help: Remove assignment to unused variable `y`
Unsafe fix
23 23 | bar = (1, 2)
24 24 | (c, d) = bar
25 25 |
26 |- (x, y) = baz = bar
26 |+ (x, _y) = baz = bar
27 27 |
28 28 |
29 29 | def f():
F841_0.py:26:14: F841 [*] Local variable `baz` is assigned to but never used
|
24 | (c, d) = bar
@@ -139,6 +217,26 @@ F841_0.py:51:9: F841 [*] Local variable `b` is assigned to but never used
53 53 | def d():
54 54 | nonlocal b
F841_0.py:66:24: F841 Local variable `connection` is assigned to but never used
|
64 | return None, None
65 |
66 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
67 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`
F841_0.py:74:24: F841 Local variable `connection` is assigned to but never used
|
72 | return None, None
73 |
74 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
75 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`
F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
|
78 | def f():
@@ -158,6 +256,24 @@ F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
81 81 |
82 82 |
F841_0.py:79:49: F841 Local variable `this` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `this`
F841_0.py:79:55: F841 Local variable `that` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `that`
F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
|
83 | def f():
@@ -179,6 +295,28 @@ F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
87 87 | ):
88 88 | print("hello")
F841_0.py:86:23: F841 Local variable `this` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `this`
F841_0.py:86:29: F841 Local variable `that` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `that`
F841_0.py:102:5: F841 [*] Local variable `msg3` is assigned to but never used
|
100 | msg1 = "Hello, world!"
@@ -238,5 +376,3 @@ F841_0.py:127:21: F841 Local variable `value` is assigned to but never used
128 | print(key)
|
= help: Remove assignment to unused variable `value`

View File

@@ -1,6 +1,38 @@
---
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
---
F841_1.py:2:5: F841 [*] Local variable `x` is assigned to but never used
|
1 | def f(tup):
2 | x, y = tup
| ^ F841
|
= help: Remove assignment to unused variable `x`
Unsafe fix
1 1 | def f(tup):
2 |- x, y = tup
2 |+ _x, y = tup
3 3 |
4 4 |
5 5 | def f():
F841_1.py:2:8: F841 [*] Local variable `y` is assigned to but never used
|
1 | def f(tup):
2 | x, y = tup
| ^ F841
|
= help: Remove assignment to unused variable `y`
Unsafe fix
1 1 | def f(tup):
2 |- x, y = tup
2 |+ x, _y = tup
3 3 |
4 4 |
5 5 | def f():
F841_1.py:6:5: F841 [*] Local variable `x` is assigned to but never used
|
5 | def f():
@@ -37,6 +69,62 @@ F841_1.py:6:8: F841 [*] Local variable `y` is assigned to but never used
8 8 |
9 9 | def f():
F841_1.py:10:9: F841 [*] Local variable `y` is assigned to but never used
|
9 | def f():
10 | (x, y) = coords = 1, 2
| ^ F841
11 | if x > 1:
12 | print(coords)
|
= help: Remove assignment to unused variable `y`
Unsafe fix
7 7 |
8 8 |
9 9 | def f():
10 |- (x, y) = coords = 1, 2
10 |+ (x, _y) = coords = 1, 2
11 11 | if x > 1:
12 12 | print(coords)
13 13 |
F841_1.py:16:6: F841 [*] Local variable `x` is assigned to but never used
|
15 | def f():
16 | (x, y) = coords = 1, 2
| ^ F841
|
= help: Remove assignment to unused variable `x`
Unsafe fix
13 13 |
14 14 |
15 15 | def f():
16 |- (x, y) = coords = 1, 2
16 |+ (_x, y) = coords = 1, 2
17 17 |
18 18 |
19 19 | def f():
F841_1.py:16:9: F841 [*] Local variable `y` is assigned to but never used
|
15 | def f():
16 | (x, y) = coords = 1, 2
| ^ F841
|
= help: Remove assignment to unused variable `y`
Unsafe fix
13 13 |
14 14 |
15 15 | def f():
16 |- (x, y) = coords = 1, 2
16 |+ (x, _y) = coords = 1, 2
17 17 |
18 18 |
19 19 | def f():
F841_1.py:16:14: F841 [*] Local variable `coords` is assigned to but never used
|
15 | def f():
@@ -73,6 +161,42 @@ F841_1.py:20:5: F841 [*] Local variable `coords` is assigned to but never used
22 22 |
23 23 | def f():
F841_1.py:20:15: F841 [*] Local variable `x` is assigned to but never used
|
19 | def f():
20 | coords = (x, y) = 1, 2
| ^ F841
|
= help: Remove assignment to unused variable `x`
Unsafe fix
17 17 |
18 18 |
19 19 | def f():
20 |- coords = (x, y) = 1, 2
20 |+ coords = (_x, y) = 1, 2
21 21 |
22 22 |
23 23 | def f():
F841_1.py:20:18: F841 [*] Local variable `y` is assigned to but never used
|
19 | def f():
20 | coords = (x, y) = 1, 2
| ^ F841
|
= help: Remove assignment to unused variable `y`
Unsafe fix
17 17 |
18 18 |
19 19 | def f():
20 |- coords = (x, y) = 1, 2
20 |+ coords = (x, _y) = 1, 2
21 21 |
22 22 |
23 23 | def f():
F841_1.py:24:6: F841 [*] Local variable `a` is assigned to but never used
|
23 | def f():
@@ -132,5 +256,3 @@ F841_1.py:24:18: F841 [*] Local variable `y` is assigned to but never used
23 23 | def f():
24 |- (a, b) = (x, y) = 1, 2 # this triggers F841 on everything
24 |+ (a, b) = (x, _y) = 1, 2 # this triggers F841 on everything

View File

@@ -96,6 +96,26 @@ F841_3.py:21:19: F841 [*] Local variable `x1` is assigned to but never used
23 23 |
24 24 | with foo() as (x2, y2):
F841_3.py:24:20: F841 Local variable `x2` is assigned to but never used
|
22 | pass
23 |
24 | with foo() as (x2, y2):
| ^^ F841
25 | pass
|
= help: Remove assignment to unused variable `x2`
F841_3.py:24:24: F841 Local variable `y2` is assigned to but never used
|
22 | pass
23 |
24 | with foo() as (x2, y2):
| ^^ F841
25 | pass
|
= help: Remove assignment to unused variable `y2`
F841_3.py:27:20: F841 [*] Local variable `x3` is assigned to but never used
|
25 | pass
@@ -196,6 +216,46 @@ F841_3.py:32:10: F841 [*] Local variable `y1` is assigned to but never used
34 34 | coords3 = (x3, y3) = (1, 2)
35 35 |
F841_3.py:33:6: F841 [*] Local variable `x2` is assigned to but never used
|
31 | def f():
32 | (x1, y1) = (1, 2)
33 | (x2, y2) = coords2 = (1, 2)
| ^^ F841
34 | coords3 = (x3, y3) = (1, 2)
|
= help: Remove assignment to unused variable `x2`
Unsafe fix
30 30 |
31 31 | def f():
32 32 | (x1, y1) = (1, 2)
33 |- (x2, y2) = coords2 = (1, 2)
33 |+ (_x2, y2) = coords2 = (1, 2)
34 34 | coords3 = (x3, y3) = (1, 2)
35 35 |
36 36 |
F841_3.py:33:10: F841 [*] Local variable `y2` is assigned to but never used
|
31 | def f():
32 | (x1, y1) = (1, 2)
33 | (x2, y2) = coords2 = (1, 2)
| ^^ F841
34 | coords3 = (x3, y3) = (1, 2)
|
= help: Remove assignment to unused variable `y2`
Unsafe fix
30 30 |
31 31 | def f():
32 32 | (x1, y1) = (1, 2)
33 |- (x2, y2) = coords2 = (1, 2)
33 |+ (x2, _y2) = coords2 = (1, 2)
34 34 | coords3 = (x3, y3) = (1, 2)
35 35 |
36 36 |
F841_3.py:33:16: F841 [*] Local variable `coords2` is assigned to but never used
|
31 | def f():
@@ -235,6 +295,44 @@ F841_3.py:34:5: F841 [*] Local variable `coords3` is assigned to but never used
36 36 |
37 37 | def f():
F841_3.py:34:16: F841 [*] Local variable `x3` is assigned to but never used
|
32 | (x1, y1) = (1, 2)
33 | (x2, y2) = coords2 = (1, 2)
34 | coords3 = (x3, y3) = (1, 2)
| ^^ F841
|
= help: Remove assignment to unused variable `x3`
Unsafe fix
31 31 | def f():
32 32 | (x1, y1) = (1, 2)
33 33 | (x2, y2) = coords2 = (1, 2)
34 |- coords3 = (x3, y3) = (1, 2)
34 |+ coords3 = (_x3, y3) = (1, 2)
35 35 |
36 36 |
37 37 | def f():
F841_3.py:34:20: F841 [*] Local variable `y3` is assigned to but never used
|
32 | (x1, y1) = (1, 2)
33 | (x2, y2) = coords2 = (1, 2)
34 | coords3 = (x3, y3) = (1, 2)
| ^^ F841
|
= help: Remove assignment to unused variable `y3`
Unsafe fix
31 31 | def f():
32 32 | (x1, y1) = (1, 2)
33 33 | (x2, y2) = coords2 = (1, 2)
34 |- coords3 = (x3, y3) = (1, 2)
34 |+ coords3 = (x3, _y3) = (1, 2)
35 35 |
36 36 |
37 37 | def f():
F841_3.py:40:26: F841 [*] Local variable `x1` is assigned to but never used
|
38 | try:
@@ -397,6 +495,24 @@ F841_3.py:77:25: F841 [*] Local variable `cm` is assigned to but never used
79 79 |
80 80 |
F841_3.py:82:24: F841 Local variable `x` is assigned to but never used
|
81 | def f():
82 | with Nested(m) as (x, y):
| ^ F841
83 | pass
|
= help: Remove assignment to unused variable `x`
F841_3.py:82:27: F841 Local variable `y` is assigned to but never used
|
81 | def f():
82 | with Nested(m) as (x, y):
| ^ F841
83 | pass
|
= help: Remove assignment to unused variable `y`
F841_3.py:87:26: F841 [*] Local variable `cm` is assigned to but never used
|
86 | def f():
@@ -490,6 +606,78 @@ F841_3.py:102:5: F841 [*] Local variable `toplevel` is assigned to but never use
104 104 |
105 105 | def f():
F841_3.py:102:17: F841 [*] Local variable `a` is assigned to but never used
|
101 | def f():
102 | toplevel = (a, b) = lexer.get_token()
| ^ F841
|
= help: Remove assignment to unused variable `a`
Unsafe fix
99 99 |
100 100 |
101 101 | def f():
102 |- toplevel = (a, b) = lexer.get_token()
102 |+ toplevel = (_a, b) = lexer.get_token()
103 103 |
104 104 |
105 105 | def f():
F841_3.py:102:20: F841 [*] Local variable `b` is assigned to but never used
|
101 | def f():
102 | toplevel = (a, b) = lexer.get_token()
| ^ F841
|
= help: Remove assignment to unused variable `b`
Unsafe fix
99 99 |
100 100 |
101 101 | def f():
102 |- toplevel = (a, b) = lexer.get_token()
102 |+ toplevel = (a, _b) = lexer.get_token()
103 103 |
104 104 |
105 105 | def f():
F841_3.py:106:6: F841 [*] Local variable `a` is assigned to but never used
|
105 | def f():
106 | (a, b) = toplevel = lexer.get_token()
| ^ F841
|
= help: Remove assignment to unused variable `a`
Unsafe fix
103 103 |
104 104 |
105 105 | def f():
106 |- (a, b) = toplevel = lexer.get_token()
106 |+ (_a, b) = toplevel = lexer.get_token()
107 107 |
108 108 |
109 109 | def f():
F841_3.py:106:9: F841 [*] Local variable `b` is assigned to but never used
|
105 | def f():
106 | (a, b) = toplevel = lexer.get_token()
| ^ F841
|
= help: Remove assignment to unused variable `b`
Unsafe fix
103 103 |
104 104 |
105 105 | def f():
106 |- (a, b) = toplevel = lexer.get_token()
106 |+ (a, _b) = toplevel = lexer.get_token()
107 107 |
108 108 |
109 109 | def f():
F841_3.py:106:14: F841 [*] Local variable `toplevel` is assigned to but never used
|
105 | def f():
@@ -712,5 +900,3 @@ F841_3.py:173:6: F841 [*] Local variable `x` is assigned to but never used
172 172 | ((x)) = foo()
173 |- (x) = (y.z) = foo()
173 |+ (y.z) = foo()

View File

@@ -20,4 +20,40 @@ F841_4.py:12:5: F841 [*] Local variable `a` is assigned to but never used
14 14 |
15 15 |
F841_4.py:13:5: F841 [*] Local variable `b` is assigned to but never used
|
11 | def bar():
12 | a = foo()
13 | b, c = foo()
| ^ F841
|
= help: Remove assignment to unused variable `b`
Unsafe fix
10 10 |
11 11 | def bar():
12 12 | a = foo()
13 |- b, c = foo()
13 |+ _b, c = foo()
14 14 |
15 15 |
16 16 | def baz():
F841_4.py:13:8: F841 [*] Local variable `c` is assigned to but never used
|
11 | def bar():
12 | a = foo()
13 | b, c = foo()
| ^ F841
|
= help: Remove assignment to unused variable `c`
Unsafe fix
10 10 |
11 11 | def bar():
12 12 | a = foo()
13 |- b, c = foo()
13 |+ b, _c = foo()
14 14 |
15 15 |
16 16 | def baz():

View File

@@ -60,6 +60,44 @@ F841_0.py:21:9: F841 Local variable `b` is assigned to but never used
|
= help: Remove assignment to unused variable `b`
F841_0.py:24:6: F841 Local variable `c` is assigned to but never used
|
23 | bar = (1, 2)
24 | (c, d) = bar
| ^ F841
25 |
26 | (x, y) = baz = bar
|
= help: Remove assignment to unused variable `c`
F841_0.py:24:9: F841 Local variable `d` is assigned to but never used
|
23 | bar = (1, 2)
24 | (c, d) = bar
| ^ F841
25 |
26 | (x, y) = baz = bar
|
= help: Remove assignment to unused variable `d`
F841_0.py:26:6: F841 Local variable `x` is assigned to but never used
|
24 | (c, d) = bar
25 |
26 | (x, y) = baz = bar
| ^ F841
|
= help: Remove assignment to unused variable `x`
F841_0.py:26:9: F841 Local variable `y` is assigned to but never used
|
24 | (c, d) = bar
25 |
26 | (x, y) = baz = bar
| ^ F841
|
= help: Remove assignment to unused variable `y`
F841_0.py:26:14: F841 [*] Local variable `baz` is assigned to but never used
|
24 | (c, d) = bar
@@ -156,6 +194,26 @@ F841_0.py:51:9: F841 [*] Local variable `b` is assigned to but never used
53 53 | def d():
54 54 | nonlocal b
F841_0.py:66:24: F841 Local variable `connection` is assigned to but never used
|
64 | return None, None
65 |
66 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
67 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`
F841_0.py:74:24: F841 Local variable `connection` is assigned to but never used
|
72 | return None, None
73 |
74 | with connect() as (connection, cursor):
| ^^^^^^^^^^ F841
75 | cursor.execute("SELECT * FROM users")
|
= help: Remove assignment to unused variable `connection`
F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
|
78 | def f():
@@ -175,6 +233,24 @@ F841_0.py:79:26: F841 [*] Local variable `my_file` is assigned to but never used
81 81 |
82 82 |
F841_0.py:79:49: F841 Local variable `this` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `this`
F841_0.py:79:55: F841 Local variable `that` is assigned to but never used
|
78 | def f():
79 | with open("file") as my_file, open("") as ((this, that)):
| ^^^^ F841
80 | print("hello")
|
= help: Remove assignment to unused variable `that`
F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
|
83 | def f():
@@ -196,6 +272,28 @@ F841_0.py:85:25: F841 [*] Local variable `my_file` is assigned to but never used
87 87 | ):
88 88 | print("hello")
F841_0.py:86:23: F841 Local variable `this` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `this`
F841_0.py:86:29: F841 Local variable `that` is assigned to but never used
|
84 | with (
85 | open("file") as my_file,
86 | open("") as ((this, that)),
| ^^^^ F841
87 | ):
88 | print("hello")
|
= help: Remove assignment to unused variable `that`
F841_0.py:102:5: F841 [*] Local variable `msg3` is assigned to but never used
|
100 | msg1 = "Hello, world!"
@@ -273,5 +371,3 @@ F841_0.py:152:25: F841 [*] Local variable `_` is assigned to but never used
152 |- except Exception as _:
152 |+ except Exception:
153 153 | pass

View File

@@ -1,61 +0,0 @@
---
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
---
F841_4.py:12:5: F841 [*] Local variable `a` is assigned to but never used
|
11 | def bar():
12 | a = foo()
| ^ F841
13 | b, c = foo()
|
= help: Remove assignment to unused variable `a`
Unsafe fix
9 9 |
10 10 |
11 11 | def bar():
12 |- a = foo()
12 |+ foo()
13 13 | b, c = foo()
14 14 |
15 15 |
F841_4.py:13:5: F841 [*] Local variable `b` is assigned to but never used
|
11 | def bar():
12 | a = foo()
13 | b, c = foo()
| ^ F841
|
= help: Remove assignment to unused variable `b`
Unsafe fix
10 10 |
11 11 | def bar():
12 12 | a = foo()
13 |- b, c = foo()
13 |+ _b, c = foo()
14 14 |
15 15 |
16 16 | def baz():
F841_4.py:13:8: F841 [*] Local variable `c` is assigned to but never used
|
11 | def bar():
12 | a = foo()
13 | b, c = foo()
| ^ F841
|
= help: Remove assignment to unused variable `c`
Unsafe fix
10 10 |
11 11 | def bar():
12 12 | a = foo()
13 |- b, c = foo()
13 |+ b, _c = foo()
14 14 |
15 15 |
16 16 | def baz():

View File

@@ -49,7 +49,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"))]

View File

@@ -24,7 +24,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::*;
@@ -61,7 +60,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;

View File

@@ -130,13 +130,23 @@ impl PythonVersion {
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, CacheKey, is_macro::Is)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, CacheKey)]
pub enum PreviewMode {
#[default]
Disabled,
Enabled,
}
impl PreviewMode {
pub const fn is_enabled(self) -> bool {
matches!(self, PreviewMode::Enabled)
}
pub const fn is_disabled(self) -> bool {
matches!(self, PreviewMode::Disabled)
}
}
impl From<bool> for PreviewMode {
fn from(version: bool) -> Self {
if version {

View File

@@ -1306,7 +1306,7 @@ pub struct Flake8ImportConventionsOptions {
/// The conventional aliases for imports. These aliases can be extended by
/// the [`extend-aliases`](#lint_flake8-import-conventions_extend-aliases) option.
#[option(
default = r#"{"altair": "alt", "matplotlib": "mpl", "matplotlib.pyplot": "plt", "numpy": "np", "pandas": "pd", "seaborn": "sns", "tensorflow": "tf", "tkinter": "tk", "holoviews": "hv", "panel": "pn", "plotly.express": "px", "polars": "pl", "pyarrow": "pa"}"#,
default = r#"{"altair": "alt", "matplotlib": "mpl", "matplotlib.pyplot": "plt", "numpy": "np", "pandas": "pd", "seaborn": "sns", "tensorflow": "tf", "tkinter": "tk", "holoviews": "hv", "panel": "pn", "plotly.express": "px", "polars": "pl", "pyarrow": "pa", "xml.etree.ElementTree": "ET"}"#,
value_type = "dict[str, str]",
scope = "aliases",
example = r#"

3
ruff.schema.json generated
View File

@@ -2833,6 +2833,8 @@
"C417",
"C418",
"C419",
"C42",
"C420",
"C9",
"C90",
"C901",
@@ -3728,7 +3730,6 @@
"RUF022",
"RUF023",
"RUF024",
"RUF025",
"RUF026",
"RUF027",
"RUF028",