Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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
| ^^^^^^^^^
|
```
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading