mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 21:35:58 +00:00
[ruff] Do not remove parens for tuples with starred expressions in Python <=3.10 RUF031
(#12784)
This commit is contained in:
parent
253474b312
commit
b595346213
6 changed files with 226 additions and 3 deletions
|
@ -28,4 +28,9 @@ d[1,]
|
|||
d[(1,)]
|
||||
d[()] # empty tuples should be ignored
|
||||
d[:,] # slices in the subscript lead to syntax error if parens are added
|
||||
d[1,2,:]
|
||||
d[1,2,:]
|
||||
|
||||
# Should keep these parentheses in
|
||||
# Python <=3.10 to avoid syntax error.
|
||||
# https://github.com/astral-sh/ruff/issues/12776
|
||||
d[(*foo,bar)]
|
|
@ -28,4 +28,9 @@ d[(1,)]
|
|||
d[()] # empty tuples should be ignored
|
||||
|
||||
d[:,] # slices in the subscript lead to syntax error if parens are added
|
||||
d[1,2,:]
|
||||
d[1,2,:]
|
||||
|
||||
# Should keep these parentheses in
|
||||
# Python <=3.10 to avoid syntax error.
|
||||
# https://github.com/astral-sh/ruff/issues/12776
|
||||
d[(*foo,bar)]
|
|
@ -84,6 +84,22 @@ mod tests {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_remove_parentheses_starred_expr_py310() -> Result<()> {
|
||||
let diagnostics = test_path(
|
||||
Path::new("ruff/RUF031.py"),
|
||||
&LinterSettings {
|
||||
ruff: super::settings::Settings {
|
||||
parenthesize_tuple_in_subscript: false,
|
||||
},
|
||||
target_version: PythonVersion::Py310,
|
||||
..LinterSettings::for_rule(Rule::IncorrectlyParenthesizedTupleInSubscript)
|
||||
},
|
||||
)?;
|
||||
assert_messages!(diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Path::new("RUF013_0.py"))]
|
||||
#[test_case(Path::new("RUF013_1.py"))]
|
||||
fn implicit_optional_py39(path: &Path) -> Result<()> {
|
||||
|
|
|
@ -3,7 +3,7 @@ use ruff_macros::{derive_message_formats, violation};
|
|||
use ruff_python_ast::{Expr, ExprSubscript};
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::{checkers::ast::Checker, settings::types::PythonVersion};
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for consistent style regarding whether nonempty tuples in subscripts
|
||||
|
@ -68,6 +68,16 @@ pub(crate) fn subscript_with_parenthesized_tuple(checker: &mut Checker, subscrip
|
|||
if prefer_parentheses && tuple_subscript.elts.iter().any(Expr::is_slice_expr) {
|
||||
return;
|
||||
}
|
||||
// Removing parentheses in the presence of unpacking leads
|
||||
// to a syntax error in Python 3.10.
|
||||
// This is no longer a syntax error starting in Python 3.11
|
||||
// see https://peps.python.org/pep-0646/#change-1-star-expressions-in-indexes
|
||||
if checker.settings.target_version <= PythonVersion::Py310
|
||||
&& !prefer_parentheses
|
||||
&& tuple_subscript.elts.iter().any(Expr::is_starred_expr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
let locator = checker.locator();
|
||||
let source_range = subscript.slice.range();
|
||||
let new_source = if prefer_parentheses {
|
||||
|
|
|
@ -169,3 +169,19 @@ RUF031.py:28:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
|||
29 29 | d[()] # empty tuples should be ignored
|
||||
30 30 | d[:,] # slices in the subscript lead to syntax error if parens are added
|
||||
31 31 | d[1,2,:]
|
||||
|
||||
RUF031.py:36:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
34 | # Python <=3.10 to avoid syntax error.
|
||||
35 | # https://github.com/astral-sh/ruff/issues/12776
|
||||
36 | d[(*foo,bar)]
|
||||
| ^^^^^^^^^^ RUF031
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
33 33 | # Should keep these parentheses in
|
||||
34 34 | # Python <=3.10 to avoid syntax error.
|
||||
35 35 | # https://github.com/astral-sh/ruff/issues/12776
|
||||
36 |-d[(*foo,bar)]
|
||||
36 |+d[*foo,bar]
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
---
|
||||
RUF031.py:2:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
1 | d = {(1,2):"a",(3,4):"b",(5,6,7):"c",(8,):"d"}
|
||||
2 | d[(1,2)]
|
||||
| ^^^^^ RUF031
|
||||
3 | d[(
|
||||
4 | 1,
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | d = {(1,2):"a",(3,4):"b",(5,6,7):"c",(8,):"d"}
|
||||
2 |-d[(1,2)]
|
||||
2 |+d[1,2]
|
||||
3 3 | d[(
|
||||
4 4 | 1,
|
||||
5 5 | 2
|
||||
|
||||
RUF031.py:3:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
1 | d = {(1,2):"a",(3,4):"b",(5,6,7):"c",(8,):"d"}
|
||||
2 | d[(1,2)]
|
||||
3 | d[(
|
||||
| ___^
|
||||
4 | | 1,
|
||||
5 | | 2
|
||||
6 | | )]
|
||||
| |_^ RUF031
|
||||
7 | d[
|
||||
8 | 1,
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
1 1 | d = {(1,2):"a",(3,4):"b",(5,6,7):"c",(8,):"d"}
|
||||
2 2 | d[(1,2)]
|
||||
3 |-d[(
|
||||
3 |+d[
|
||||
4 4 | 1,
|
||||
5 5 | 2
|
||||
6 |-)]
|
||||
6 |+]
|
||||
7 7 | d[
|
||||
8 8 | 1,
|
||||
9 9 | 2
|
||||
|
||||
RUF031.py:11:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
9 | 2
|
||||
10 | ]
|
||||
11 | d[(2,4)]
|
||||
| ^^^^^ RUF031
|
||||
12 | d[(5,6,7)]
|
||||
13 | d[(8,)]
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
8 8 | 1,
|
||||
9 9 | 2
|
||||
10 10 | ]
|
||||
11 |-d[(2,4)]
|
||||
11 |+d[2,4]
|
||||
12 12 | d[(5,6,7)]
|
||||
13 13 | d[(8,)]
|
||||
14 14 | d[tuple(1,2)]
|
||||
|
||||
RUF031.py:12:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
10 | ]
|
||||
11 | d[(2,4)]
|
||||
12 | d[(5,6,7)]
|
||||
| ^^^^^^^ RUF031
|
||||
13 | d[(8,)]
|
||||
14 | d[tuple(1,2)]
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
9 9 | 2
|
||||
10 10 | ]
|
||||
11 11 | d[(2,4)]
|
||||
12 |-d[(5,6,7)]
|
||||
12 |+d[5,6,7]
|
||||
13 13 | d[(8,)]
|
||||
14 14 | d[tuple(1,2)]
|
||||
15 15 | d[tuple(8)]
|
||||
|
||||
RUF031.py:13:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
11 | d[(2,4)]
|
||||
12 | d[(5,6,7)]
|
||||
13 | d[(8,)]
|
||||
| ^^^^ RUF031
|
||||
14 | d[tuple(1,2)]
|
||||
15 | d[tuple(8)]
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
10 10 | ]
|
||||
11 11 | d[(2,4)]
|
||||
12 12 | d[(5,6,7)]
|
||||
13 |-d[(8,)]
|
||||
13 |+d[8,]
|
||||
14 14 | d[tuple(1,2)]
|
||||
15 15 | d[tuple(8)]
|
||||
16 16 | d[1,2]
|
||||
|
||||
RUF031.py:20:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
18 | d[5,6,7]
|
||||
19 | e = {((1,2),(3,4)):"a"}
|
||||
20 | e[((1,2),(3,4))]
|
||||
| ^^^^^^^^^^^^^ RUF031
|
||||
21 | e[(1,2),(3,4)]
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
17 17 | d[3,4]
|
||||
18 18 | d[5,6,7]
|
||||
19 19 | e = {((1,2),(3,4)):"a"}
|
||||
20 |-e[((1,2),(3,4))]
|
||||
21 20 | e[(1,2),(3,4)]
|
||||
21 |+e[(1,2),(3,4)]
|
||||
22 22 |
|
||||
23 23 | token_features[
|
||||
24 24 | (window_position, feature_name)
|
||||
|
||||
RUF031.py:24:5: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
23 | token_features[
|
||||
24 | (window_position, feature_name)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF031
|
||||
25 | ] = self._extract_raw_features_from_token
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
21 21 | e[(1,2),(3,4)]
|
||||
22 22 |
|
||||
23 23 | token_features[
|
||||
24 |- (window_position, feature_name)
|
||||
24 |+ window_position, feature_name
|
||||
25 25 | ] = self._extract_raw_features_from_token
|
||||
26 26 |
|
||||
27 27 | d[1,]
|
||||
|
||||
RUF031.py:28:3: RUF031 [*] Avoid parentheses for tuples in subscripts.
|
||||
|
|
||||
27 | d[1,]
|
||||
28 | d[(1,)]
|
||||
| ^^^^ RUF031
|
||||
29 | d[()] # empty tuples should be ignored
|
||||
30 | d[:,] # slices in the subscript lead to syntax error if parens are added
|
||||
|
|
||||
= help: Remove the parentheses.
|
||||
|
||||
ℹ Safe fix
|
||||
25 25 | ] = self._extract_raw_features_from_token
|
||||
26 26 |
|
||||
27 27 | d[1,]
|
||||
28 |-d[(1,)]
|
||||
28 |+d[1,]
|
||||
29 29 | d[()] # empty tuples should be ignored
|
||||
30 30 | d[:,] # slices in the subscript lead to syntax error if parens are added
|
||||
31 31 | d[1,2,:]
|
Loading…
Add table
Add a link
Reference in a new issue