From 2cc3cefc2d1ae4de84f86ea94cbb284567add725 Mon Sep 17 00:00:00 2001 From: Evan Rittenhouse Date: Sat, 3 Jun 2023 10:23:46 -0500 Subject: [PATCH] Make FLY002 emit a string (instead of an f-string) if all join() arguments are strings --- .../flynt/rules/static_join_to_fstring.rs | 25 ++++++++++--------- ...rules__flynt__tests__FLY002_FLY002.py.snap | 6 ++--- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs b/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs index a43f6804a59b2b..db7cc6ae22c690 100644 --- a/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs +++ b/crates/ruff/src/rules/flynt/rules/static_join_to_fstring.rs @@ -1,3 +1,4 @@ +use itertools::Itertools; use ruff_text_size::TextRange; use rustpython_parser::ast::{self, Constant, Expr, Ranged}; @@ -33,7 +34,7 @@ fn is_static_length(elts: &[Expr]) -> bool { fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { let mut fstring_elems = Vec::with_capacity(joinees.len() * 2); let mut first = true; - let mut only_strings = true; + let mut strings: Vec<&String> = vec![]; for expr in joinees { if matches!(expr, Expr::JoinedStr(_)) { @@ -46,20 +47,18 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { } fstring_elems.push(helpers::to_fstring_elem(expr)?); - if !matches!( - expr, - Expr::Constant(ast::ExprConstant { - value: Constant::Str(_), - .. - }) - ) { - only_strings = false; + if let Expr::Constant(ast::ExprConstant { + value: Constant::Str(value), + .. + }) = expr + { + strings.push(value); } } - let node = if only_strings { + let node = if strings.len() == joinees.len() { ast::Expr::Constant(ast::ExprConstant { - value: fstring_elems.iter().collect::().into(), + value: Constant::Str(strings.iter().join(joiner)), range: TextRange::default(), kind: None, }) @@ -68,8 +67,10 @@ fn build_fstring(joiner: &str, joinees: &[Expr]) -> Option { values: fstring_elems, range: TextRange::default(), } + .into() }; - Some(node.into()) + + Some(node) } pub(crate) fn static_join_to_fstring(checker: &mut Checker, expr: &Expr, joiner: &str) { diff --git a/crates/ruff/src/rules/flynt/snapshots/ruff__rules__flynt__tests__FLY002_FLY002.py.snap b/crates/ruff/src/rules/flynt/snapshots/ruff__rules__flynt__tests__FLY002_FLY002.py.snap index d268b251ba6a96..e987f86206f848 100644 --- a/crates/ruff/src/rules/flynt/snapshots/ruff__rules__flynt__tests__FLY002_FLY002.py.snap +++ b/crates/ruff/src/rules/flynt/snapshots/ruff__rules__flynt__tests__FLY002_FLY002.py.snap @@ -42,7 +42,7 @@ FLY002.py:6:7: FLY002 [*] Consider `f"Finally, {a} World"` instead of string joi 8 8 | ok4 = "y".join([1, 2, 3]) # Technically OK, though would've been an error originally 9 9 | ok5 = "a".join([random(), random()]) # OK (simple calls) -FLY002.py:7:7: FLY002 [*] Consider `f"1x2x3"` instead of string join +FLY002.py:7:7: FLY002 [*] Consider `"1x2x3"` instead of string join | 7 | ok1 = " ".join([a, " World"]) # OK 8 | ok2 = "".join(["Finally, ", a, " World"]) # OK @@ -51,14 +51,14 @@ FLY002.py:7:7: FLY002 [*] Consider `f"1x2x3"` instead of string join 10 | ok4 = "y".join([1, 2, 3]) # Technically OK, though would've been an error originally 11 | ok5 = "a".join([random(), random()]) # OK (simple calls) | - = help: Replace with `f"1x2x3"` + = help: Replace with `"1x2x3"` ℹ Suggested fix 4 4 | a = "Hello" 5 5 | ok1 = " ".join([a, " World"]) # OK 6 6 | ok2 = "".join(["Finally, ", a, " World"]) # OK 7 |-ok3 = "x".join(("1", "2", "3")) # OK - 7 |+ok3 = f"1x2x3" # OK + 7 |+ok3 = "1x2x3" # OK 8 8 | ok4 = "y".join([1, 2, 3]) # Technically OK, though would've been an error originally 9 9 | ok5 = "a".join([random(), random()]) # OK (simple calls) 10 10 | ok6 = "a".join([secrets.token_urlsafe(), secrets.token_hex()]) # OK (attr calls)