ruff/crates/ruff_linter/src
Dan Parizher 1fd852fb3f
[`ruff`] Ignore `str()` when not used for simple conversion (`RUF065`) (#21330)
## Summary

Fixed RUF065 (`logging-eager-conversion`) to only flag `str()` calls
when they perform a simple conversion that can be safely removed. The
rule now ignores `str()` calls with no arguments, multiple arguments,
starred arguments, or keyword unpacking, preventing false positives.

Fixes #21315

## Problem Analysis

The RUF065 rule was incorrectly flagging all `str()` calls in logging
statements, even when `str()` was performing actual conversion work
beyond simple type coercion. Specifically, the rule flagged:

- `str()` with no arguments - which returns an empty string
- `str(b"data", "utf-8")` with multiple arguments - which performs
encoding conversion
- `str(*args)` with starred arguments - which unpacks arguments
- `str(**kwargs)` with keyword unpacking - which passes keyword
arguments

These cases cannot be safely removed because `str()` is doing meaningful
work (encoding conversion, argument unpacking, etc.), not just redundant
type conversion.

The root cause was that the rule only checked if the function was
`str()` without validating the call signature. It didn't distinguish
between simple `str(value)` conversions (which can be removed) and more
complex `str()` calls that perform actual work.

## Approach

The fix adds validation to the `str()` detection logic in
`logging_eager_conversion.rs`:

1. **Check argument count**: Only flag `str()` calls with exactly one
positional argument (`str_call_args.args.len() == 1`)
2. **Check for starred arguments**: Ensure the single argument is not
starred (`!str_call_args.args[0].is_starred_expr()`)
3. **Check for keyword arguments**: Ensure there are no keyword
arguments (`str_call_args.keywords.is_empty()`)

This ensures the rule only flags cases like `str(value)` where `str()`
is truly redundant and can be removed, while ignoring cases where
`str()` performs actual conversion work.

The fix maintains backward compatibility - all existing valid test cases
continue to be flagged correctly, while the new edge cases are properly
ignored.

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-11-10 18:04:41 -05:00
..
checkers [`pyupgrade`] Fix false positive on relative imports from local `.builtins` module (`UP029`) (#21309) 2025-11-07 16:01:52 +00:00
comments Update insta snapshots (#14366) 2024-11-15 19:31:15 +01:00
cst Update Rust toolchain to 1.89 (#19807) 2025-08-07 18:21:50 +02:00
docstrings Add missing docstring sections to the numpy list (#20931) 2025-10-24 17:19:30 -04:00
fix Update Rust crate anyhow to v1.0.100 (#20499) 2025-09-22 09:51:52 +02:00
importer [`isort`] Fix inserting required imports before future imports (`I002`) (#20676) 2025-10-06 13:40:36 +00:00
linter [`pylint`] Detect more exotic NaN literals in `PLW0177` (#18630) 2025-06-19 11:05:06 +00:00
message Consistently wrap tokens in parser diagnostics in `backticks` instead of 'quotes' (#21163) 2025-10-31 11:59:11 -04:00
registry Remove `Message::to_rule` (#18447) 2025-06-05 12:48:29 -04:00
rules [`ruff`] Ignore `str()` when not used for simple conversion (`RUF065`) (#21330) 2025-11-10 18:04:41 -05:00
settings [`ruff`] Update schemars to v1 (#20942) 2025-10-20 08:59:52 +02:00
snapshots [semantic error tests]: refactor semantic error tests to separate files (#20926) 2025-10-27 21:18:11 +00:00
codes.rs [`pylint`] Implement `stop-iteration-return` (`PLR1708`) (#20733) 2025-10-23 15:02:41 -07:00
directives.rs Track t-strings and f-strings for token-based rules and suppression comments (#20357) 2025-09-12 13:00:12 -05:00
doc_lines.rs Update Rust toolchain to 1.89 (#19807) 2025-08-07 18:21:50 +02:00
fs.rs Render unsupported syntax errors in formatter tests (#20777) 2025-10-13 10:00:37 -04:00
lib.rs Combine `OldDiagnostic` and `Diagnostic` (#19053) 2025-07-03 13:01:09 -04:00
line_width.rs [`configuration`] Fix unclear error messages for line-length values exceeding `u16::MAX` (#21329) 2025-11-10 18:29:35 +00:00
linter.rs [semantic error tests]: refactor semantic error tests to separate files (#20926) 2025-10-27 21:18:11 +00:00
locator.rs Update Rust toolchain to 1.89 (#19807) 2025-08-07 18:21:50 +02:00
logging.rs Display diffs for `ruff format --check` and add support for different output formats (#20443) 2025-09-30 12:00:51 -04:00
noqa.rs Remove Diagnostic::expect_range and all consumers (#20322) 2025-09-10 17:19:20 -07:00
package.rs Detect empty implicit namespace packages (#14236) 2024-11-09 22:03:34 -05:00
packaging.rs Nested namespace packages support (#10541) 2024-03-24 22:53:32 -04:00
preview.rs Remove duplicate preview tests for `FURB101` and `FURB103` (#21303) 2025-11-07 12:47:21 -05:00
pyproject_toml.rs Rename `Diagnostic::syntax_error` methods, separate `Ord` implementation (#19179) 2025-07-08 09:54:19 -04:00
registry.rs Apply fix availability and applicability when adding to `DiagnosticGuard` and remove `NoqaCode::rule` (#18834) 2025-06-24 10:08:36 -04:00
renamer.rs Add a `ScopeKind` for the `__class__` cell (#20048) 2025-08-26 09:49:08 -04:00
rule_redirects.rs Document when a rule was added (#21035) 2025-10-23 14:48:41 -04:00
rule_selector.rs Document when a rule was added (#21035) 2025-10-23 14:48:41 -04:00
source_kind.rs Update MSRV to 1.85 and toolchain to 1.87 (#18126) 2025-05-16 09:19:55 +02:00
test.rs Standardize syntax error construction (#20903) 2025-10-16 11:56:32 -04:00
text_helpers.rs Handle non-printable characters in diff view (#11687) 2024-06-08 06:22:03 +00:00
upstream_categories.rs Fix pylint upstream categories not showing in docs (#10441) 2024-03-18 01:27:39 +00:00
violation.rs Document when a rule was added (#21035) 2025-10-23 14:48:41 -04:00