diff --git a/crates/ruff/resources/test/fixtures/pyupgrade/UP030_0.py b/crates/ruff/resources/test/fixtures/pyupgrade/UP030_0.py index 35b85eb3cc3e3..37e3ba4d49d4f 100644 --- a/crates/ruff/resources/test/fixtures/pyupgrade/UP030_0.py +++ b/crates/ruff/resources/test/fixtures/pyupgrade/UP030_0.py @@ -32,3 +32,30 @@ ) '{' '0}'.format(1) + +args = list(range(10)) +kwargs = {x: x for x in range(10)} + +"{0}".format(*args) + +"{0}".format(**kwargs) + +"{0}_{1}".format(*args) + +"{0}_{1}".format(1, *args) + +"{0}_{1}".format(1, 2, *args) + +"{0}_{1}".format(*args, 1, 2) + +"{0}_{1}_{2}".format(1, **kwargs) + +"{0}_{1}_{2}".format(1, 2, **kwargs) + +"{0}_{1}_{2}".format(1, 2, 3, **kwargs) + +"{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) + +"{1}_{0}".format(1, 2, *args) + +"{1}_{0}".format(1, 2) diff --git a/crates/ruff/resources/test/fixtures/pyupgrade/UP030_1.py b/crates/ruff/resources/test/fixtures/pyupgrade/UP030_1.py index 85fcf311f5c81..5cb750ece9c1c 100644 --- a/crates/ruff/resources/test/fixtures/pyupgrade/UP030_1.py +++ b/crates/ruff/resources/test/fixtures/pyupgrade/UP030_1.py @@ -15,3 +15,17 @@ print(f"{0}".format(1)) ''.format(1) + +'{1} {0}'.format(*args) + +"{1}_{0}".format(*args, 1) + +"{1}_{0}".format(*args, 1, 2) + +"{1}_{0}".format(1, **kwargs) + +"{1}_{0}".format(1, foo=2) + +"{1}_{0}".format(1, 2, **kwargs) + +"{1}_{0}".format(1, 2, foo=3, bar=4) diff --git a/crates/ruff/resources/test/fixtures/pyupgrade/UP030_2.py b/crates/ruff/resources/test/fixtures/pyupgrade/UP030_2.py deleted file mode 100644 index 30f2d0c8863da..0000000000000 --- a/crates/ruff/resources/test/fixtures/pyupgrade/UP030_2.py +++ /dev/null @@ -1,28 +0,0 @@ -# These SHOULD change - -args = list(range(10)) -kwargs = {x: x for x in range(10)} - -"{0}".format(*args) - -"{0}".format(**kwargs) - -"{0}_{1}".format(*args) - -"{0}_{1}".format(1, *args) - -"{1}_{0}".format(*args) - -"{1}_{0}".format(1, *args) - -"{0}_{1}".format(1, 2, *args) - -"{0}_{1}".format(*args, 1, 2) - -"{0}_{1}_{2}".format(1, **kwargs) - -"{0}_{1}_{2}".format(1, 2, **kwargs) - -"{0}_{1}_{2}".format(1, 2, 3, **kwargs) - -"{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) diff --git a/crates/ruff/src/checkers/ast/analyze/expression.rs b/crates/ruff/src/checkers/ast/analyze/expression.rs index ae29ce56f552f..e47b871f776a5 100644 --- a/crates/ruff/src/checkers/ast/analyze/expression.rs +++ b/crates/ruff/src/checkers/ast/analyze/expression.rs @@ -410,7 +410,7 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) { ); } if checker.enabled(Rule::FormatLiterals) { - pyupgrade::rules::format_literals(checker, &summary, expr); + pyupgrade::rules::format_literals(checker, &summary, call); } if checker.enabled(Rule::FString) { pyupgrade::rules::f_strings( diff --git a/crates/ruff/src/rules/pyupgrade/mod.rs b/crates/ruff/src/rules/pyupgrade/mod.rs index 7ffeb2b1165ff..9e2f633ba03b2 100644 --- a/crates/ruff/src/rules/pyupgrade/mod.rs +++ b/crates/ruff/src/rules/pyupgrade/mod.rs @@ -30,7 +30,6 @@ mod tests { #[test_case(Rule::FString, Path::new("UP032_2.py"))] #[test_case(Rule::FormatLiterals, Path::new("UP030_0.py"))] #[test_case(Rule::FormatLiterals, Path::new("UP030_1.py"))] - #[test_case(Rule::FormatLiterals, Path::new("UP030_2.py"))] #[test_case(Rule::LRUCacheWithMaxsizeNone, Path::new("UP033_0.py"))] #[test_case(Rule::LRUCacheWithMaxsizeNone, Path::new("UP033_1.py"))] #[test_case(Rule::LRUCacheWithoutParameters, Path::new("UP011.py"))] diff --git a/crates/ruff/src/rules/pyupgrade/rules/format_literals.rs b/crates/ruff/src/rules/pyupgrade/rules/format_literals.rs index 1469cb7e74d95..360e8b855fa52 100644 --- a/crates/ruff/src/rules/pyupgrade/rules/format_literals.rs +++ b/crates/ruff/src/rules/pyupgrade/rules/format_literals.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Result}; use libcst_native::{Arg, Expression}; use once_cell::sync::Lazy; use regex::Regex; -use ruff_python_ast::{Expr, Ranged}; +use ruff_python_ast::{self as ast, Expr, Ranged}; use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation}; use ruff_macros::{derive_message_formats, violation}; @@ -55,6 +55,77 @@ impl Violation for FormatLiterals { } } +/// UP030 +pub(crate) fn format_literals( + checker: &mut Checker, + summary: &FormatSummary, + call: &ast::ExprCall, +) { + // The format we expect is, e.g.: `"{0} {1}".format(...)` + if summary.has_nested_parts { + return; + } + if !summary.keywords.is_empty() { + return; + } + if !summary.autos.is_empty() { + return; + } + if summary.indices.is_empty() { + return; + } + if (0..summary.indices.len()).any(|index| !summary.indices.contains(&index)) { + return; + } + + // If the positional indices aren't sequential (e.g., `"{1} {0}".format(1, 2)`), then we + // need to reorder the function arguments; so we need to ensure that the function + // arguments aren't splatted (e.g., `"{1} {0}".format(*foo)`), that there are a sufficient + // number of them, etc. + let arguments = if is_sequential(&summary.indices) { + Arguments::Preserve + } else { + // Ex) `"{1} {0}".format(foo=1, bar=2)` + if !call.arguments.keywords.is_empty() { + return; + } + + // Ex) `"{1} {0}".format(foo)` + if call.arguments.args.len() < summary.indices.len() { + return; + } + + // Ex) `"{1} {0}".format(*foo)` + if call + .arguments + .args + .iter() + .take(summary.indices.len()) + .any(Expr::is_starred_expr) + { + return; + } + + Arguments::Reorder(&summary.indices) + }; + + let mut diagnostic = Diagnostic::new(FormatLiterals, call.range()); + if checker.patch(diagnostic.kind.rule()) { + diagnostic.try_set_fix(|| { + Ok(Fix::suggested(Edit::range_replacement( + generate_call(call, arguments, checker.locator(), checker.stylist())?, + call.range(), + ))) + }); + } + checker.diagnostics.push(diagnostic); +} + +/// Returns true if the indices are sequential. +fn is_sequential(indices: &[usize]) -> bool { + indices.iter().enumerate().all(|(idx, value)| idx == *value) +} + // An opening curly brace, followed by any integer, followed by any text, // followed by a closing brace. static FORMAT_SPECIFIER: Lazy = @@ -118,26 +189,30 @@ fn generate_arguments<'a>(arguments: &[Arg<'a>], order: &'a [usize]) -> Result bool { - indices.iter().enumerate().all(|(idx, value)| idx == *value) +#[derive(Debug, Copy, Clone)] +enum Arguments<'a> { + /// Preserve the arguments to the `.format(...)` call. + Preserve, + /// Reorder the arguments to the `.format(...)` call, based on the given + /// indices. + Reorder(&'a [usize]), } /// Returns the corrected function call. fn generate_call( - expr: &Expr, - correct_order: &[usize], + call: &ast::ExprCall, + arguments: Arguments, locator: &Locator, stylist: &Stylist, ) -> Result { - let content = locator.slice(expr.range()); + let content = locator.slice(call.range()); let parenthesized_content = format!("({content})"); let mut expression = match_expression(&parenthesized_content)?; // Fix the call arguments. let call = match_call_mut(&mut expression)?; - if !is_sequential(correct_order) { - call.args = generate_arguments(&call.args, correct_order)?; + if let Arguments::Reorder(order) = arguments { + call.args = generate_arguments(&call.args, order)?; } // Fix the string itself. @@ -157,34 +232,3 @@ fn generate_call( Ok(output) } - -/// UP030 -pub(crate) fn format_literals(checker: &mut Checker, summary: &FormatSummary, expr: &Expr) { - // The format we expect is, e.g.: `"{0} {1}".format(...)` - if summary.has_nested_parts { - return; - } - if !summary.keywords.is_empty() { - return; - } - if !summary.autos.is_empty() { - return; - } - if summary.indices.is_empty() { - return; - } - if (0..summary.indices.len()).any(|index| !summary.indices.contains(&index)) { - return; - } - - let mut diagnostic = Diagnostic::new(FormatLiterals, expr.range()); - if checker.patch(diagnostic.kind.rule()) { - diagnostic.try_set_fix(|| { - Ok(Fix::suggested(Edit::range_replacement( - generate_call(expr, &summary.indices, checker.locator(), checker.stylist())?, - expr.range(), - ))) - }); - } - checker.diagnostics.push(diagnostic); -} diff --git a/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP030_0.py.snap b/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP030_0.py.snap index 393bdb502c78c..a0b8e1a467227 100644 --- a/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP030_0.py.snap +++ b/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP030_0.py.snap @@ -249,7 +249,255 @@ UP030_0.py:34:1: UP030 Use implicit references for positional format fields 33 | 34 | '{' '0}'.format(1) | ^^^^^^^^^^^^^^^^^^ UP030 +35 | +36 | args = list(range(10)) | = help: Remove explicit positional indices +UP030_0.py:39:1: UP030 [*] Use implicit references for positional format fields + | +37 | kwargs = {x: x for x in range(10)} +38 | +39 | "{0}".format(*args) + | ^^^^^^^^^^^^^^^^^^^ UP030 +40 | +41 | "{0}".format(**kwargs) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +36 36 | args = list(range(10)) +37 37 | kwargs = {x: x for x in range(10)} +38 38 | +39 |-"{0}".format(*args) + 39 |+"{}".format(*args) +40 40 | +41 41 | "{0}".format(**kwargs) +42 42 | + +UP030_0.py:41:1: UP030 [*] Use implicit references for positional format fields + | +39 | "{0}".format(*args) +40 | +41 | "{0}".format(**kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^ UP030 +42 | +43 | "{0}_{1}".format(*args) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +38 38 | +39 39 | "{0}".format(*args) +40 40 | +41 |-"{0}".format(**kwargs) + 41 |+"{}".format(**kwargs) +42 42 | +43 43 | "{0}_{1}".format(*args) +44 44 | + +UP030_0.py:43:1: UP030 [*] Use implicit references for positional format fields + | +41 | "{0}".format(**kwargs) +42 | +43 | "{0}_{1}".format(*args) + | ^^^^^^^^^^^^^^^^^^^^^^^ UP030 +44 | +45 | "{0}_{1}".format(1, *args) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +40 40 | +41 41 | "{0}".format(**kwargs) +42 42 | +43 |-"{0}_{1}".format(*args) + 43 |+"{}_{}".format(*args) +44 44 | +45 45 | "{0}_{1}".format(1, *args) +46 46 | + +UP030_0.py:45:1: UP030 [*] Use implicit references for positional format fields + | +43 | "{0}_{1}".format(*args) +44 | +45 | "{0}_{1}".format(1, *args) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +46 | +47 | "{0}_{1}".format(1, 2, *args) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +42 42 | +43 43 | "{0}_{1}".format(*args) +44 44 | +45 |-"{0}_{1}".format(1, *args) + 45 |+"{}_{}".format(1, *args) +46 46 | +47 47 | "{0}_{1}".format(1, 2, *args) +48 48 | + +UP030_0.py:47:1: UP030 [*] Use implicit references for positional format fields + | +45 | "{0}_{1}".format(1, *args) +46 | +47 | "{0}_{1}".format(1, 2, *args) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +48 | +49 | "{0}_{1}".format(*args, 1, 2) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +44 44 | +45 45 | "{0}_{1}".format(1, *args) +46 46 | +47 |-"{0}_{1}".format(1, 2, *args) + 47 |+"{}_{}".format(1, 2, *args) +48 48 | +49 49 | "{0}_{1}".format(*args, 1, 2) +50 50 | + +UP030_0.py:49:1: UP030 [*] Use implicit references for positional format fields + | +47 | "{0}_{1}".format(1, 2, *args) +48 | +49 | "{0}_{1}".format(*args, 1, 2) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +50 | +51 | "{0}_{1}_{2}".format(1, **kwargs) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +46 46 | +47 47 | "{0}_{1}".format(1, 2, *args) +48 48 | +49 |-"{0}_{1}".format(*args, 1, 2) + 49 |+"{}_{}".format(*args, 1, 2) +50 50 | +51 51 | "{0}_{1}_{2}".format(1, **kwargs) +52 52 | + +UP030_0.py:51:1: UP030 [*] Use implicit references for positional format fields + | +49 | "{0}_{1}".format(*args, 1, 2) +50 | +51 | "{0}_{1}_{2}".format(1, **kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +52 | +53 | "{0}_{1}_{2}".format(1, 2, **kwargs) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +48 48 | +49 49 | "{0}_{1}".format(*args, 1, 2) +50 50 | +51 |-"{0}_{1}_{2}".format(1, **kwargs) + 51 |+"{}_{}_{}".format(1, **kwargs) +52 52 | +53 53 | "{0}_{1}_{2}".format(1, 2, **kwargs) +54 54 | + +UP030_0.py:53:1: UP030 [*] Use implicit references for positional format fields + | +51 | "{0}_{1}_{2}".format(1, **kwargs) +52 | +53 | "{0}_{1}_{2}".format(1, 2, **kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +54 | +55 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +50 50 | +51 51 | "{0}_{1}_{2}".format(1, **kwargs) +52 52 | +53 |-"{0}_{1}_{2}".format(1, 2, **kwargs) + 53 |+"{}_{}_{}".format(1, 2, **kwargs) +54 54 | +55 55 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) +56 56 | + +UP030_0.py:55:1: UP030 [*] Use implicit references for positional format fields + | +53 | "{0}_{1}_{2}".format(1, 2, **kwargs) +54 | +55 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +56 | +57 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +52 52 | +53 53 | "{0}_{1}_{2}".format(1, 2, **kwargs) +54 54 | +55 |-"{0}_{1}_{2}".format(1, 2, 3, **kwargs) + 55 |+"{}_{}_{}".format(1, 2, 3, **kwargs) +56 56 | +57 57 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) +58 58 | + +UP030_0.py:57:1: UP030 [*] Use implicit references for positional format fields + | +55 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) +56 | +57 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +58 | +59 | "{1}_{0}".format(1, 2, *args) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +54 54 | +55 55 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) +56 56 | +57 |-"{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) + 57 |+"{}_{}_{}".format(1, 2, 3, *args, **kwargs) +58 58 | +59 59 | "{1}_{0}".format(1, 2, *args) +60 60 | + +UP030_0.py:59:1: UP030 [*] Use implicit references for positional format fields + | +57 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) +58 | +59 | "{1}_{0}".format(1, 2, *args) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 +60 | +61 | "{1}_{0}".format(1, 2) + | + = help: Remove explicit positional indices + +ℹ Suggested fix +56 56 | +57 57 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) +58 58 | +59 |-"{1}_{0}".format(1, 2, *args) + 59 |+"{}_{}".format(2, 1, ) +60 60 | +61 61 | "{1}_{0}".format(1, 2) + +UP030_0.py:61:1: UP030 [*] Use implicit references for positional format fields + | +59 | "{1}_{0}".format(1, 2, *args) +60 | +61 | "{1}_{0}".format(1, 2) + | ^^^^^^^^^^^^^^^^^^^^^^ UP030 + | + = help: Remove explicit positional indices + +ℹ Suggested fix +58 58 | +59 59 | "{1}_{0}".format(1, 2, *args) +60 60 | +61 |-"{1}_{0}".format(1, 2) + 61 |+"{}_{}".format(2, 1) + diff --git a/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP030_2.py.snap b/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP030_2.py.snap deleted file mode 100644 index 7a96569187495..0000000000000 --- a/crates/ruff/src/rules/pyupgrade/snapshots/ruff__rules__pyupgrade__tests__UP030_2.py.snap +++ /dev/null @@ -1,240 +0,0 @@ ---- -source: crates/ruff/src/rules/pyupgrade/mod.rs ---- -UP030_2.py:6:1: UP030 [*] Use implicit references for positional format fields - | -4 | kwargs = {x: x for x in range(10)} -5 | -6 | "{0}".format(*args) - | ^^^^^^^^^^^^^^^^^^^ UP030 -7 | -8 | "{0}".format(**kwargs) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -3 3 | args = list(range(10)) -4 4 | kwargs = {x: x for x in range(10)} -5 5 | -6 |-"{0}".format(*args) - 6 |+"{}".format(*args) -7 7 | -8 8 | "{0}".format(**kwargs) -9 9 | - -UP030_2.py:8:1: UP030 [*] Use implicit references for positional format fields - | - 6 | "{0}".format(*args) - 7 | - 8 | "{0}".format(**kwargs) - | ^^^^^^^^^^^^^^^^^^^^^^ UP030 - 9 | -10 | "{0}_{1}".format(*args) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -5 5 | -6 6 | "{0}".format(*args) -7 7 | -8 |-"{0}".format(**kwargs) - 8 |+"{}".format(**kwargs) -9 9 | -10 10 | "{0}_{1}".format(*args) -11 11 | - -UP030_2.py:10:1: UP030 [*] Use implicit references for positional format fields - | - 8 | "{0}".format(**kwargs) - 9 | -10 | "{0}_{1}".format(*args) - | ^^^^^^^^^^^^^^^^^^^^^^^ UP030 -11 | -12 | "{0}_{1}".format(1, *args) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -7 7 | -8 8 | "{0}".format(**kwargs) -9 9 | -10 |-"{0}_{1}".format(*args) - 10 |+"{}_{}".format(*args) -11 11 | -12 12 | "{0}_{1}".format(1, *args) -13 13 | - -UP030_2.py:12:1: UP030 [*] Use implicit references for positional format fields - | -10 | "{0}_{1}".format(*args) -11 | -12 | "{0}_{1}".format(1, *args) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 -13 | -14 | "{1}_{0}".format(*args) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -9 9 | -10 10 | "{0}_{1}".format(*args) -11 11 | -12 |-"{0}_{1}".format(1, *args) - 12 |+"{}_{}".format(1, *args) -13 13 | -14 14 | "{1}_{0}".format(*args) -15 15 | - -UP030_2.py:14:1: UP030 Use implicit references for positional format fields - | -12 | "{0}_{1}".format(1, *args) -13 | -14 | "{1}_{0}".format(*args) - | ^^^^^^^^^^^^^^^^^^^^^^^ UP030 -15 | -16 | "{1}_{0}".format(1, *args) - | - = help: Remove explicit positional indices - -UP030_2.py:16:1: UP030 [*] Use implicit references for positional format fields - | -14 | "{1}_{0}".format(*args) -15 | -16 | "{1}_{0}".format(1, *args) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 -17 | -18 | "{0}_{1}".format(1, 2, *args) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -13 13 | -14 14 | "{1}_{0}".format(*args) -15 15 | -16 |-"{1}_{0}".format(1, *args) - 16 |+"{}_{}".format(*args, 1) -17 17 | -18 18 | "{0}_{1}".format(1, 2, *args) -19 19 | - -UP030_2.py:18:1: UP030 [*] Use implicit references for positional format fields - | -16 | "{1}_{0}".format(1, *args) -17 | -18 | "{0}_{1}".format(1, 2, *args) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 -19 | -20 | "{0}_{1}".format(*args, 1, 2) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -15 15 | -16 16 | "{1}_{0}".format(1, *args) -17 17 | -18 |-"{0}_{1}".format(1, 2, *args) - 18 |+"{}_{}".format(1, 2, *args) -19 19 | -20 20 | "{0}_{1}".format(*args, 1, 2) -21 21 | - -UP030_2.py:20:1: UP030 [*] Use implicit references for positional format fields - | -18 | "{0}_{1}".format(1, 2, *args) -19 | -20 | "{0}_{1}".format(*args, 1, 2) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 -21 | -22 | "{0}_{1}_{2}".format(1, **kwargs) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -17 17 | -18 18 | "{0}_{1}".format(1, 2, *args) -19 19 | -20 |-"{0}_{1}".format(*args, 1, 2) - 20 |+"{}_{}".format(*args, 1, 2) -21 21 | -22 22 | "{0}_{1}_{2}".format(1, **kwargs) -23 23 | - -UP030_2.py:22:1: UP030 [*] Use implicit references for positional format fields - | -20 | "{0}_{1}".format(*args, 1, 2) -21 | -22 | "{0}_{1}_{2}".format(1, **kwargs) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 -23 | -24 | "{0}_{1}_{2}".format(1, 2, **kwargs) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -19 19 | -20 20 | "{0}_{1}".format(*args, 1, 2) -21 21 | -22 |-"{0}_{1}_{2}".format(1, **kwargs) - 22 |+"{}_{}_{}".format(1, **kwargs) -23 23 | -24 24 | "{0}_{1}_{2}".format(1, 2, **kwargs) -25 25 | - -UP030_2.py:24:1: UP030 [*] Use implicit references for positional format fields - | -22 | "{0}_{1}_{2}".format(1, **kwargs) -23 | -24 | "{0}_{1}_{2}".format(1, 2, **kwargs) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 -25 | -26 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -21 21 | -22 22 | "{0}_{1}_{2}".format(1, **kwargs) -23 23 | -24 |-"{0}_{1}_{2}".format(1, 2, **kwargs) - 24 |+"{}_{}_{}".format(1, 2, **kwargs) -25 25 | -26 26 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) -27 27 | - -UP030_2.py:26:1: UP030 [*] Use implicit references for positional format fields - | -24 | "{0}_{1}_{2}".format(1, 2, **kwargs) -25 | -26 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 -27 | -28 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) - | - = help: Remove explicit positional indices - -ℹ Suggested fix -23 23 | -24 24 | "{0}_{1}_{2}".format(1, 2, **kwargs) -25 25 | -26 |-"{0}_{1}_{2}".format(1, 2, 3, **kwargs) - 26 |+"{}_{}_{}".format(1, 2, 3, **kwargs) -27 27 | -28 28 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) - -UP030_2.py:28:1: UP030 [*] Use implicit references for positional format fields - | -26 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) -27 | -28 | "{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UP030 - | - = help: Remove explicit positional indices - -ℹ Suggested fix -25 25 | -26 26 | "{0}_{1}_{2}".format(1, 2, 3, **kwargs) -27 27 | -28 |-"{0}_{1}_{2}".format(1, 2, 3, *args, **kwargs) - 28 |+"{}_{}_{}".format(1, 2, 3, *args, **kwargs) - -