diff --git a/crates/ruff_linter/resources/mdtest/ruff/logging-eager-conversion.md b/crates/ruff_linter/resources/mdtest/ruff/logging-eager-conversion.md new file mode 100644 index 00000000000000..800d2776e64e79 --- /dev/null +++ b/crates/ruff_linter/resources/mdtest/ruff/logging-eager-conversion.md @@ -0,0 +1,43 @@ +# `logging-eager-conversion` (`RUF065`) + +```toml +lint.preview = true +lint.select = ["RUF065"] +``` + +## Unpacked arguments + +The presence of a starred expression (`*args`) breaks the positional mapping between format string specifiers and variadic logging arguments. Ensure eager conversions *before* the starred argument are still flagged, but bail out on ambiguous cases *after* it. + +```py +import logging + +# 1. Starred before eager conversion (should not trigger for repr("5") because the mapping is broken) +logging.warning("%s%s%s%s %s", *"1234", repr("5")) + +# 2. Eager conversion before starred (should trigger for repr("1") because it maps reliably) +logging.warning("%s %s", repr("1"), *["1234"]) # snapshot: logging-eager-conversion + +# 3. Multiple starred arguments (should not trigger anywhere) +logging.warning("%s %s %s", *["1"], *["2"], repr("3")) + +# 4. Mixed specifiers and eager conversion before starred (should trigger for repr("1")) +logging.warning("%s %s %s", repr("1"), *["2", "3"]) # snapshot: logging-eager-conversion +``` + +```snapshot +error[RUF065]: Unnecessary `repr()` conversion when formatting with `%s`. Use `%r` instead of `%s` + --> src/mdtest_snippet.py:7:26 + | +7 | logging.warning("%s %s", repr("1"), *["1234"]) # snapshot: logging-eager-conversion + | ^^^^^^^^^ + | + + +error[RUF065]: Unnecessary `repr()` conversion when formatting with `%s`. Use `%r` instead of `%s` + --> src/mdtest_snippet.py:13:29 + | +13 | logging.warning("%s %s %s", repr("1"), *["2", "3"]) # snapshot: logging-eager-conversion + | ^^^^^^^^^ + | +``` diff --git a/crates/ruff_linter/src/rules/ruff/rules/logging_eager_conversion.rs b/crates/ruff_linter/src/rules/ruff/rules/logging_eager_conversion.rs index 920f6c73a5e644..861ee00c3d9c02 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/logging_eager_conversion.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/logging_eager_conversion.rs @@ -137,7 +137,13 @@ pub(crate) fn logging_eager_conversion(checker: &Checker, call: &ast::ExprCall) None } }) - .zip(call.arguments.args.iter().skip(msg_pos + 1)) + .zip( + call.arguments + .args + .iter() + .skip(msg_pos + 1) + .take_while(|arg| !arg.is_starred_expr()), + ) { // Check if the argument is a call to eagerly format a value if let Expr::Call(ast::ExprCall {