From 9a078654a6502145d6eae6860b8ac0cfcebd372e Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sat, 20 May 2023 23:01:50 +0900 Subject: [PATCH 01/19] Added problematic case to the fixture. --- .../ruff/resources/test/fixtures/ruff/RUF005.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/ruff/RUF005.py b/crates/ruff/resources/test/fixtures/ruff/RUF005.py index e8ecc06b16e61..a6f37dd4fe09d 100644 --- a/crates/ruff/resources/test/fixtures/ruff/RUF005.py +++ b/crates/ruff/resources/test/fixtures/ruff/RUF005.py @@ -4,6 +4,7 @@ class Fun: def yay(self): return self.words + yay = Fun().yay foo = [4, 5, 6] @@ -13,11 +14,11 @@ def yay(self): spam = quux + (10, 11, 12) spom = list(spam) eggs = spom + [13, 14, 15] -elatement = ("we all say", ) + yay() -excitement = ("we all think", ) + Fun().yay() -astonishment = ("we all feel", ) + Fun.words +elatement = ("we all say",) + yay() +excitement = ("we all think",) + Fun().yay() +astonishment = ("we all feel",) + Fun.words -chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) +chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) baz = () + zoob @@ -38,11 +39,11 @@ def yay(self): 6, ] -[] + foo + [ -] +[] + foo + [] -[] + foo + [ # This will be preserved, but doesn't prevent the fix -] +[] + foo + [] # This will be preserved, but doesn't prevent the fix # Uses the non-preferred quote style, which should be retained. f"{[*a(), 'b']}" + +pylint_call = [sys.executable, "-m", "pylint"] + args + [path] From acaeeb615b90fac8da72eb6ad78511294e743d63 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 21 May 2023 02:54:43 +0900 Subject: [PATCH 02/19] Added first draft of a solution. wip. --- .../rules/collection_literal_concatenation.rs | 134 ++++++++++++------ 1 file changed, 90 insertions(+), 44 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 4f868b30838e6..ee8120ec85991 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -1,3 +1,5 @@ +use std::dbg; + use ruff_text_size::TextRange; use rustpython_parser::ast::{self, Expr, ExprContext, Operator, Ranged}; @@ -54,65 +56,84 @@ enum Kind { Tuple, } -/// RUF005 -/// This suggestion could be unsafe if the non-literal expression in the -/// expression has overridden the `__add__` (or `__radd__`) magic methods. -pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { +fn build_new_expr(expr: &Expr) -> Option { let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { - return; + return None; }; + let new_left = match left.as_ref() { + Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(left) { + Some(new_left) => new_left.to_owned(), + None => *left.to_owned(), + }, + _ => *left.to_owned(), + }; + + let new_right = match right.as_ref() { + Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(right) { + Some(new_right) => { + dbg!("AAAAAAA"); + new_right.to_owned() + } + None => *right.to_owned(), + }, + _ => *right.to_owned(), + }; + + // dbg!(&new_left); + // dbg!(&new_right); + // Figure out which way the splat is, and what the kind of the collection is. - let (kind, splat_element, other_elements, splat_at_left, ctx) = - match (left.as_ref(), right.as_ref()) { - ( - Expr::List(ast::ExprList { - elts: l_elts, - ctx, - range: _, - }), - _, - ) => (Kind::List, right, l_elts, false, ctx), - ( - Expr::Tuple(ast::ExprTuple { - elts: l_elts, - ctx, - range: _, - }), - _, - ) => (Kind::Tuple, right, l_elts, false, ctx), - ( - _, - Expr::List(ast::ExprList { - elts: r_elts, - ctx, - range: _, - }), - ) => (Kind::List, left, r_elts, true, ctx), - ( - _, - Expr::Tuple(ast::ExprTuple { - elts: r_elts, - ctx, - range: _, - }), - ) => (Kind::Tuple, left, r_elts, true, ctx), - _ => return, - }; + let (kind, splat_element, other_elements, splat_at_left, ctx) = match (&new_left, &new_right) { + ( + Expr::List(ast::ExprList { + elts: l_elts, + ctx, + range: _, + }), + _, + ) => (Kind::List, new_right, l_elts, false, ctx), + ( + Expr::Tuple(ast::ExprTuple { + elts: l_elts, + ctx, + range: _, + }), + _, + ) => (Kind::Tuple, new_right, l_elts, false, ctx), + ( + _, + Expr::List(ast::ExprList { + elts: r_elts, + ctx, + range: _, + }), + ) => (Kind::List, new_left, r_elts, true, ctx), + ( + _, + Expr::Tuple(ast::ExprTuple { + elts: r_elts, + ctx, + range: _, + }), + ) => (Kind::Tuple, new_left, r_elts, true, ctx), + _ => return None, + }; // We'll be a bit conservative here; only calls, names and attribute accesses // will be considered as splat elements. if !(splat_element.is_call_expr() || splat_element.is_name_expr() + || splat_element.is_list_expr() || splat_element.is_attribute_expr()) { - return; + return None; } let new_expr = match kind { Kind::List => { let node = ast::ExprList { - elts: make_splat_elts(splat_element, other_elements, splat_at_left), + elts: make_splat_elts(&splat_element, &other_elements, splat_at_left), ctx: *ctx, range: TextRange::default(), }; @@ -120,7 +141,7 @@ pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Exp } Kind::Tuple => { let node = ast::ExprTuple { - elts: make_splat_elts(splat_element, other_elements, splat_at_left), + elts: make_splat_elts(&splat_element, &other_elements, splat_at_left), ctx: *ctx, range: TextRange::default(), }; @@ -128,6 +149,31 @@ pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Exp } }; + return Some(new_expr); +} + +/// RUF005 +/// This suggestion could be unsafe if the non-literal expression in the +/// expression has overridden the `__add__` (or `__radd__`) magic methods. +pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { + let Some(new_expr) = build_new_expr(expr) else { + return + }; + + // dbg!(&new_expr); + + let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { + return; + }; + + let kind = match (left.as_ref(), right.as_ref()) { + (Expr::List(ast::ExprList { .. }), _) => Kind::List, + (Expr::Tuple(ast::ExprTuple { .. }), _) => Kind::Tuple, + (_, Expr::List(ast::ExprList { .. })) => Kind::List, + (_, Expr::Tuple(ast::ExprTuple { .. })) => Kind::Tuple, + _ => return, + }; + let contents = match kind { // Wrap the new expression in parentheses if it was a tuple Kind::Tuple => format!("({})", checker.generator().expr(&new_expr)), From bc25d52dbd2f4a77be4dba9fea24bb6ee19b082a Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 21 May 2023 03:26:00 +0900 Subject: [PATCH 03/19] Somewhat working, needs cleanup (and deduplication). --- .../rules/collection_literal_concatenation.rs | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index ee8120ec85991..a38835f607dfe 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -85,6 +85,24 @@ fn build_new_expr(expr: &Expr) -> Option { // Figure out which way the splat is, and what the kind of the collection is. let (kind, splat_element, other_elements, splat_at_left, ctx) = match (&new_left, &new_right) { + // ( + // Expr::List(ast::ExprList { + // elts: l_elts, + // ctx, + // range: _, + // }), + // Expr::List(ast::ExprList { elts: r_elts, .. }), + // _, + // ) => (Kind::List, l_elts, r_elts, false, ctx), + // ( + // Expr::Tuple(ast::ExprTuple { + // elts: l_elts, + // ctx, + // range: _, + // }), + // Expr::Tuple(ast::ExprTuple { elts: r_elts, .. }), + // _, + // ) => (Kind::Tuple, l_elts, r_elts, false, ctx), ( Expr::List(ast::ExprList { elts: l_elts, @@ -92,7 +110,7 @@ fn build_new_expr(expr: &Expr) -> Option { range: _, }), _, - ) => (Kind::List, new_right, l_elts, false, ctx), + ) => (Kind::List, &new_right, l_elts, false, ctx), ( Expr::Tuple(ast::ExprTuple { elts: l_elts, @@ -100,7 +118,7 @@ fn build_new_expr(expr: &Expr) -> Option { range: _, }), _, - ) => (Kind::Tuple, new_right, l_elts, false, ctx), + ) => (Kind::Tuple, &new_right, l_elts, false, ctx), ( _, Expr::List(ast::ExprList { @@ -108,7 +126,7 @@ fn build_new_expr(expr: &Expr) -> Option { ctx, range: _, }), - ) => (Kind::List, new_left, r_elts, true, ctx), + ) => (Kind::List, &new_left, r_elts, true, ctx), ( _, Expr::Tuple(ast::ExprTuple { @@ -116,24 +134,42 @@ fn build_new_expr(expr: &Expr) -> Option { ctx, range: _, }), - ) => (Kind::Tuple, new_left, r_elts, true, ctx), + ) => (Kind::Tuple, &new_left, r_elts, true, ctx), _ => return None, }; // We'll be a bit conservative here; only calls, names and attribute accesses // will be considered as splat elements. - if !(splat_element.is_call_expr() + let mut new_elts; + if splat_element.is_call_expr() || splat_element.is_name_expr() - || splat_element.is_list_expr() - || splat_element.is_attribute_expr()) + || splat_element.is_attribute_expr() { + new_elts = make_splat_elts(&splat_element, &other_elements, splat_at_left); + } else if splat_element.is_list_expr() { + new_elts = other_elements.to_owned(); + + let mut elts = match splat_element { + Expr::List(ast::ExprList { elts, .. }) => elts.to_owned(), + Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.to_owned(), + _ => return None, + }; + + if splat_at_left { + elts.extend_from_slice(&new_elts); + new_elts = elts.to_vec(); + } else { + new_elts.extend_from_slice(&elts); + } + // new_elts = make_splat_elts(&splat_element, &other_elements, splat_at_left); + } else { return None; } let new_expr = match kind { Kind::List => { let node = ast::ExprList { - elts: make_splat_elts(&splat_element, &other_elements, splat_at_left), + elts: new_elts, ctx: *ctx, range: TextRange::default(), }; @@ -141,7 +177,7 @@ fn build_new_expr(expr: &Expr) -> Option { } Kind::Tuple => { let node = ast::ExprTuple { - elts: make_splat_elts(&splat_element, &other_elements, splat_at_left), + elts: new_elts, ctx: *ctx, range: TextRange::default(), }; From e270c7ddfbe1fbf87ab05ba07973404375043deb Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 21 May 2023 11:36:56 +0900 Subject: [PATCH 04/19] Fix tuples not being fixed. --- .../rules/collection_literal_concatenation.rs | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index a38835f607dfe..7872c0b34bd7e 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -80,29 +80,8 @@ fn build_new_expr(expr: &Expr) -> Option { _ => *right.to_owned(), }; - // dbg!(&new_left); - // dbg!(&new_right); - // Figure out which way the splat is, and what the kind of the collection is. let (kind, splat_element, other_elements, splat_at_left, ctx) = match (&new_left, &new_right) { - // ( - // Expr::List(ast::ExprList { - // elts: l_elts, - // ctx, - // range: _, - // }), - // Expr::List(ast::ExprList { elts: r_elts, .. }), - // _, - // ) => (Kind::List, l_elts, r_elts, false, ctx), - // ( - // Expr::Tuple(ast::ExprTuple { - // elts: l_elts, - // ctx, - // range: _, - // }), - // Expr::Tuple(ast::ExprTuple { elts: r_elts, .. }), - // _, - // ) => (Kind::Tuple, l_elts, r_elts, false, ctx), ( Expr::List(ast::ExprList { elts: l_elts, @@ -146,7 +125,7 @@ fn build_new_expr(expr: &Expr) -> Option { || splat_element.is_attribute_expr() { new_elts = make_splat_elts(&splat_element, &other_elements, splat_at_left); - } else if splat_element.is_list_expr() { + } else if splat_element.is_list_expr() || splat_element.is_tuple_expr() { new_elts = other_elements.to_owned(); let mut elts = match splat_element { @@ -196,8 +175,6 @@ pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Exp return }; - // dbg!(&new_expr); - let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { return; }; From 10f19f3bac3b7820929ccf20db92b4ef30c2f083 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 21 May 2023 12:03:39 +0900 Subject: [PATCH 05/19] Fix linting. --- .../rules/collection_literal_concatenation.rs | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 7872c0b34bd7e..afff2aaa25cfc 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -1,5 +1,3 @@ -use std::dbg; - use ruff_text_size::TextRange; use rustpython_parser::ast::{self, Expr, ExprContext, Operator, Ranged}; @@ -63,21 +61,18 @@ fn build_new_expr(expr: &Expr) -> Option { let new_left = match left.as_ref() { Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(left) { - Some(new_left) => new_left.to_owned(), - None => *left.to_owned(), + Some(new_left) => new_left, + None => *left.clone(), }, - _ => *left.to_owned(), + _ => *left.clone(), }; let new_right = match right.as_ref() { Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(right) { - Some(new_right) => { - dbg!("AAAAAAA"); - new_right.to_owned() - } - None => *right.to_owned(), + Some(new_right) => new_right, + None => *right.clone(), }, - _ => *right.to_owned(), + _ => *right.clone(), }; // Figure out which way the splat is, and what the kind of the collection is. @@ -124,23 +119,24 @@ fn build_new_expr(expr: &Expr) -> Option { || splat_element.is_name_expr() || splat_element.is_attribute_expr() { - new_elts = make_splat_elts(&splat_element, &other_elements, splat_at_left); - } else if splat_element.is_list_expr() || splat_element.is_tuple_expr() { - new_elts = other_elements.to_owned(); + new_elts = make_splat_elts(splat_element, other_elements, splat_at_left); + } + // If the splat element is itself a list/tuple, insert them in the other list/tuple. + else if splat_element.is_list_expr() || splat_element.is_tuple_expr() { + new_elts = other_elements.clone(); let mut elts = match splat_element { - Expr::List(ast::ExprList { elts, .. }) => elts.to_owned(), - Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.to_owned(), + Expr::List(ast::ExprList { elts, .. }) => elts.clone(), + Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.clone(), _ => return None, }; if splat_at_left { elts.extend_from_slice(&new_elts); - new_elts = elts.to_vec(); + new_elts = elts.clone(); } else { new_elts.extend_from_slice(&elts); } - // new_elts = make_splat_elts(&splat_element, &other_elements, splat_at_left); } else { return None; } @@ -164,7 +160,7 @@ fn build_new_expr(expr: &Expr) -> Option { } }; - return Some(new_expr); + Some(new_expr) } /// RUF005 From 1476cac0587d25c7c26f5b2fd2ed8066be4a0584 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 21 May 2023 12:04:48 +0900 Subject: [PATCH 06/19] Added 2 test fixtures. --- crates/ruff/resources/test/fixtures/ruff/RUF005.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/ruff/resources/test/fixtures/ruff/RUF005.py b/crates/ruff/resources/test/fixtures/ruff/RUF005.py index a6f37dd4fe09d..28aa09c58de60 100644 --- a/crates/ruff/resources/test/fixtures/ruff/RUF005.py +++ b/crates/ruff/resources/test/fixtures/ruff/RUF005.py @@ -47,3 +47,5 @@ def yay(self): f"{[*a(), 'b']}" pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +b = a + [2, 3] + [4] From 2e91326921da52e0d9f17225b30b118ccecfe93f Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 21 May 2023 12:08:55 +0900 Subject: [PATCH 07/19] Updated snapshot. --- ..._rules__ruff__tests__RUF005_RUF005.py.snap | 524 +++++++++++------- 1 file changed, 332 insertions(+), 192 deletions(-) diff --git a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap index bb508f24fa47e..fd22135169d04 100644 --- a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap +++ b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap @@ -1,271 +1,411 @@ --- source: crates/ruff/src/rules/ruff/mod.rs --- -RUF005.py:10:7: RUF005 [*] Consider `[1, 2, 3, *foo]` instead of concatenation +RUF005.py:11:7: RUF005 [*] Consider `[1, 2, 3, *foo]` instead of concatenation | -10 | foo = [4, 5, 6] -11 | bar = [1, 2, 3] + foo +11 | foo = [4, 5, 6] +12 | bar = [1, 2, 3] + foo | ^^^^^^^^^^^^^^^ RUF005 -12 | zoob = tuple(bar) -13 | quux = (7, 8, 9) + zoob +13 | zoob = tuple(bar) +14 | quux = (7, 8, 9) + zoob | = help: Replace with `[1, 2, 3, *foo]` ℹ Suggested fix -7 7 | yay = Fun().yay -8 8 | -9 9 | foo = [4, 5, 6] -10 |-bar = [1, 2, 3] + foo - 10 |+bar = [1, 2, 3, *foo] -11 11 | zoob = tuple(bar) -12 12 | quux = (7, 8, 9) + zoob -13 13 | spam = quux + (10, 11, 12) +8 8 | yay = Fun().yay +9 9 | +10 10 | foo = [4, 5, 6] +11 |-bar = [1, 2, 3] + foo + 11 |+bar = [1, 2, 3, *foo] +12 12 | zoob = tuple(bar) +13 13 | quux = (7, 8, 9) + zoob +14 14 | spam = quux + (10, 11, 12) -RUF005.py:12:8: RUF005 [*] Consider `(7, 8, 9, *zoob)` instead of concatenation +RUF005.py:13:8: RUF005 [*] Consider `(7, 8, 9, *zoob)` instead of concatenation | -12 | bar = [1, 2, 3] + foo -13 | zoob = tuple(bar) -14 | quux = (7, 8, 9) + zoob +13 | bar = [1, 2, 3] + foo +14 | zoob = tuple(bar) +15 | quux = (7, 8, 9) + zoob | ^^^^^^^^^^^^^^^^ RUF005 -15 | spam = quux + (10, 11, 12) -16 | spom = list(spam) +16 | spam = quux + (10, 11, 12) +17 | spom = list(spam) | = help: Replace with `(7, 8, 9, *zoob)` ℹ Suggested fix -9 9 | foo = [4, 5, 6] -10 10 | bar = [1, 2, 3] + foo -11 11 | zoob = tuple(bar) -12 |-quux = (7, 8, 9) + zoob - 12 |+quux = (7, 8, 9, *zoob) -13 13 | spam = quux + (10, 11, 12) -14 14 | spom = list(spam) -15 15 | eggs = spom + [13, 14, 15] +10 10 | foo = [4, 5, 6] +11 11 | bar = [1, 2, 3] + foo +12 12 | zoob = tuple(bar) +13 |-quux = (7, 8, 9) + zoob + 13 |+quux = (7, 8, 9, *zoob) +14 14 | spam = quux + (10, 11, 12) +15 15 | spom = list(spam) +16 16 | eggs = spom + [13, 14, 15] -RUF005.py:13:8: RUF005 [*] Consider `(*quux, 10, 11, 12)` instead of concatenation +RUF005.py:14:8: RUF005 [*] Consider `(*quux, 10, 11, 12)` instead of concatenation | -13 | zoob = tuple(bar) -14 | quux = (7, 8, 9) + zoob -15 | spam = quux + (10, 11, 12) +14 | zoob = tuple(bar) +15 | quux = (7, 8, 9) + zoob +16 | spam = quux + (10, 11, 12) | ^^^^^^^^^^^^^^^^^^^ RUF005 -16 | spom = list(spam) -17 | eggs = spom + [13, 14, 15] +17 | spom = list(spam) +18 | eggs = spom + [13, 14, 15] | = help: Replace with `(*quux, 10, 11, 12)` ℹ Suggested fix -10 10 | bar = [1, 2, 3] + foo -11 11 | zoob = tuple(bar) -12 12 | quux = (7, 8, 9) + zoob -13 |-spam = quux + (10, 11, 12) - 13 |+spam = (*quux, 10, 11, 12) -14 14 | spom = list(spam) -15 15 | eggs = spom + [13, 14, 15] -16 16 | elatement = ("we all say", ) + yay() - -RUF005.py:15:8: RUF005 [*] Consider `[*spom, 13, 14, 15]` instead of concatenation - | -15 | spam = quux + (10, 11, 12) -16 | spom = list(spam) -17 | eggs = spom + [13, 14, 15] +11 11 | bar = [1, 2, 3] + foo +12 12 | zoob = tuple(bar) +13 13 | quux = (7, 8, 9) + zoob +14 |-spam = quux + (10, 11, 12) + 14 |+spam = (*quux, 10, 11, 12) +15 15 | spom = list(spam) +16 16 | eggs = spom + [13, 14, 15] +17 17 | elatement = ("we all say",) + yay() + +RUF005.py:16:8: RUF005 [*] Consider `[*spom, 13, 14, 15]` instead of concatenation + | +16 | spam = quux + (10, 11, 12) +17 | spom = list(spam) +18 | eggs = spom + [13, 14, 15] | ^^^^^^^^^^^^^^^^^^^ RUF005 -18 | elatement = ("we all say", ) + yay() -19 | excitement = ("we all think", ) + Fun().yay() +19 | elatement = ("we all say",) + yay() +20 | excitement = ("we all think",) + Fun().yay() | = help: Replace with `[*spom, 13, 14, 15]` ℹ Suggested fix -12 12 | quux = (7, 8, 9) + zoob -13 13 | spam = quux + (10, 11, 12) -14 14 | spom = list(spam) -15 |-eggs = spom + [13, 14, 15] - 15 |+eggs = [*spom, 13, 14, 15] -16 16 | elatement = ("we all say", ) + yay() -17 17 | excitement = ("we all think", ) + Fun().yay() -18 18 | astonishment = ("we all feel", ) + Fun.words - -RUF005.py:16:13: RUF005 [*] Consider `("we all say", *yay())` instead of concatenation - | -16 | spom = list(spam) -17 | eggs = spom + [13, 14, 15] -18 | elatement = ("we all say", ) + yay() - | ^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -19 | excitement = ("we all think", ) + Fun().yay() -20 | astonishment = ("we all feel", ) + Fun.words +13 13 | quux = (7, 8, 9) + zoob +14 14 | spam = quux + (10, 11, 12) +15 15 | spom = list(spam) +16 |-eggs = spom + [13, 14, 15] + 16 |+eggs = [*spom, 13, 14, 15] +17 17 | elatement = ("we all say",) + yay() +18 18 | excitement = ("we all think",) + Fun().yay() +19 19 | astonishment = ("we all feel",) + Fun.words + +RUF005.py:17:13: RUF005 [*] Consider `("we all say", *yay())` instead of concatenation + | +17 | spom = list(spam) +18 | eggs = spom + [13, 14, 15] +19 | elatement = ("we all say",) + yay() + | ^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +20 | excitement = ("we all think",) + Fun().yay() +21 | astonishment = ("we all feel",) + Fun.words | = help: Replace with `("we all say", *yay())` ℹ Suggested fix -13 13 | spam = quux + (10, 11, 12) -14 14 | spom = list(spam) -15 15 | eggs = spom + [13, 14, 15] -16 |-elatement = ("we all say", ) + yay() - 16 |+elatement = ("we all say", *yay()) -17 17 | excitement = ("we all think", ) + Fun().yay() -18 18 | astonishment = ("we all feel", ) + Fun.words -19 19 | - -RUF005.py:17:14: RUF005 [*] Consider `("we all think", *Fun().yay())` instead of concatenation - | -17 | eggs = spom + [13, 14, 15] -18 | elatement = ("we all say", ) + yay() -19 | excitement = ("we all think", ) + Fun().yay() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -20 | astonishment = ("we all feel", ) + Fun.words +14 14 | spam = quux + (10, 11, 12) +15 15 | spom = list(spam) +16 16 | eggs = spom + [13, 14, 15] +17 |-elatement = ("we all say",) + yay() + 17 |+elatement = ("we all say", *yay()) +18 18 | excitement = ("we all think",) + Fun().yay() +19 19 | astonishment = ("we all feel",) + Fun.words +20 20 | + +RUF005.py:18:14: RUF005 [*] Consider `("we all think", *Fun().yay())` instead of concatenation + | +18 | eggs = spom + [13, 14, 15] +19 | elatement = ("we all say",) + yay() +20 | excitement = ("we all think",) + Fun().yay() + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +21 | astonishment = ("we all feel",) + Fun.words | = help: Replace with `("we all think", *Fun().yay())` ℹ Suggested fix -14 14 | spom = list(spam) -15 15 | eggs = spom + [13, 14, 15] -16 16 | elatement = ("we all say", ) + yay() -17 |-excitement = ("we all think", ) + Fun().yay() - 17 |+excitement = ("we all think", *Fun().yay()) -18 18 | astonishment = ("we all feel", ) + Fun.words -19 19 | -20 20 | chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) - -RUF005.py:18:16: RUF005 [*] Consider `("we all feel", *Fun.words)` instead of concatenation - | -18 | elatement = ("we all say", ) + yay() -19 | excitement = ("we all think", ) + Fun().yay() -20 | astonishment = ("we all feel", ) + Fun.words - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -21 | -22 | chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) +15 15 | spom = list(spam) +16 16 | eggs = spom + [13, 14, 15] +17 17 | elatement = ("we all say",) + yay() +18 |-excitement = ("we all think",) + Fun().yay() + 18 |+excitement = ("we all think", *Fun().yay()) +19 19 | astonishment = ("we all feel",) + Fun.words +20 20 | +21 21 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + +RUF005.py:19:16: RUF005 [*] Consider `("we all feel", *Fun.words)` instead of concatenation + | +19 | elatement = ("we all say",) + yay() +20 | excitement = ("we all think",) + Fun().yay() +21 | astonishment = ("we all feel",) + Fun.words + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +22 | +23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | = help: Replace with `("we all feel", *Fun.words)` ℹ Suggested fix -15 15 | eggs = spom + [13, 14, 15] -16 16 | elatement = ("we all say", ) + yay() -17 17 | excitement = ("we all think", ) + Fun().yay() -18 |-astonishment = ("we all feel", ) + Fun.words - 18 |+astonishment = ("we all feel", *Fun.words) -19 19 | -20 20 | chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) -21 21 | - -RUF005.py:20:9: RUF005 [*] Consider `["a", "b", "c", *eggs]` instead of concatenation - | -20 | astonishment = ("we all feel", ) + Fun.words -21 | -22 | chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) +16 16 | eggs = spom + [13, 14, 15] +17 17 | elatement = ("we all say",) + yay() +18 18 | excitement = ("we all think",) + Fun().yay() +19 |-astonishment = ("we all feel",) + Fun.words + 19 |+astonishment = ("we all feel", *Fun.words) +20 20 | +21 21 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +22 22 | + +RUF005.py:21:9: RUF005 [*] Consider `["a", "b", "c", *eggs]` instead of concatenation + | +21 | astonishment = ("we all feel",) + Fun.words +22 | +23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | ^^^^^^^^^^^^^^^^^^^^^^ RUF005 -23 | -24 | baz = () + zoob +24 | +25 | baz = () + zoob | = help: Replace with `["a", "b", "c", *eggs]` ℹ Suggested fix -17 17 | excitement = ("we all think", ) + Fun().yay() -18 18 | astonishment = ("we all feel", ) + Fun.words -19 19 | -20 |-chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) - 20 |+chain = ["a", "b", "c", *eggs] + list(('yes', 'no', 'pants') + zoob) -21 21 | -22 22 | baz = () + zoob -23 23 | - -RUF005.py:20:39: RUF005 [*] Consider `("yes", "no", "pants", *zoob)` instead of concatenation - | -20 | astonishment = ("we all feel", ) + Fun.words -21 | -22 | chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) +18 18 | excitement = ("we all think",) + Fun().yay() +19 19 | astonishment = ("we all feel",) + Fun.words +20 20 | +21 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + 21 |+chain = ["a", "b", "c", *eggs] + list(("yes", "no", "pants") + zoob) +22 22 | +23 23 | baz = () + zoob +24 24 | + +RUF005.py:21:39: RUF005 [*] Consider `("yes", "no", "pants", *zoob)` instead of concatenation + | +21 | astonishment = ("we all feel",) + Fun.words +22 | +23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -23 | -24 | baz = () + zoob +24 | +25 | baz = () + zoob | = help: Replace with `("yes", "no", "pants", *zoob)` ℹ Suggested fix -17 17 | excitement = ("we all think", ) + Fun().yay() -18 18 | astonishment = ("we all feel", ) + Fun.words -19 19 | -20 |-chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) - 20 |+chain = ['a', 'b', 'c'] + eggs + list(("yes", "no", "pants", *zoob)) -21 21 | -22 22 | baz = () + zoob -23 23 | - -RUF005.py:22:7: RUF005 [*] Consider `(*zoob,)` instead of concatenation - | -22 | chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) -23 | -24 | baz = () + zoob +18 18 | excitement = ("we all think",) + Fun().yay() +19 19 | astonishment = ("we all feel",) + Fun.words +20 20 | +21 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + 21 |+chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants", *zoob)) +22 22 | +23 23 | baz = () + zoob +24 24 | + +RUF005.py:23:7: RUF005 [*] Consider `(*zoob,)` instead of concatenation + | +23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +24 | +25 | baz = () + zoob | ^^^^^^^^^ RUF005 -25 | -26 | first = [ +26 | +27 | first = [ | = help: Replace with `(*zoob,)` ℹ Suggested fix -19 19 | -20 20 | chain = ['a', 'b', 'c'] + eggs + list(('yes', 'no', 'pants') + zoob) -21 21 | -22 |-baz = () + zoob - 22 |+baz = (*zoob,) -23 23 | -24 24 | first = [ -25 25 | # The order - -RUF005.py:32:10: RUF005 Consider `[*first, 4, 5, 6]` instead of concatenation - | -32 | # to preserve -33 | ] -34 | second = first + [ +20 20 | +21 21 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +22 22 | +23 |-baz = () + zoob + 23 |+baz = (*zoob,) +24 24 | +25 25 | first = [ +26 26 | # The order + +RUF005.py:33:10: RUF005 Consider `[*first, 4, 5, 6]` instead of concatenation + | +33 | # to preserve +34 | ] +35 | second = first + [ | __________^ -35 | | # please -36 | | 4, -37 | | # don't -38 | | 5, -39 | | # touch -40 | | 6, -41 | | ] +36 | | # please +37 | | 4, +38 | | # don't +39 | | 5, +40 | | # touch +41 | | 6, +42 | | ] | |_^ RUF005 -42 | -43 | [] + foo + [ +43 | +44 | [] + foo + [] | = help: Replace with `[*first, 4, 5, 6]` -RUF005.py:41:1: RUF005 [*] Consider `[*foo]` instead of concatenation +RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation + | +42 | ] +43 | +44 | [] + foo + [] + | ^^^^^^^^^^^^^ RUF005 +45 | +46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix | -41 | ] -42 | -43 | [] + foo + [ + = help: Replace with `[*foo]` + +ℹ Suggested fix +39 39 | 6, +40 40 | ] +41 41 | +42 |-[] + foo + [] + 42 |+[*foo] +43 43 | +44 44 | [] + foo + [] # This will be preserved, but doesn't prevent the fix +45 45 | + +RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation + | +42 | ] +43 | +44 | [] + foo + [] | ^^^^^^^^ RUF005 -44 | ] +45 | +46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix | = help: Replace with `[*foo]` ℹ Suggested fix -38 38 | 6, -39 39 | ] -40 40 | -41 |-[] + foo + [ - 41 |+[*foo] + [ -42 42 | ] +39 39 | 6, +40 40 | ] +41 41 | +42 |-[] + foo + [] + 42 |+[*foo] + [] 43 43 | -44 44 | [] + foo + [ # This will be preserved, but doesn't prevent the fix +44 44 | [] + foo + [] # This will be preserved, but doesn't prevent the fix +45 45 | + +RUF005.py:44:1: RUF005 Consider `[*foo]` instead of concatenation + | +44 | [] + foo + [] +45 | +46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix + | ^^^^^^^^^^^^^ RUF005 +47 | +48 | # Uses the non-preferred quote style, which should be retained. + | + = help: Replace with `[*foo]` RUF005.py:44:1: RUF005 [*] Consider `[*foo]` instead of concatenation | -44 | ] +44 | [] + foo + [] 45 | -46 | [] + foo + [ # This will be preserved, but doesn't prevent the fix +46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix | ^^^^^^^^ RUF005 -47 | ] +47 | +48 | # Uses the non-preferred quote style, which should be retained. | = help: Replace with `[*foo]` ℹ Suggested fix -41 41 | [] + foo + [ -42 42 | ] +41 41 | +42 42 | [] + foo + [] 43 43 | -44 |-[] + foo + [ # This will be preserved, but doesn't prevent the fix - 44 |+[*foo] + [ # This will be preserved, but doesn't prevent the fix -45 45 | ] -46 46 | -47 47 | # Uses the non-preferred quote style, which should be retained. +44 |-[] + foo + [] # This will be preserved, but doesn't prevent the fix + 44 |+[*foo] + [] # This will be preserved, but doesn't prevent the fix +45 45 | +46 46 | # Uses the non-preferred quote style, which should be retained. +47 47 | f"{[*a(), 'b']}" + +RUF005.py:49:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args, path]` instead of concatenation + | +49 | f"{[*a(), 'b']}" +50 | +51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 | b = a + [2, 3] + [4] + | + = help: Replace with `[sys.executable, "-m", "pylint", *args, path]` + +ℹ Suggested fix +46 46 | # Uses the non-preferred quote style, which should be retained. +47 47 | f"{[*a(), 'b']}" +48 48 | +49 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + 49 |+pylint_call = [sys.executable, "-m", "pylint", *args, path] +50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +51 51 | b = a + [2, 3] + [4] + +RUF005.py:49:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args]` instead of concatenation + | +49 | f"{[*a(), 'b']}" +50 | +51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 | b = a + [2, 3] + [4] + | + = help: Replace with `[sys.executable, "-m", "pylint", *args]` + +ℹ Suggested fix +46 46 | # Uses the non-preferred quote style, which should be retained. +47 47 | f"{[*a(), 'b']}" +48 48 | +49 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + 49 |+pylint_call = [sys.executable, "-m", "pylint", *args] + [path] +50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +51 51 | b = a + [2, 3] + [4] + +RUF005.py:50:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, path, path2)` instead of concatenation + | +50 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +51 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +52 | b = a + [2, 3] + [4] + | + = help: Replace with `(sys.executable, "-m", "pylint", *args, path, path2)` + +ℹ Suggested fix +47 47 | f"{[*a(), 'b']}" +48 48 | +49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +50 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + 50 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) +51 51 | b = a + [2, 3] + [4] + +RUF005.py:50:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args)` instead of concatenation + | +50 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +51 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +52 | b = a + [2, 3] + [4] + | + = help: Replace with `(sys.executable, "-m", "pylint", *args)` + +ℹ Suggested fix +47 47 | f"{[*a(), 'b']}" +48 48 | +49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +50 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + 50 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args) + (path, path2) +51 51 | b = a + [2, 3] + [4] + +RUF005.py:51:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation + | +51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 | b = a + [2, 3] + [4] + | ^^^^^^^^^^^^^^^^ RUF005 + | + = help: Replace with `[*a, 2, 3, 4]` + +ℹ Suggested fix +48 48 | +49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +51 |-b = a + [2, 3] + [4] + 51 |+b = [*a, 2, 3, 4] + +RUF005.py:51:5: RUF005 [*] Consider `[*a, 2, 3]` instead of concatenation + | +51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 | b = a + [2, 3] + [4] + | ^^^^^^^^^^ RUF005 + | + = help: Replace with `[*a, 2, 3]` + +ℹ Suggested fix +48 48 | +49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +51 |-b = a + [2, 3] + [4] + 51 |+b = [*a, 2, 3] + [4] From e2a6ca96347660b08e0f3f4e54cd602da656a2a1 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Sun, 21 May 2023 12:26:59 +0900 Subject: [PATCH 08/19] Reverted test fixture that had been auto-fixed by black. --- .../resources/test/fixtures/ruff/RUF005.py | 6 +- ..._rules__ruff__tests__RUF005_RUF005.py.snap | 229 +++++++++--------- 2 files changed, 119 insertions(+), 116 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/ruff/RUF005.py b/crates/ruff/resources/test/fixtures/ruff/RUF005.py index 28aa09c58de60..e00ff62776f58 100644 --- a/crates/ruff/resources/test/fixtures/ruff/RUF005.py +++ b/crates/ruff/resources/test/fixtures/ruff/RUF005.py @@ -39,9 +39,11 @@ def yay(self): 6, ] -[] + foo + [] +[] + foo + [ +] -[] + foo + [] # This will be preserved, but doesn't prevent the fix +[] + foo + [ # This will be preserved, but doesn't prevent the fix +] # Uses the non-preferred quote style, which should be retained. f"{[*a(), 'b']}" diff --git a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap index fd22135169d04..ff5685e08c279 100644 --- a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap +++ b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap @@ -224,18 +224,19 @@ RUF005.py:33:10: RUF005 Consider `[*first, 4, 5, 6]` instead of concatenation 42 | | ] | |_^ RUF005 43 | -44 | [] + foo + [] +44 | [] + foo + [ | = help: Replace with `[*first, 4, 5, 6]` RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation | -42 | ] -43 | -44 | [] + foo + [] - | ^^^^^^^^^^^^^ RUF005 -45 | -46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix +42 | ] +43 | +44 | / [] + foo + [ +45 | | ] + | |_^ RUF005 +46 | +47 | [] + foo + [ # This will be preserved, but doesn't prevent the fix | = help: Replace with `[*foo]` @@ -243,20 +244,20 @@ RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation 39 39 | 6, 40 40 | ] 41 41 | -42 |-[] + foo + [] +42 |-[] + foo + [ +43 |-] 42 |+[*foo] -43 43 | -44 44 | [] + foo + [] # This will be preserved, but doesn't prevent the fix -45 45 | +44 43 | +45 44 | [] + foo + [ # This will be preserved, but doesn't prevent the fix +46 45 | ] RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation | 42 | ] 43 | -44 | [] + foo + [] +44 | [] + foo + [ | ^^^^^^^^ RUF005 -45 | -46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix +45 | ] | = help: Replace with `[*foo]` @@ -264,148 +265,148 @@ RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation 39 39 | 6, 40 40 | ] 41 41 | -42 |-[] + foo + [] - 42 |+[*foo] + [] -43 43 | -44 44 | [] + foo + [] # This will be preserved, but doesn't prevent the fix -45 45 | - -RUF005.py:44:1: RUF005 Consider `[*foo]` instead of concatenation - | -44 | [] + foo + [] -45 | -46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix - | ^^^^^^^^^^^^^ RUF005 -47 | -48 | # Uses the non-preferred quote style, which should be retained. +42 |-[] + foo + [ + 42 |+[*foo] + [ +43 43 | ] +44 44 | +45 45 | [] + foo + [ # This will be preserved, but doesn't prevent the fix + +RUF005.py:45:1: RUF005 Consider `[*foo]` instead of concatenation + | +45 | ] +46 | +47 | / [] + foo + [ # This will be preserved, but doesn't prevent the fix +48 | | ] + | |_^ RUF005 +49 | +50 | # Uses the non-preferred quote style, which should be retained. | = help: Replace with `[*foo]` -RUF005.py:44:1: RUF005 [*] Consider `[*foo]` instead of concatenation +RUF005.py:45:1: RUF005 [*] Consider `[*foo]` instead of concatenation | -44 | [] + foo + [] -45 | -46 | [] + foo + [] # This will be preserved, but doesn't prevent the fix +45 | ] +46 | +47 | [] + foo + [ # This will be preserved, but doesn't prevent the fix | ^^^^^^^^ RUF005 -47 | -48 | # Uses the non-preferred quote style, which should be retained. +48 | ] | = help: Replace with `[*foo]` ℹ Suggested fix -41 41 | -42 42 | [] + foo + [] -43 43 | -44 |-[] + foo + [] # This will be preserved, but doesn't prevent the fix - 44 |+[*foo] + [] # This will be preserved, but doesn't prevent the fix -45 45 | -46 46 | # Uses the non-preferred quote style, which should be retained. -47 47 | f"{[*a(), 'b']}" - -RUF005.py:49:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args, path]` instead of concatenation - | -49 | f"{[*a(), 'b']}" -50 | -51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +42 42 | [] + foo + [ +43 43 | ] +44 44 | +45 |-[] + foo + [ # This will be preserved, but doesn't prevent the fix + 45 |+[*foo] + [ # This will be preserved, but doesn't prevent the fix +46 46 | ] +47 47 | +48 48 | # Uses the non-preferred quote style, which should be retained. + +RUF005.py:51:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args, path]` instead of concatenation + | +51 | f"{[*a(), 'b']}" +52 | +53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 | b = a + [2, 3] + [4] +54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +55 | b = a + [2, 3] + [4] | = help: Replace with `[sys.executable, "-m", "pylint", *args, path]` ℹ Suggested fix -46 46 | # Uses the non-preferred quote style, which should be retained. -47 47 | f"{[*a(), 'b']}" -48 48 | -49 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - 49 |+pylint_call = [sys.executable, "-m", "pylint", *args, path] -50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -51 51 | b = a + [2, 3] + [4] - -RUF005.py:49:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args]` instead of concatenation - | -49 | f"{[*a(), 'b']}" -50 | -51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +48 48 | # Uses the non-preferred quote style, which should be retained. +49 49 | f"{[*a(), 'b']}" +50 50 | +51 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + 51 |+pylint_call = [sys.executable, "-m", "pylint", *args, path] +52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 53 | b = a + [2, 3] + [4] + +RUF005.py:51:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args]` instead of concatenation + | +51 | f"{[*a(), 'b']}" +52 | +53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 | b = a + [2, 3] + [4] +54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +55 | b = a + [2, 3] + [4] | = help: Replace with `[sys.executable, "-m", "pylint", *args]` ℹ Suggested fix -46 46 | # Uses the non-preferred quote style, which should be retained. -47 47 | f"{[*a(), 'b']}" -48 48 | -49 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - 49 |+pylint_call = [sys.executable, "-m", "pylint", *args] + [path] -50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -51 51 | b = a + [2, 3] + [4] - -RUF005.py:50:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, path, path2)` instead of concatenation - | -50 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -51 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +48 48 | # Uses the non-preferred quote style, which should be retained. +49 49 | f"{[*a(), 'b']}" +50 50 | +51 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + 51 |+pylint_call = [sys.executable, "-m", "pylint", *args] + [path] +52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 53 | b = a + [2, 3] + [4] + +RUF005.py:52:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, path, path2)` instead of concatenation + | +52 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +53 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -52 | b = a + [2, 3] + [4] +54 | b = a + [2, 3] + [4] | = help: Replace with `(sys.executable, "-m", "pylint", *args, path, path2)` ℹ Suggested fix -47 47 | f"{[*a(), 'b']}" -48 48 | -49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -50 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - 50 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) -51 51 | b = a + [2, 3] + [4] +49 49 | f"{[*a(), 'b']}" +50 50 | +51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +52 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + 52 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) +53 53 | b = a + [2, 3] + [4] -RUF005.py:50:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args)` instead of concatenation +RUF005.py:52:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args)` instead of concatenation | -50 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -51 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +52 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +53 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -52 | b = a + [2, 3] + [4] +54 | b = a + [2, 3] + [4] | = help: Replace with `(sys.executable, "-m", "pylint", *args)` ℹ Suggested fix -47 47 | f"{[*a(), 'b']}" -48 48 | -49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -50 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - 50 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args) + (path, path2) -51 51 | b = a + [2, 3] + [4] - -RUF005.py:51:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation - | -51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 | b = a + [2, 3] + [4] +49 49 | f"{[*a(), 'b']}" +50 50 | +51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +52 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + 52 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args) + (path, path2) +53 53 | b = a + [2, 3] + [4] + +RUF005.py:53:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation + | +53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +55 | b = a + [2, 3] + [4] | ^^^^^^^^^^^^^^^^ RUF005 | = help: Replace with `[*a, 2, 3, 4]` ℹ Suggested fix -48 48 | -49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -51 |-b = a + [2, 3] + [4] - 51 |+b = [*a, 2, 3, 4] +50 50 | +51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 |-b = a + [2, 3] + [4] + 53 |+b = [*a, 2, 3, 4] -RUF005.py:51:5: RUF005 [*] Consider `[*a, 2, 3]` instead of concatenation +RUF005.py:53:5: RUF005 [*] Consider `[*a, 2, 3]` instead of concatenation | -51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 | b = a + [2, 3] + [4] +53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +55 | b = a + [2, 3] + [4] | ^^^^^^^^^^ RUF005 | = help: Replace with `[*a, 2, 3]` ℹ Suggested fix -48 48 | -49 49 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -50 50 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -51 |-b = a + [2, 3] + [4] - 51 |+b = [*a, 2, 3] + [4] +50 50 | +51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 |-b = a + [2, 3] + [4] + 53 |+b = [*a, 2, 3] + [4] From bf82a16a626ece11d632de1213da09bee6a169b1 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Mon, 22 May 2023 22:09:03 +0900 Subject: [PATCH 09/19] Remove unnecessary if/else statement since condition is always true. --- .../rules/ruff/rules/collection_literal_concatenation.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index afff2aaa25cfc..483f203c0800f 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -125,18 +125,13 @@ fn build_new_expr(expr: &Expr) -> Option { else if splat_element.is_list_expr() || splat_element.is_tuple_expr() { new_elts = other_elements.clone(); - let mut elts = match splat_element { + let elts = match splat_element { Expr::List(ast::ExprList { elts, .. }) => elts.clone(), Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.clone(), _ => return None, }; - if splat_at_left { - elts.extend_from_slice(&new_elts); - new_elts = elts.clone(); - } else { - new_elts.extend_from_slice(&elts); - } + new_elts.extend_from_slice(&elts); } else { return None; } From f49f5a958d94297275748ac32519a4188aef7ce0 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Mon, 22 May 2023 22:24:00 +0900 Subject: [PATCH 10/19] Added a comment. --- .../src/rules/ruff/rules/collection_literal_concatenation.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 483f203c0800f..d89190f0a43d7 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -54,6 +54,7 @@ enum Kind { Tuple, } +/// Recursively merge all the tuples/lists of the expression. fn build_new_expr(expr: &Expr) -> Option { let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { return None; From 2d2d2d09e00a9f4b2caeec7ca3cecea6f48678b1 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Mon, 22 May 2023 22:33:46 +0900 Subject: [PATCH 11/19] Do not generate warning/fix for concatenation of a list with a tuple. --- .../rules/ruff/rules/collection_literal_concatenation.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index d89190f0a43d7..5b38ea34e8d38 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -48,7 +48,7 @@ fn make_splat_elts( new_elts } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, PartialEq)] enum Kind { List, Tuple, @@ -123,7 +123,9 @@ fn build_new_expr(expr: &Expr) -> Option { new_elts = make_splat_elts(splat_element, other_elements, splat_at_left); } // If the splat element is itself a list/tuple, insert them in the other list/tuple. - else if splat_element.is_list_expr() || splat_element.is_tuple_expr() { + else if (kind == Kind::List && splat_element.is_list_expr()) + || (kind == Kind::Tuple && splat_element.is_tuple_expr()) + { new_elts = other_elements.clone(); let elts = match splat_element { From aebfc34c471cfa9437992287437c6ff12084aa6b Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Mon, 22 May 2023 22:59:20 +0900 Subject: [PATCH 12/19] Updated test fixture. --- .../resources/test/fixtures/ruff/RUF005.py | 61 +- ..._rules__ruff__tests__RUF005_RUF005.py.snap | 636 +++++++++--------- 2 files changed, 358 insertions(+), 339 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/ruff/RUF005.py b/crates/ruff/resources/test/fixtures/ruff/RUF005.py index e00ff62776f58..ce302485c9c2a 100644 --- a/crates/ruff/resources/test/fixtures/ruff/RUF005.py +++ b/crates/ruff/resources/test/fixtures/ruff/RUF005.py @@ -1,3 +1,31 @@ +### +# Non-fixable Errors. +### +foo + [ # This will be preserved, but doesn't prevent the fix +] +[*foo] + [ # This will be preserved, but doesn't prevent the fix +] +first = [ + # The order + 1, # here + 2, # is + # extremely + 3, # critical + # to preserve +] +second = first + [ + # please + 4, + # don't + 5, + # touch + 6, +] + + +### +# Fixable errors. +### class Fun: words = ("how", "fun!") @@ -22,32 +50,19 @@ def yay(self): baz = () + zoob -first = [ - # The order - 1, # here - 2, # is - # extremely - 3, # critical - # to preserve -] -second = first + [ - # please - 4, - # don't - 5, - # touch - 6, -] - [] + foo + [ ] -[] + foo + [ # This will be preserved, but doesn't prevent the fix -] - -# Uses the non-preferred quote style, which should be retained. -f"{[*a(), 'b']}" - pylint_call = [sys.executable, "-m", "pylint"] + args + [path] pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) b = a + [2, 3] + [4] + + +### +# Non-errors. +### +a = (1,) + [2] +a = [1, 2] + (3, 4) + +# Uses the non-preferred quote style, which should be retained. +f"{[*a(), 'b']}" diff --git a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap index ff5685e08c279..eb58af3ad59ab 100644 --- a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap +++ b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap @@ -1,412 +1,416 @@ --- source: crates/ruff/src/rules/ruff/mod.rs --- -RUF005.py:11:7: RUF005 [*] Consider `[1, 2, 3, *foo]` instead of concatenation +RUF005.py:4:1: RUF005 Consider `[*foo]` instead of concatenation + | +4 | # Non-fixable Errors. +5 | ### +6 | / foo + [ # This will be preserved, but doesn't prevent the fix +7 | | ] + | |_^ RUF005 +8 | [*foo] + [ # This will be preserved, but doesn't prevent the fix +9 | ] + | + = help: Replace with `[*foo]` + +RUF005.py:6:1: RUF005 Consider `[*foo]` instead of concatenation + | + 6 | foo + [ # This will be preserved, but doesn't prevent the fix + 7 | ] + 8 | / [*foo] + [ # This will be preserved, but doesn't prevent the fix + 9 | | ] + | |_^ RUF005 +10 | first = [ +11 | # The order + | + = help: Replace with `[*foo]` + +RUF005.py:16:10: RUF005 Consider `[*first, 4, 5, 6]` instead of concatenation + | +16 | # to preserve +17 | ] +18 | second = first + [ + | __________^ +19 | | # please +20 | | 4, +21 | | # don't +22 | | 5, +23 | | # touch +24 | | 6, +25 | | ] + | |_^ RUF005 +26 | +27 | ### | -11 | foo = [4, 5, 6] -12 | bar = [1, 2, 3] + foo + = help: Replace with `[*first, 4, 5, 6]` + +RUF005.py:38:7: RUF005 [*] Consider `[1, 2, 3, *foo]` instead of concatenation + | +38 | foo = [4, 5, 6] +39 | bar = [1, 2, 3] + foo | ^^^^^^^^^^^^^^^ RUF005 -13 | zoob = tuple(bar) -14 | quux = (7, 8, 9) + zoob +40 | zoob = tuple(bar) +41 | quux = (7, 8, 9) + zoob | = help: Replace with `[1, 2, 3, *foo]` ℹ Suggested fix -8 8 | yay = Fun().yay -9 9 | -10 10 | foo = [4, 5, 6] -11 |-bar = [1, 2, 3] + foo - 11 |+bar = [1, 2, 3, *foo] -12 12 | zoob = tuple(bar) -13 13 | quux = (7, 8, 9) + zoob -14 14 | spam = quux + (10, 11, 12) - -RUF005.py:13:8: RUF005 [*] Consider `(7, 8, 9, *zoob)` instead of concatenation - | -13 | bar = [1, 2, 3] + foo -14 | zoob = tuple(bar) -15 | quux = (7, 8, 9) + zoob +35 35 | yay = Fun().yay +36 36 | +37 37 | foo = [4, 5, 6] +38 |-bar = [1, 2, 3] + foo + 38 |+bar = [1, 2, 3, *foo] +39 39 | zoob = tuple(bar) +40 40 | quux = (7, 8, 9) + zoob +41 41 | spam = quux + (10, 11, 12) + +RUF005.py:40:8: RUF005 [*] Consider `(7, 8, 9, *zoob)` instead of concatenation + | +40 | bar = [1, 2, 3] + foo +41 | zoob = tuple(bar) +42 | quux = (7, 8, 9) + zoob | ^^^^^^^^^^^^^^^^ RUF005 -16 | spam = quux + (10, 11, 12) -17 | spom = list(spam) +43 | spam = quux + (10, 11, 12) +44 | spom = list(spam) | = help: Replace with `(7, 8, 9, *zoob)` ℹ Suggested fix -10 10 | foo = [4, 5, 6] -11 11 | bar = [1, 2, 3] + foo -12 12 | zoob = tuple(bar) -13 |-quux = (7, 8, 9) + zoob - 13 |+quux = (7, 8, 9, *zoob) -14 14 | spam = quux + (10, 11, 12) -15 15 | spom = list(spam) -16 16 | eggs = spom + [13, 14, 15] - -RUF005.py:14:8: RUF005 [*] Consider `(*quux, 10, 11, 12)` instead of concatenation - | -14 | zoob = tuple(bar) -15 | quux = (7, 8, 9) + zoob -16 | spam = quux + (10, 11, 12) +37 37 | foo = [4, 5, 6] +38 38 | bar = [1, 2, 3] + foo +39 39 | zoob = tuple(bar) +40 |-quux = (7, 8, 9) + zoob + 40 |+quux = (7, 8, 9, *zoob) +41 41 | spam = quux + (10, 11, 12) +42 42 | spom = list(spam) +43 43 | eggs = spom + [13, 14, 15] + +RUF005.py:41:8: RUF005 [*] Consider `(*quux, 10, 11, 12)` instead of concatenation + | +41 | zoob = tuple(bar) +42 | quux = (7, 8, 9) + zoob +43 | spam = quux + (10, 11, 12) | ^^^^^^^^^^^^^^^^^^^ RUF005 -17 | spom = list(spam) -18 | eggs = spom + [13, 14, 15] +44 | spom = list(spam) +45 | eggs = spom + [13, 14, 15] | = help: Replace with `(*quux, 10, 11, 12)` ℹ Suggested fix -11 11 | bar = [1, 2, 3] + foo -12 12 | zoob = tuple(bar) -13 13 | quux = (7, 8, 9) + zoob -14 |-spam = quux + (10, 11, 12) - 14 |+spam = (*quux, 10, 11, 12) -15 15 | spom = list(spam) -16 16 | eggs = spom + [13, 14, 15] -17 17 | elatement = ("we all say",) + yay() - -RUF005.py:16:8: RUF005 [*] Consider `[*spom, 13, 14, 15]` instead of concatenation - | -16 | spam = quux + (10, 11, 12) -17 | spom = list(spam) -18 | eggs = spom + [13, 14, 15] +38 38 | bar = [1, 2, 3] + foo +39 39 | zoob = tuple(bar) +40 40 | quux = (7, 8, 9) + zoob +41 |-spam = quux + (10, 11, 12) + 41 |+spam = (*quux, 10, 11, 12) +42 42 | spom = list(spam) +43 43 | eggs = spom + [13, 14, 15] +44 44 | elatement = ("we all say",) + yay() + +RUF005.py:43:8: RUF005 [*] Consider `[*spom, 13, 14, 15]` instead of concatenation + | +43 | spam = quux + (10, 11, 12) +44 | spom = list(spam) +45 | eggs = spom + [13, 14, 15] | ^^^^^^^^^^^^^^^^^^^ RUF005 -19 | elatement = ("we all say",) + yay() -20 | excitement = ("we all think",) + Fun().yay() +46 | elatement = ("we all say",) + yay() +47 | excitement = ("we all think",) + Fun().yay() | = help: Replace with `[*spom, 13, 14, 15]` ℹ Suggested fix -13 13 | quux = (7, 8, 9) + zoob -14 14 | spam = quux + (10, 11, 12) -15 15 | spom = list(spam) -16 |-eggs = spom + [13, 14, 15] - 16 |+eggs = [*spom, 13, 14, 15] -17 17 | elatement = ("we all say",) + yay() -18 18 | excitement = ("we all think",) + Fun().yay() -19 19 | astonishment = ("we all feel",) + Fun.words - -RUF005.py:17:13: RUF005 [*] Consider `("we all say", *yay())` instead of concatenation - | -17 | spom = list(spam) -18 | eggs = spom + [13, 14, 15] -19 | elatement = ("we all say",) + yay() +40 40 | quux = (7, 8, 9) + zoob +41 41 | spam = quux + (10, 11, 12) +42 42 | spom = list(spam) +43 |-eggs = spom + [13, 14, 15] + 43 |+eggs = [*spom, 13, 14, 15] +44 44 | elatement = ("we all say",) + yay() +45 45 | excitement = ("we all think",) + Fun().yay() +46 46 | astonishment = ("we all feel",) + Fun.words + +RUF005.py:44:13: RUF005 [*] Consider `("we all say", *yay())` instead of concatenation + | +44 | spom = list(spam) +45 | eggs = spom + [13, 14, 15] +46 | elatement = ("we all say",) + yay() | ^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -20 | excitement = ("we all think",) + Fun().yay() -21 | astonishment = ("we all feel",) + Fun.words +47 | excitement = ("we all think",) + Fun().yay() +48 | astonishment = ("we all feel",) + Fun.words | = help: Replace with `("we all say", *yay())` ℹ Suggested fix -14 14 | spam = quux + (10, 11, 12) -15 15 | spom = list(spam) -16 16 | eggs = spom + [13, 14, 15] -17 |-elatement = ("we all say",) + yay() - 17 |+elatement = ("we all say", *yay()) -18 18 | excitement = ("we all think",) + Fun().yay() -19 19 | astonishment = ("we all feel",) + Fun.words -20 20 | - -RUF005.py:18:14: RUF005 [*] Consider `("we all think", *Fun().yay())` instead of concatenation - | -18 | eggs = spom + [13, 14, 15] -19 | elatement = ("we all say",) + yay() -20 | excitement = ("we all think",) + Fun().yay() +41 41 | spam = quux + (10, 11, 12) +42 42 | spom = list(spam) +43 43 | eggs = spom + [13, 14, 15] +44 |-elatement = ("we all say",) + yay() + 44 |+elatement = ("we all say", *yay()) +45 45 | excitement = ("we all think",) + Fun().yay() +46 46 | astonishment = ("we all feel",) + Fun.words +47 47 | + +RUF005.py:45:14: RUF005 [*] Consider `("we all think", *Fun().yay())` instead of concatenation + | +45 | eggs = spom + [13, 14, 15] +46 | elatement = ("we all say",) + yay() +47 | excitement = ("we all think",) + Fun().yay() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -21 | astonishment = ("we all feel",) + Fun.words +48 | astonishment = ("we all feel",) + Fun.words | = help: Replace with `("we all think", *Fun().yay())` ℹ Suggested fix -15 15 | spom = list(spam) -16 16 | eggs = spom + [13, 14, 15] -17 17 | elatement = ("we all say",) + yay() -18 |-excitement = ("we all think",) + Fun().yay() - 18 |+excitement = ("we all think", *Fun().yay()) -19 19 | astonishment = ("we all feel",) + Fun.words -20 20 | -21 21 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) - -RUF005.py:19:16: RUF005 [*] Consider `("we all feel", *Fun.words)` instead of concatenation - | -19 | elatement = ("we all say",) + yay() -20 | excitement = ("we all think",) + Fun().yay() -21 | astonishment = ("we all feel",) + Fun.words +42 42 | spom = list(spam) +43 43 | eggs = spom + [13, 14, 15] +44 44 | elatement = ("we all say",) + yay() +45 |-excitement = ("we all think",) + Fun().yay() + 45 |+excitement = ("we all think", *Fun().yay()) +46 46 | astonishment = ("we all feel",) + Fun.words +47 47 | +48 48 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + +RUF005.py:46:16: RUF005 [*] Consider `("we all feel", *Fun.words)` instead of concatenation + | +46 | elatement = ("we all say",) + yay() +47 | excitement = ("we all think",) + Fun().yay() +48 | astonishment = ("we all feel",) + Fun.words | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -22 | -23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +49 | +50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | = help: Replace with `("we all feel", *Fun.words)` ℹ Suggested fix -16 16 | eggs = spom + [13, 14, 15] -17 17 | elatement = ("we all say",) + yay() -18 18 | excitement = ("we all think",) + Fun().yay() -19 |-astonishment = ("we all feel",) + Fun.words - 19 |+astonishment = ("we all feel", *Fun.words) -20 20 | -21 21 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) -22 22 | - -RUF005.py:21:9: RUF005 [*] Consider `["a", "b", "c", *eggs]` instead of concatenation - | -21 | astonishment = ("we all feel",) + Fun.words -22 | -23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +43 43 | eggs = spom + [13, 14, 15] +44 44 | elatement = ("we all say",) + yay() +45 45 | excitement = ("we all think",) + Fun().yay() +46 |-astonishment = ("we all feel",) + Fun.words + 46 |+astonishment = ("we all feel", *Fun.words) +47 47 | +48 48 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +49 49 | + +RUF005.py:48:9: RUF005 [*] Consider `["a", "b", "c", *eggs]` instead of concatenation + | +48 | astonishment = ("we all feel",) + Fun.words +49 | +50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | ^^^^^^^^^^^^^^^^^^^^^^ RUF005 -24 | -25 | baz = () + zoob +51 | +52 | baz = () + zoob | = help: Replace with `["a", "b", "c", *eggs]` ℹ Suggested fix -18 18 | excitement = ("we all think",) + Fun().yay() -19 19 | astonishment = ("we all feel",) + Fun.words -20 20 | -21 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) - 21 |+chain = ["a", "b", "c", *eggs] + list(("yes", "no", "pants") + zoob) -22 22 | -23 23 | baz = () + zoob -24 24 | - -RUF005.py:21:39: RUF005 [*] Consider `("yes", "no", "pants", *zoob)` instead of concatenation - | -21 | astonishment = ("we all feel",) + Fun.words -22 | -23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +45 45 | excitement = ("we all think",) + Fun().yay() +46 46 | astonishment = ("we all feel",) + Fun.words +47 47 | +48 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + 48 |+chain = ["a", "b", "c", *eggs] + list(("yes", "no", "pants") + zoob) +49 49 | +50 50 | baz = () + zoob +51 51 | + +RUF005.py:48:39: RUF005 [*] Consider `("yes", "no", "pants", *zoob)` instead of concatenation + | +48 | astonishment = ("we all feel",) + Fun.words +49 | +50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -24 | -25 | baz = () + zoob +51 | +52 | baz = () + zoob | = help: Replace with `("yes", "no", "pants", *zoob)` ℹ Suggested fix -18 18 | excitement = ("we all think",) + Fun().yay() -19 19 | astonishment = ("we all feel",) + Fun.words -20 20 | -21 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) - 21 |+chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants", *zoob)) -22 22 | -23 23 | baz = () + zoob -24 24 | - -RUF005.py:23:7: RUF005 [*] Consider `(*zoob,)` instead of concatenation - | -23 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) -24 | -25 | baz = () + zoob +45 45 | excitement = ("we all think",) + Fun().yay() +46 46 | astonishment = ("we all feel",) + Fun.words +47 47 | +48 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + 48 |+chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants", *zoob)) +49 49 | +50 50 | baz = () + zoob +51 51 | + +RUF005.py:50:7: RUF005 [*] Consider `(*zoob,)` instead of concatenation + | +50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +51 | +52 | baz = () + zoob | ^^^^^^^^^ RUF005 -26 | -27 | first = [ +53 | +54 | [] + foo + [ | = help: Replace with `(*zoob,)` ℹ Suggested fix -20 20 | -21 21 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) -22 22 | -23 |-baz = () + zoob - 23 |+baz = (*zoob,) -24 24 | -25 25 | first = [ -26 26 | # The order - -RUF005.py:33:10: RUF005 Consider `[*first, 4, 5, 6]` instead of concatenation - | -33 | # to preserve -34 | ] -35 | second = first + [ - | __________^ -36 | | # please -37 | | 4, -38 | | # don't -39 | | 5, -40 | | # touch -41 | | 6, -42 | | ] - | |_^ RUF005 -43 | -44 | [] + foo + [ - | - = help: Replace with `[*first, 4, 5, 6]` - -RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation - | -42 | ] -43 | -44 | / [] + foo + [ -45 | | ] +47 47 | +48 48 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +49 49 | +50 |-baz = () + zoob + 50 |+baz = (*zoob,) +51 51 | +52 52 | [] + foo + [ +53 53 | ] + +RUF005.py:52:1: RUF005 [*] Consider `[*foo]` instead of concatenation + | +52 | baz = () + zoob +53 | +54 | / [] + foo + [ +55 | | ] | |_^ RUF005 -46 | -47 | [] + foo + [ # This will be preserved, but doesn't prevent the fix - | - = help: Replace with `[*foo]` - -ℹ Suggested fix -39 39 | 6, -40 40 | ] -41 41 | -42 |-[] + foo + [ -43 |-] - 42 |+[*foo] -44 43 | -45 44 | [] + foo + [ # This will be preserved, but doesn't prevent the fix -46 45 | ] - -RUF005.py:42:1: RUF005 [*] Consider `[*foo]` instead of concatenation - | -42 | ] -43 | -44 | [] + foo + [ - | ^^^^^^^^ RUF005 -45 | ] +56 | +57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] | = help: Replace with `[*foo]` ℹ Suggested fix -39 39 | 6, -40 40 | ] -41 41 | -42 |-[] + foo + [ - 42 |+[*foo] + [ -43 43 | ] -44 44 | -45 45 | [] + foo + [ # This will be preserved, but doesn't prevent the fix - -RUF005.py:45:1: RUF005 Consider `[*foo]` instead of concatenation - | -45 | ] -46 | -47 | / [] + foo + [ # This will be preserved, but doesn't prevent the fix -48 | | ] - | |_^ RUF005 -49 | -50 | # Uses the non-preferred quote style, which should be retained. - | - = help: Replace with `[*foo]` - -RUF005.py:45:1: RUF005 [*] Consider `[*foo]` instead of concatenation - | -45 | ] -46 | -47 | [] + foo + [ # This will be preserved, but doesn't prevent the fix +49 49 | +50 50 | baz = () + zoob +51 51 | +52 |-[] + foo + [ +53 |-] + 52 |+[*foo] +54 53 | +55 54 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +56 55 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + +RUF005.py:52:1: RUF005 [*] Consider `[*foo]` instead of concatenation + | +52 | baz = () + zoob +53 | +54 | [] + foo + [ | ^^^^^^^^ RUF005 -48 | ] +55 | ] | = help: Replace with `[*foo]` ℹ Suggested fix -42 42 | [] + foo + [ -43 43 | ] -44 44 | -45 |-[] + foo + [ # This will be preserved, but doesn't prevent the fix - 45 |+[*foo] + [ # This will be preserved, but doesn't prevent the fix -46 46 | ] -47 47 | -48 48 | # Uses the non-preferred quote style, which should be retained. - -RUF005.py:51:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args, path]` instead of concatenation - | -51 | f"{[*a(), 'b']}" -52 | -53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +49 49 | +50 50 | baz = () + zoob +51 51 | +52 |-[] + foo + [ + 52 |+[*foo] + [ +53 53 | ] +54 54 | +55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + +RUF005.py:55:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args, path]` instead of concatenation + | +55 | ] +56 | +57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -55 | b = a + [2, 3] + [4] +58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +59 | b = a + [2, 3] + [4] | = help: Replace with `[sys.executable, "-m", "pylint", *args, path]` ℹ Suggested fix -48 48 | # Uses the non-preferred quote style, which should be retained. -49 49 | f"{[*a(), 'b']}" -50 50 | -51 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - 51 |+pylint_call = [sys.executable, "-m", "pylint", *args, path] -52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 53 | b = a + [2, 3] + [4] - -RUF005.py:51:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args]` instead of concatenation - | -51 | f"{[*a(), 'b']}" -52 | -53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +52 52 | [] + foo + [ +53 53 | ] +54 54 | +55 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + 55 |+pylint_call = [sys.executable, "-m", "pylint", *args, path] +56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +57 57 | b = a + [2, 3] + [4] +58 58 | + +RUF005.py:55:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args]` instead of concatenation + | +55 | ] +56 | +57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -55 | b = a + [2, 3] + [4] +58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +59 | b = a + [2, 3] + [4] | = help: Replace with `[sys.executable, "-m", "pylint", *args]` ℹ Suggested fix -48 48 | # Uses the non-preferred quote style, which should be retained. -49 49 | f"{[*a(), 'b']}" -50 50 | -51 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - 51 |+pylint_call = [sys.executable, "-m", "pylint", *args] + [path] -52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 53 | b = a + [2, 3] + [4] - -RUF005.py:52:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, path, path2)` instead of concatenation - | -52 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -53 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +52 52 | [] + foo + [ +53 53 | ] +54 54 | +55 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + 55 |+pylint_call = [sys.executable, "-m", "pylint", *args] + [path] +56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +57 57 | b = a + [2, 3] + [4] +58 58 | + +RUF005.py:56:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, path, path2)` instead of concatenation + | +56 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +57 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -54 | b = a + [2, 3] + [4] +58 | b = a + [2, 3] + [4] | = help: Replace with `(sys.executable, "-m", "pylint", *args, path, path2)` ℹ Suggested fix -49 49 | f"{[*a(), 'b']}" -50 50 | -51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -52 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - 52 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) -53 53 | b = a + [2, 3] + [4] - -RUF005.py:52:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args)` instead of concatenation - | -52 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -53 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +53 53 | ] +54 54 | +55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +56 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + 56 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) +57 57 | b = a + [2, 3] + [4] +58 58 | +59 59 | + +RUF005.py:56:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args)` instead of concatenation + | +56 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +57 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -54 | b = a + [2, 3] + [4] +58 | b = a + [2, 3] + [4] | = help: Replace with `(sys.executable, "-m", "pylint", *args)` ℹ Suggested fix -49 49 | f"{[*a(), 'b']}" -50 50 | -51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -52 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - 52 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args) + (path, path2) -53 53 | b = a + [2, 3] + [4] - -RUF005.py:53:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation - | -53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -55 | b = a + [2, 3] + [4] +53 53 | ] +54 54 | +55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +56 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + 56 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args) + (path, path2) +57 57 | b = a + [2, 3] + [4] +58 58 | +59 59 | + +RUF005.py:57:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation + | +57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +59 | b = a + [2, 3] + [4] | ^^^^^^^^^^^^^^^^ RUF005 | = help: Replace with `[*a, 2, 3, 4]` ℹ Suggested fix -50 50 | -51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 |-b = a + [2, 3] + [4] - 53 |+b = [*a, 2, 3, 4] - -RUF005.py:53:5: RUF005 [*] Consider `[*a, 2, 3]` instead of concatenation - | -53 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -54 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -55 | b = a + [2, 3] + [4] +54 54 | +55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +57 |-b = a + [2, 3] + [4] + 57 |+b = [*a, 2, 3, 4] +58 58 | +59 59 | +60 60 | ### + +RUF005.py:57:5: RUF005 [*] Consider `[*a, 2, 3]` instead of concatenation + | +57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +59 | b = a + [2, 3] + [4] | ^^^^^^^^^^ RUF005 | = help: Replace with `[*a, 2, 3]` ℹ Suggested fix -50 50 | -51 51 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -52 52 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -53 |-b = a + [2, 3] + [4] - 53 |+b = [*a, 2, 3] + [4] +54 54 | +55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +57 |-b = a + [2, 3] + [4] + 57 |+b = [*a, 2, 3] + [4] +58 58 | +59 59 | +60 60 | ### From be57062f33678a327ee592e9e9c19b751f25c410 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Mon, 22 May 2023 23:25:39 +0900 Subject: [PATCH 13/19] Return the kind of expression from build_new_expr to avoid code duplication. --- .../rules/collection_literal_concatenation.rs | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 5b38ea34e8d38..5a06c91f2d448 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -54,15 +54,16 @@ enum Kind { Tuple, } -/// Recursively merge all the tuples/lists of the expression. -fn build_new_expr(expr: &Expr) -> Option { +/// Recursively merge all the tuples/lists of the expression and return the new suggested expression +/// along with what kind of expression it is (or return none if the expression is not a concatenation of tuples/lists). +fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { return None; }; let new_left = match left.as_ref() { Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(left) { - Some(new_left) => new_left, + Some((new_left, _)) => new_left, None => *left.clone(), }, _ => *left.clone(), @@ -70,7 +71,7 @@ fn build_new_expr(expr: &Expr) -> Option { let new_right = match right.as_ref() { Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(right) { - Some(new_right) => new_right, + Some((new_right, _)) => new_right, None => *right.clone(), }, _ => *right.clone(), @@ -158,29 +159,17 @@ fn build_new_expr(expr: &Expr) -> Option { } }; - Some(new_expr) + Some((new_expr, kind)) } /// RUF005 /// This suggestion could be unsafe if the non-literal expression in the /// expression has overridden the `__add__` (or `__radd__`) magic methods. pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { - let Some(new_expr) = build_new_expr(expr) else { + let Some((new_expr, kind)) = build_new_expr(expr) else { return }; - let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { - return; - }; - - let kind = match (left.as_ref(), right.as_ref()) { - (Expr::List(ast::ExprList { .. }), _) => Kind::List, - (Expr::Tuple(ast::ExprTuple { .. }), _) => Kind::Tuple, - (_, Expr::List(ast::ExprList { .. })) => Kind::List, - (_, Expr::Tuple(ast::ExprTuple { .. })) => Kind::Tuple, - _ => return, - }; - let contents = match kind { // Wrap the new expression in parentheses if it was a tuple Kind::Tuple => format!("({})", checker.generator().expr(&new_expr)), From 8aea4a5afde76ba21e44aa6d5cb9dfcd89e8d8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ho=C3=ABl=20Bagard?= <34478245+hoel-bagard@users.noreply.github.com> Date: Tue, 23 May 2023 18:03:50 +0900 Subject: [PATCH 14/19] Update crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs Co-authored-by: Micha Reiser --- .../src/rules/ruff/rules/collection_literal_concatenation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 5a06c91f2d448..98c73080234f7 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -48,7 +48,7 @@ fn make_splat_elts( new_elts } -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq)] enum Kind { List, Tuple, From 319b9d7c0039927b0f67f4ada497c2a82fb79e94 Mon Sep 17 00:00:00 2001 From: Hoel Bagard Date: Wed, 24 May 2023 00:23:31 +0900 Subject: [PATCH 15/19] Skip child nodes to avoid redundant warnings. --- .../rules/ruff/rules/collection_literal_concatenation.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 98c73080234f7..25a6e14320c21 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -166,6 +166,14 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { /// This suggestion could be unsafe if the non-literal expression in the /// expression has overridden the `__add__` (or `__radd__`) magic methods. pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { + // Skip the current node if a diagnostic and fix for the parent node has already been generated. + if let Some(Expr::BinOp(ast::ExprBinOp { + op: Operator::Add, .. + })) = checker.ctx.expr_parent() + { + return; + } + let Some((new_expr, kind)) = build_new_expr(expr) else { return }; From 100cccffde7e904e7613d5dcec1d6f20457437c1 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 23 May 2023 20:49:13 -0400 Subject: [PATCH 16/19] Rebase --- .../rules/collection_literal_concatenation.rs | 28 +- ..._rules__ruff__tests__RUF005_RUF005.py.snap | 511 ++++++++---------- 2 files changed, 229 insertions(+), 310 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 25a6e14320c21..c8316c9384a97 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -49,14 +49,14 @@ fn make_splat_elts( } #[derive(Debug, Copy, Clone, PartialEq, Eq)] -enum Kind { +enum Type { List, Tuple, } /// Recursively merge all the tuples/lists of the expression and return the new suggested expression /// along with what kind of expression it is (or return none if the expression is not a concatenation of tuples/lists). -fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { +fn build_new_expr(expr: &Expr) -> Option<(Expr, Type)> { let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { return None; }; @@ -86,7 +86,7 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { range: _, }), _, - ) => (Kind::List, &new_right, l_elts, false, ctx), + ) => (Type::List, &new_right, l_elts, false, ctx), ( Expr::Tuple(ast::ExprTuple { elts: l_elts, @@ -94,7 +94,7 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { range: _, }), _, - ) => (Kind::Tuple, &new_right, l_elts, false, ctx), + ) => (Type::Tuple, &new_right, l_elts, false, ctx), ( _, Expr::List(ast::ExprList { @@ -102,7 +102,7 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { ctx, range: _, }), - ) => (Kind::List, &new_left, r_elts, true, ctx), + ) => (Type::List, &new_left, r_elts, true, ctx), ( _, Expr::Tuple(ast::ExprTuple { @@ -110,7 +110,7 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { ctx, range: _, }), - ) => (Kind::Tuple, &new_left, r_elts, true, ctx), + ) => (Type::Tuple, &new_left, r_elts, true, ctx), _ => return None, }; @@ -124,8 +124,8 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { new_elts = make_splat_elts(splat_element, other_elements, splat_at_left); } // If the splat element is itself a list/tuple, insert them in the other list/tuple. - else if (kind == Kind::List && splat_element.is_list_expr()) - || (kind == Kind::Tuple && splat_element.is_tuple_expr()) + else if (kind == Type::List && splat_element.is_list_expr()) + || (kind == Type::Tuple && splat_element.is_tuple_expr()) { new_elts = other_elements.clone(); @@ -141,7 +141,7 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { } let new_expr = match kind { - Kind::List => { + Type::List => { let node = ast::ExprList { elts: new_elts, ctx: *ctx, @@ -149,7 +149,7 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { }; node.into() } - Kind::Tuple => { + Type::Tuple => { let node = ast::ExprTuple { elts: new_elts, ctx: *ctx, @@ -166,10 +166,10 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Kind)> { /// This suggestion could be unsafe if the non-literal expression in the /// expression has overridden the `__add__` (or `__radd__`) magic methods. pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { - // Skip the current node if a diagnostic and fix for the parent node has already been generated. + // If the expression is already a child of an addition, we'll have analyzed it already. if let Some(Expr::BinOp(ast::ExprBinOp { op: Operator::Add, .. - })) = checker.ctx.expr_parent() + })) = checker.semantic_model().expr_parent() { return; } @@ -180,8 +180,8 @@ pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Exp let contents = match kind { // Wrap the new expression in parentheses if it was a tuple - Kind::Tuple => format!("({})", checker.generator().expr(&new_expr)), - Kind::List => checker.generator().expr(&new_expr), + Type::Tuple => format!("({})", checker.generator().expr(&new_expr)), + Type::List => checker.generator().expr(&new_expr), }; let fixable = !has_comments(expr, checker.locator); diff --git a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap index eb58af3ad59ab..4345a8567d7a7 100644 --- a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap +++ b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap @@ -39,378 +39,297 @@ RUF005.py:16:10: RUF005 Consider `[*first, 4, 5, 6]` instead of concatenation 24 | | 6, 25 | | ] | |_^ RUF005 -26 | -27 | ### | = help: Replace with `[*first, 4, 5, 6]` -RUF005.py:38:7: RUF005 [*] Consider `[1, 2, 3, *foo]` instead of concatenation +RUF005.py:39:7: RUF005 [*] Consider `[1, 2, 3, *foo]` instead of concatenation | -38 | foo = [4, 5, 6] -39 | bar = [1, 2, 3] + foo +39 | foo = [4, 5, 6] +40 | bar = [1, 2, 3] + foo | ^^^^^^^^^^^^^^^ RUF005 -40 | zoob = tuple(bar) -41 | quux = (7, 8, 9) + zoob +41 | zoob = tuple(bar) +42 | quux = (7, 8, 9) + zoob | = help: Replace with `[1, 2, 3, *foo]` ℹ Suggested fix -35 35 | yay = Fun().yay -36 36 | -37 37 | foo = [4, 5, 6] -38 |-bar = [1, 2, 3] + foo - 38 |+bar = [1, 2, 3, *foo] -39 39 | zoob = tuple(bar) -40 40 | quux = (7, 8, 9) + zoob -41 41 | spam = quux + (10, 11, 12) - -RUF005.py:40:8: RUF005 [*] Consider `(7, 8, 9, *zoob)` instead of concatenation - | -40 | bar = [1, 2, 3] + foo -41 | zoob = tuple(bar) -42 | quux = (7, 8, 9) + zoob +36 36 | yay = Fun().yay +37 37 | +38 38 | foo = [4, 5, 6] +39 |-bar = [1, 2, 3] + foo + 39 |+bar = [1, 2, 3, *foo] +40 40 | zoob = tuple(bar) +41 41 | quux = (7, 8, 9) + zoob +42 42 | spam = quux + (10, 11, 12) + +RUF005.py:41:8: RUF005 [*] Consider `(7, 8, 9, *zoob)` instead of concatenation + | +41 | bar = [1, 2, 3] + foo +42 | zoob = tuple(bar) +43 | quux = (7, 8, 9) + zoob | ^^^^^^^^^^^^^^^^ RUF005 -43 | spam = quux + (10, 11, 12) -44 | spom = list(spam) +44 | spam = quux + (10, 11, 12) +45 | spom = list(spam) | = help: Replace with `(7, 8, 9, *zoob)` ℹ Suggested fix -37 37 | foo = [4, 5, 6] -38 38 | bar = [1, 2, 3] + foo -39 39 | zoob = tuple(bar) -40 |-quux = (7, 8, 9) + zoob - 40 |+quux = (7, 8, 9, *zoob) -41 41 | spam = quux + (10, 11, 12) -42 42 | spom = list(spam) -43 43 | eggs = spom + [13, 14, 15] - -RUF005.py:41:8: RUF005 [*] Consider `(*quux, 10, 11, 12)` instead of concatenation - | -41 | zoob = tuple(bar) -42 | quux = (7, 8, 9) + zoob -43 | spam = quux + (10, 11, 12) +38 38 | foo = [4, 5, 6] +39 39 | bar = [1, 2, 3] + foo +40 40 | zoob = tuple(bar) +41 |-quux = (7, 8, 9) + zoob + 41 |+quux = (7, 8, 9, *zoob) +42 42 | spam = quux + (10, 11, 12) +43 43 | spom = list(spam) +44 44 | eggs = spom + [13, 14, 15] + +RUF005.py:42:8: RUF005 [*] Consider `(*quux, 10, 11, 12)` instead of concatenation + | +42 | zoob = tuple(bar) +43 | quux = (7, 8, 9) + zoob +44 | spam = quux + (10, 11, 12) | ^^^^^^^^^^^^^^^^^^^ RUF005 -44 | spom = list(spam) -45 | eggs = spom + [13, 14, 15] +45 | spom = list(spam) +46 | eggs = spom + [13, 14, 15] | = help: Replace with `(*quux, 10, 11, 12)` ℹ Suggested fix -38 38 | bar = [1, 2, 3] + foo -39 39 | zoob = tuple(bar) -40 40 | quux = (7, 8, 9) + zoob -41 |-spam = quux + (10, 11, 12) - 41 |+spam = (*quux, 10, 11, 12) -42 42 | spom = list(spam) -43 43 | eggs = spom + [13, 14, 15] -44 44 | elatement = ("we all say",) + yay() - -RUF005.py:43:8: RUF005 [*] Consider `[*spom, 13, 14, 15]` instead of concatenation - | -43 | spam = quux + (10, 11, 12) -44 | spom = list(spam) -45 | eggs = spom + [13, 14, 15] +39 39 | bar = [1, 2, 3] + foo +40 40 | zoob = tuple(bar) +41 41 | quux = (7, 8, 9) + zoob +42 |-spam = quux + (10, 11, 12) + 42 |+spam = (*quux, 10, 11, 12) +43 43 | spom = list(spam) +44 44 | eggs = spom + [13, 14, 15] +45 45 | elatement = ("we all say",) + yay() + +RUF005.py:44:8: RUF005 [*] Consider `[*spom, 13, 14, 15]` instead of concatenation + | +44 | spam = quux + (10, 11, 12) +45 | spom = list(spam) +46 | eggs = spom + [13, 14, 15] | ^^^^^^^^^^^^^^^^^^^ RUF005 -46 | elatement = ("we all say",) + yay() -47 | excitement = ("we all think",) + Fun().yay() +47 | elatement = ("we all say",) + yay() +48 | excitement = ("we all think",) + Fun().yay() | = help: Replace with `[*spom, 13, 14, 15]` ℹ Suggested fix -40 40 | quux = (7, 8, 9) + zoob -41 41 | spam = quux + (10, 11, 12) -42 42 | spom = list(spam) -43 |-eggs = spom + [13, 14, 15] - 43 |+eggs = [*spom, 13, 14, 15] -44 44 | elatement = ("we all say",) + yay() -45 45 | excitement = ("we all think",) + Fun().yay() -46 46 | astonishment = ("we all feel",) + Fun.words - -RUF005.py:44:13: RUF005 [*] Consider `("we all say", *yay())` instead of concatenation - | -44 | spom = list(spam) -45 | eggs = spom + [13, 14, 15] -46 | elatement = ("we all say",) + yay() +41 41 | quux = (7, 8, 9) + zoob +42 42 | spam = quux + (10, 11, 12) +43 43 | spom = list(spam) +44 |-eggs = spom + [13, 14, 15] + 44 |+eggs = [*spom, 13, 14, 15] +45 45 | elatement = ("we all say",) + yay() +46 46 | excitement = ("we all think",) + Fun().yay() +47 47 | astonishment = ("we all feel",) + Fun.words + +RUF005.py:45:13: RUF005 [*] Consider `("we all say", *yay())` instead of concatenation + | +45 | spom = list(spam) +46 | eggs = spom + [13, 14, 15] +47 | elatement = ("we all say",) + yay() | ^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -47 | excitement = ("we all think",) + Fun().yay() -48 | astonishment = ("we all feel",) + Fun.words +48 | excitement = ("we all think",) + Fun().yay() +49 | astonishment = ("we all feel",) + Fun.words | = help: Replace with `("we all say", *yay())` ℹ Suggested fix -41 41 | spam = quux + (10, 11, 12) -42 42 | spom = list(spam) -43 43 | eggs = spom + [13, 14, 15] -44 |-elatement = ("we all say",) + yay() - 44 |+elatement = ("we all say", *yay()) -45 45 | excitement = ("we all think",) + Fun().yay() -46 46 | astonishment = ("we all feel",) + Fun.words -47 47 | - -RUF005.py:45:14: RUF005 [*] Consider `("we all think", *Fun().yay())` instead of concatenation - | -45 | eggs = spom + [13, 14, 15] -46 | elatement = ("we all say",) + yay() -47 | excitement = ("we all think",) + Fun().yay() +42 42 | spam = quux + (10, 11, 12) +43 43 | spom = list(spam) +44 44 | eggs = spom + [13, 14, 15] +45 |-elatement = ("we all say",) + yay() + 45 |+elatement = ("we all say", *yay()) +46 46 | excitement = ("we all think",) + Fun().yay() +47 47 | astonishment = ("we all feel",) + Fun.words +48 48 | + +RUF005.py:46:14: RUF005 [*] Consider `("we all think", *Fun().yay())` instead of concatenation + | +46 | eggs = spom + [13, 14, 15] +47 | elatement = ("we all say",) + yay() +48 | excitement = ("we all think",) + Fun().yay() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -48 | astonishment = ("we all feel",) + Fun.words +49 | astonishment = ("we all feel",) + Fun.words | = help: Replace with `("we all think", *Fun().yay())` ℹ Suggested fix -42 42 | spom = list(spam) -43 43 | eggs = spom + [13, 14, 15] -44 44 | elatement = ("we all say",) + yay() -45 |-excitement = ("we all think",) + Fun().yay() - 45 |+excitement = ("we all think", *Fun().yay()) -46 46 | astonishment = ("we all feel",) + Fun.words -47 47 | -48 48 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) - -RUF005.py:46:16: RUF005 [*] Consider `("we all feel", *Fun.words)` instead of concatenation - | -46 | elatement = ("we all say",) + yay() -47 | excitement = ("we all think",) + Fun().yay() -48 | astonishment = ("we all feel",) + Fun.words +43 43 | spom = list(spam) +44 44 | eggs = spom + [13, 14, 15] +45 45 | elatement = ("we all say",) + yay() +46 |-excitement = ("we all think",) + Fun().yay() + 46 |+excitement = ("we all think", *Fun().yay()) +47 47 | astonishment = ("we all feel",) + Fun.words +48 48 | +49 49 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + +RUF005.py:47:16: RUF005 [*] Consider `("we all feel", *Fun.words)` instead of concatenation + | +47 | elatement = ("we all say",) + yay() +48 | excitement = ("we all think",) + Fun().yay() +49 | astonishment = ("we all feel",) + Fun.words | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -49 | -50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +50 | +51 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | = help: Replace with `("we all feel", *Fun.words)` ℹ Suggested fix -43 43 | eggs = spom + [13, 14, 15] -44 44 | elatement = ("we all say",) + yay() -45 45 | excitement = ("we all think",) + Fun().yay() -46 |-astonishment = ("we all feel",) + Fun.words - 46 |+astonishment = ("we all feel", *Fun.words) -47 47 | -48 48 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) -49 49 | - -RUF005.py:48:9: RUF005 [*] Consider `["a", "b", "c", *eggs]` instead of concatenation - | -48 | astonishment = ("we all feel",) + Fun.words -49 | -50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) - | ^^^^^^^^^^^^^^^^^^^^^^ RUF005 -51 | -52 | baz = () + zoob - | - = help: Replace with `["a", "b", "c", *eggs]` +44 44 | eggs = spom + [13, 14, 15] +45 45 | elatement = ("we all say",) + yay() +46 46 | excitement = ("we all think",) + Fun().yay() +47 |-astonishment = ("we all feel",) + Fun.words + 47 |+astonishment = ("we all feel", *Fun.words) +48 48 | +49 49 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +50 50 | + +RUF005.py:49:9: RUF005 [*] Consider `["a", "b", "c", *eggs, *list(("yes", "no", "pants") + zoob)]` instead of concatenation + | +49 | astonishment = ("we all feel",) + Fun.words +50 | +51 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 +52 | +53 | baz = () + zoob + | + = help: Replace with `["a", "b", "c", *eggs, *list(("yes", "no", "pants") + zoob)]` ℹ Suggested fix -45 45 | excitement = ("we all think",) + Fun().yay() -46 46 | astonishment = ("we all feel",) + Fun.words -47 47 | -48 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) - 48 |+chain = ["a", "b", "c", *eggs] + list(("yes", "no", "pants") + zoob) -49 49 | -50 50 | baz = () + zoob -51 51 | - -RUF005.py:48:39: RUF005 [*] Consider `("yes", "no", "pants", *zoob)` instead of concatenation - | -48 | astonishment = ("we all feel",) + Fun.words -49 | -50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +46 46 | excitement = ("we all think",) + Fun().yay() +47 47 | astonishment = ("we all feel",) + Fun.words +48 48 | +49 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + 49 |+chain = ["a", "b", "c", *eggs, *list(("yes", "no", "pants") + zoob)] +50 50 | +51 51 | baz = () + zoob +52 52 | + +RUF005.py:49:39: RUF005 [*] Consider `("yes", "no", "pants", *zoob)` instead of concatenation + | +49 | astonishment = ("we all feel",) + Fun.words +50 | +51 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -51 | -52 | baz = () + zoob +52 | +53 | baz = () + zoob | = help: Replace with `("yes", "no", "pants", *zoob)` ℹ Suggested fix -45 45 | excitement = ("we all think",) + Fun().yay() -46 46 | astonishment = ("we all feel",) + Fun.words -47 47 | -48 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) - 48 |+chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants", *zoob)) -49 49 | -50 50 | baz = () + zoob -51 51 | - -RUF005.py:50:7: RUF005 [*] Consider `(*zoob,)` instead of concatenation - | -50 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) -51 | -52 | baz = () + zoob +46 46 | excitement = ("we all think",) + Fun().yay() +47 47 | astonishment = ("we all feel",) + Fun.words +48 48 | +49 |-chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) + 49 |+chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants", *zoob)) +50 50 | +51 51 | baz = () + zoob +52 52 | + +RUF005.py:51:7: RUF005 [*] Consider `(*zoob,)` instead of concatenation + | +51 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +52 | +53 | baz = () + zoob | ^^^^^^^^^ RUF005 -53 | -54 | [] + foo + [ +54 | +55 | [] + foo + [ | = help: Replace with `(*zoob,)` ℹ Suggested fix -47 47 | -48 48 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) -49 49 | -50 |-baz = () + zoob - 50 |+baz = (*zoob,) -51 51 | -52 52 | [] + foo + [ -53 53 | ] - -RUF005.py:52:1: RUF005 [*] Consider `[*foo]` instead of concatenation - | -52 | baz = () + zoob -53 | -54 | / [] + foo + [ -55 | | ] +48 48 | +49 49 | chain = ["a", "b", "c"] + eggs + list(("yes", "no", "pants") + zoob) +50 50 | +51 |-baz = () + zoob + 51 |+baz = (*zoob,) +52 52 | +53 53 | [] + foo + [ +54 54 | ] + +RUF005.py:53:1: RUF005 [*] Consider `[*foo]` instead of concatenation + | +53 | baz = () + zoob +54 | +55 | / [] + foo + [ +56 | | ] | |_^ RUF005 -56 | -57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +57 | +58 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] | = help: Replace with `[*foo]` ℹ Suggested fix -49 49 | -50 50 | baz = () + zoob -51 51 | -52 |-[] + foo + [ -53 |-] - 52 |+[*foo] -54 53 | -55 54 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -56 55 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - -RUF005.py:52:1: RUF005 [*] Consider `[*foo]` instead of concatenation - | -52 | baz = () + zoob -53 | -54 | [] + foo + [ - | ^^^^^^^^ RUF005 -55 | ] - | - = help: Replace with `[*foo]` - -ℹ Suggested fix -49 49 | -50 50 | baz = () + zoob -51 51 | -52 |-[] + foo + [ - 52 |+[*foo] + [ -53 53 | ] -54 54 | -55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - -RUF005.py:55:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args, path]` instead of concatenation - | -55 | ] -56 | -57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +50 50 | +51 51 | baz = () + zoob +52 52 | +53 |-[] + foo + [ +54 |-] + 53 |+[*foo] +55 54 | +56 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +57 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + +RUF005.py:56:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args, path]` instead of concatenation + | +56 | ] +57 | +58 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -59 | b = a + [2, 3] + [4] +59 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +60 | b = a + [2, 3] + [4] | = help: Replace with `[sys.executable, "-m", "pylint", *args, path]` ℹ Suggested fix -52 52 | [] + foo + [ -53 53 | ] -54 54 | -55 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - 55 |+pylint_call = [sys.executable, "-m", "pylint", *args, path] -56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -57 57 | b = a + [2, 3] + [4] -58 58 | - -RUF005.py:55:15: RUF005 [*] Consider `[sys.executable, "-m", "pylint", *args]` instead of concatenation - | -55 | ] -56 | -57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -59 | b = a + [2, 3] + [4] - | - = help: Replace with `[sys.executable, "-m", "pylint", *args]` - -ℹ Suggested fix -52 52 | [] + foo + [ -53 53 | ] -54 54 | -55 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] - 55 |+pylint_call = [sys.executable, "-m", "pylint", *args] + [path] -56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -57 57 | b = a + [2, 3] + [4] -58 58 | - -RUF005.py:56:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, path, path2)` instead of concatenation - | -56 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -57 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -58 | b = a + [2, 3] + [4] - | - = help: Replace with `(sys.executable, "-m", "pylint", *args, path, path2)` - -ℹ Suggested fix -53 53 | ] -54 54 | -55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -56 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - 56 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) -57 57 | b = a + [2, 3] + [4] -58 58 | -59 59 | - -RUF005.py:56:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args)` instead of concatenation - | -56 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -57 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 -58 | b = a + [2, 3] + [4] - | - = help: Replace with `(sys.executable, "-m", "pylint", *args)` - -ℹ Suggested fix -53 53 | ] -54 54 | -55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -56 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) - 56 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args) + (path, path2) -57 57 | b = a + [2, 3] + [4] -58 58 | +53 53 | [] + foo + [ +54 54 | ] +55 55 | +56 |-pylint_call = [sys.executable, "-m", "pylint"] + args + [path] + 56 |+pylint_call = [sys.executable, "-m", "pylint", *args, path] +57 57 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +58 58 | b = a + [2, 3] + [4] 59 59 | -RUF005.py:57:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation +RUF005.py:57:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, path, path2)` instead of concatenation | 57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] 58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF005 59 | b = a + [2, 3] + [4] - | ^^^^^^^^^^^^^^^^ RUF005 | - = help: Replace with `[*a, 2, 3, 4]` + = help: Replace with `(sys.executable, "-m", "pylint", *args, path, path2)` ℹ Suggested fix -54 54 | -55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -57 |-b = a + [2, 3] + [4] - 57 |+b = [*a, 2, 3, 4] -58 58 | +54 54 | ] +55 55 | +56 56 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +57 |-pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) + 57 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) +58 58 | b = a + [2, 3] + [4] 59 59 | -60 60 | ### +60 60 | -RUF005.py:57:5: RUF005 [*] Consider `[*a, 2, 3]` instead of concatenation +RUF005.py:58:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation | -57 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -58 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -59 | b = a + [2, 3] + [4] - | ^^^^^^^^^^ RUF005 +58 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +59 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +60 | b = a + [2, 3] + [4] + | ^^^^^^^^^^^^^^^^ RUF005 | - = help: Replace with `[*a, 2, 3]` + = help: Replace with `[*a, 2, 3, 4]` ℹ Suggested fix -54 54 | -55 55 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] -56 56 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) -57 |-b = a + [2, 3] + [4] - 57 |+b = [*a, 2, 3] + [4] -58 58 | +55 55 | +56 56 | pylint_call = [sys.executable, "-m", "pylint"] + args + [path] +57 57 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) +58 |-b = a + [2, 3] + [4] + 58 |+b = [*a, 2, 3, 4] 59 59 | -60 60 | ### +60 60 | +61 61 | ### From 814663f7cba7da92f199e1c3695ff79e5882cacf Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 23 May 2023 21:08:25 -0400 Subject: [PATCH 17/19] Use some matches --- .../resources/test/fixtures/ruff/RUF005.py | 13 +- .../rules/collection_literal_concatenation.rs | 153 +++++++----------- ..._rules__ruff__tests__RUF005_RUF005.py.snap | 36 ++++- 3 files changed, 97 insertions(+), 105 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/ruff/RUF005.py b/crates/ruff/resources/test/fixtures/ruff/RUF005.py index ce302485c9c2a..6477bff56bf1c 100644 --- a/crates/ruff/resources/test/fixtures/ruff/RUF005.py +++ b/crates/ruff/resources/test/fixtures/ruff/RUF005.py @@ -1,9 +1,9 @@ ### # Non-fixable Errors. ### -foo + [ # This will be preserved, but doesn't prevent the fix +foo + [ # This will be preserved. ] -[*foo] + [ # This will be preserved, but doesn't prevent the fix +[*foo] + [ # This will be preserved. ] first = [ # The order @@ -57,6 +57,8 @@ def yay(self): pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) b = a + [2, 3] + [4] +# Uses the non-preferred quote style, which should be retained. +f"{a() + ['b']}" ### # Non-errors. @@ -64,5 +66,8 @@ def yay(self): a = (1,) + [2] a = [1, 2] + (3, 4) -# Uses the non-preferred quote style, which should be retained. -f"{[*a(), 'b']}" + +### +# False negatives. +### +foo = [1, 2, 3] + bar + (4, 5, 6) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index c8316c9384a97..5ce11d29a9125 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -54,15 +54,14 @@ enum Type { Tuple, } -/// Recursively merge all the tuples/lists of the expression and return the new suggested expression -/// along with what kind of expression it is (or return none if the expression is not a concatenation of tuples/lists). -fn build_new_expr(expr: &Expr) -> Option<(Expr, Type)> { +/// Recursively merge all the tuples and lists in the expression. +fn concatenate_expressions(expr: &Expr) -> Option<(Expr, Type)> { let Expr::BinOp(ast::ExprBinOp { left, op: Operator::Add, right, range: _ }) = expr else { return None; }; let new_left = match left.as_ref() { - Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(left) { + Expr::BinOp(ast::ExprBinOp { .. }) => match concatenate_expressions(left) { Some((new_left, _)) => new_left, None => *left.clone(), }, @@ -70,121 +69,86 @@ fn build_new_expr(expr: &Expr) -> Option<(Expr, Type)> { }; let new_right = match right.as_ref() { - Expr::BinOp(ast::ExprBinOp { .. }) => match build_new_expr(right) { + Expr::BinOp(ast::ExprBinOp { .. }) => match concatenate_expressions(right) { Some((new_right, _)) => new_right, None => *right.clone(), }, _ => *right.clone(), }; - // Figure out which way the splat is, and what the kind of the collection is. - let (kind, splat_element, other_elements, splat_at_left, ctx) = match (&new_left, &new_right) { - ( - Expr::List(ast::ExprList { - elts: l_elts, - ctx, - range: _, - }), - _, - ) => (Type::List, &new_right, l_elts, false, ctx), - ( - Expr::Tuple(ast::ExprTuple { - elts: l_elts, - ctx, - range: _, - }), - _, - ) => (Type::Tuple, &new_right, l_elts, false, ctx), - ( - _, - Expr::List(ast::ExprList { - elts: r_elts, - ctx, - range: _, - }), - ) => (Type::List, &new_left, r_elts, true, ctx), - ( - _, - Expr::Tuple(ast::ExprTuple { - elts: r_elts, - ctx, - range: _, - }), - ) => (Type::Tuple, &new_left, r_elts, true, ctx), + // Figure out which way the splat is, and the type of the collection. + let (type_, splat_element, other_elements, splat_at_left) = match (&new_left, &new_right) { + (Expr::List(ast::ExprList { elts: l_elts, .. }), _) => { + (Type::List, &new_right, l_elts, false) + } + (Expr::Tuple(ast::ExprTuple { elts: l_elts, .. }), _) => { + (Type::Tuple, &new_right, l_elts, false) + } + (_, Expr::List(ast::ExprList { elts: r_elts, .. })) => { + (Type::List, &new_left, r_elts, true) + } + (_, Expr::Tuple(ast::ExprTuple { elts: r_elts, .. })) => { + (Type::Tuple, &new_left, r_elts, true) + } _ => return None, }; - // We'll be a bit conservative here; only calls, names and attribute accesses - // will be considered as splat elements. - let mut new_elts; - if splat_element.is_call_expr() - || splat_element.is_name_expr() - || splat_element.is_attribute_expr() - { - new_elts = make_splat_elts(splat_element, other_elements, splat_at_left); - } - // If the splat element is itself a list/tuple, insert them in the other list/tuple. - else if (kind == Type::List && splat_element.is_list_expr()) - || (kind == Type::Tuple && splat_element.is_tuple_expr()) - { - new_elts = other_elements.clone(); - - let elts = match splat_element { - Expr::List(ast::ExprList { elts, .. }) => elts.clone(), - Expr::Tuple(ast::ExprTuple { elts, .. }) => elts.clone(), - _ => return None, - }; - - new_elts.extend_from_slice(&elts); - } else { - return None; - } + let new_elts = match splat_element { + // We'll be a bit conservative here; only calls, names and attribute accesses + // will be considered as splat elements. + Expr::Call(_) | Expr::Attribute(_) | Expr::Name(_) => { + make_splat_elts(splat_element, other_elements, splat_at_left) + } + // If the splat element is itself a list/tuple, insert them in the other list/tuple. + Expr::List(ast::ExprList { elts, .. }) if type_ == Type::List => { + other_elements.iter().chain(elts.iter()).cloned().collect() + } + Expr::Tuple(ast::ExprTuple { elts, .. }) if type_ == Type::Tuple => { + other_elements.iter().chain(elts.iter()).cloned().collect() + } + _ => return None, + }; - let new_expr = match kind { - Type::List => { - let node = ast::ExprList { - elts: new_elts, - ctx: *ctx, - range: TextRange::default(), - }; - node.into() + let new_expr = match type_ { + Type::List => ast::ExprList { + elts: new_elts, + ctx: ExprContext::Load, + range: TextRange::default(), } - Type::Tuple => { - let node = ast::ExprTuple { - elts: new_elts, - ctx: *ctx, - range: TextRange::default(), - }; - node.into() + .into(), + Type::Tuple => ast::ExprTuple { + elts: new_elts, + ctx: ExprContext::Load, + range: TextRange::default(), } + .into(), }; - Some((new_expr, kind)) + Some((new_expr, type_)) } /// RUF005 -/// This suggestion could be unsafe if the non-literal expression in the -/// expression has overridden the `__add__` (or `__radd__`) magic methods. pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Expr) { // If the expression is already a child of an addition, we'll have analyzed it already. - if let Some(Expr::BinOp(ast::ExprBinOp { - op: Operator::Add, .. - })) = checker.semantic_model().expr_parent() - { + if matches!( + checker.semantic_model().expr_parent(), + Some(Expr::BinOp(ast::ExprBinOp { + op: Operator::Add, + .. + })) + ) { return; } - let Some((new_expr, kind)) = build_new_expr(expr) else { + let Some((new_expr, type_)) = concatenate_expressions(expr) else { return }; - let contents = match kind { - // Wrap the new expression in parentheses if it was a tuple + let contents = match type_ { + // Wrap the new expression in parentheses if it was a tuple. Type::Tuple => format!("({})", checker.generator().expr(&new_expr)), Type::List => checker.generator().expr(&new_expr), }; - let fixable = !has_comments(expr, checker.locator); - let mut diagnostic = Diagnostic::new( CollectionLiteralConcatenation { expr: contents.clone(), @@ -192,9 +156,10 @@ pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Exp expr.range(), ); if checker.patch(diagnostic.kind.rule()) { - if fixable { - #[allow(deprecated)] - diagnostic.set_fix(Fix::unspecified(Edit::range_replacement( + if !has_comments(expr, checker.locator) { + // This suggestion could be unsafe if the non-literal expression in the + // expression has overridden the `__add__` (or `__radd__`) magic methods. + diagnostic.set_fix(Fix::suggested(Edit::range_replacement( contents, expr.range(), ))); diff --git a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap index 4345a8567d7a7..a2885f683f89c 100644 --- a/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap +++ b/crates/ruff/src/rules/ruff/snapshots/ruff__rules__ruff__tests__RUF005_RUF005.py.snap @@ -5,19 +5,19 @@ RUF005.py:4:1: RUF005 Consider `[*foo]` instead of concatenation | 4 | # Non-fixable Errors. 5 | ### -6 | / foo + [ # This will be preserved, but doesn't prevent the fix +6 | / foo + [ # This will be preserved. 7 | | ] | |_^ RUF005 -8 | [*foo] + [ # This will be preserved, but doesn't prevent the fix +8 | [*foo] + [ # This will be preserved. 9 | ] | = help: Replace with `[*foo]` RUF005.py:6:1: RUF005 Consider `[*foo]` instead of concatenation | - 6 | foo + [ # This will be preserved, but doesn't prevent the fix + 6 | foo + [ # This will be preserved. 7 | ] - 8 | / [*foo] + [ # This will be preserved, but doesn't prevent the fix + 8 | / [*foo] + [ # This will be preserved. 9 | | ] | |_^ RUF005 10 | first = [ @@ -311,7 +311,7 @@ RUF005.py:57:21: RUF005 [*] Consider `(sys.executable, "-m", "pylint", *args, pa 57 |+pylint_call_tuple = (sys.executable, "-m", "pylint", *args, path, path2) 58 58 | b = a + [2, 3] + [4] 59 59 | -60 60 | +60 60 | # Uses the non-preferred quote style, which should be retained. RUF005.py:58:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation | @@ -319,6 +319,8 @@ RUF005.py:58:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation 59 | pylint_call_tuple = (sys.executable, "-m", "pylint") + args + (path, path2) 60 | b = a + [2, 3] + [4] | ^^^^^^^^^^^^^^^^ RUF005 +61 | +62 | # Uses the non-preferred quote style, which should be retained. | = help: Replace with `[*a, 2, 3, 4]` @@ -329,7 +331,27 @@ RUF005.py:58:5: RUF005 [*] Consider `[*a, 2, 3, 4]` instead of concatenation 58 |-b = a + [2, 3] + [4] 58 |+b = [*a, 2, 3, 4] 59 59 | -60 60 | -61 61 | ### +60 60 | # Uses the non-preferred quote style, which should be retained. +61 61 | f"{a() + ['b']}" + +RUF005.py:61:4: RUF005 [*] Consider `[*a(), 'b']` instead of concatenation + | +61 | # Uses the non-preferred quote style, which should be retained. +62 | f"{a() + ['b']}" + | ^^^^^^^^^^^ RUF005 +63 | +64 | ### + | + = help: Replace with `[*a(), 'b']` + +ℹ Suggested fix +58 58 | b = a + [2, 3] + [4] +59 59 | +60 60 | # Uses the non-preferred quote style, which should be retained. +61 |-f"{a() + ['b']}" + 61 |+f"{[*a(), 'b']}" +62 62 | +63 63 | ### +64 64 | # Non-errors. From 71f0af81c6ca35074b381c00646f68b7716566ba Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 23 May 2023 21:16:31 -0400 Subject: [PATCH 18/19] Tweak fixture --- crates/ruff/resources/test/fixtures/ruff/RUF005.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/crates/ruff/resources/test/fixtures/ruff/RUF005.py b/crates/ruff/resources/test/fixtures/ruff/RUF005.py index 6477bff56bf1c..2007e47a2e5e8 100644 --- a/crates/ruff/resources/test/fixtures/ruff/RUF005.py +++ b/crates/ruff/resources/test/fixtures/ruff/RUF005.py @@ -65,9 +65,4 @@ def yay(self): ### a = (1,) + [2] a = [1, 2] + (3, 4) - - -### -# False negatives. -### -foo = [1, 2, 3] + bar + (4, 5, 6) +a = ([1, 2, 3] + b) + (4, 5, 6) From a976e0512305b3f1a9f500b495677f700d9edaf8 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 23 May 2023 21:18:27 -0400 Subject: [PATCH 19/19] Use matches --- .../rules/ruff/rules/collection_literal_concatenation.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 5ce11d29a9125..c5b2196d53ef9 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -48,7 +48,7 @@ fn make_splat_elts( new_elts } -#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone)] enum Type { List, Tuple, @@ -100,10 +100,10 @@ fn concatenate_expressions(expr: &Expr) -> Option<(Expr, Type)> { make_splat_elts(splat_element, other_elements, splat_at_left) } // If the splat element is itself a list/tuple, insert them in the other list/tuple. - Expr::List(ast::ExprList { elts, .. }) if type_ == Type::List => { + Expr::List(ast::ExprList { elts, .. }) if matches!(type_, Type::List) => { other_elements.iter().chain(elts.iter()).cloned().collect() } - Expr::Tuple(ast::ExprTuple { elts, .. }) if type_ == Type::Tuple => { + Expr::Tuple(ast::ExprTuple { elts, .. }) if matches!(type_, Type::Tuple) => { other_elements.iter().chain(elts.iter()).cloned().collect() } _ => return None,