mirror of https://github.com/astral-sh/ruff
Fix `RUF010` autofix within f-strings (#4423)
This commit is contained in:
parent
a69451ff46
commit
b9e387013f
|
|
@ -1,4 +1,5 @@
|
|||
bla = b"bla"
|
||||
d = {"a": b"bla", "b": b"bla", "c": b"bla"}
|
||||
|
||||
|
||||
def foo(one_arg):
|
||||
|
|
@ -7,6 +8,8 @@ def foo(one_arg):
|
|||
|
||||
f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
|
||||
f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
|
||||
f"{foo(bla)}" # OK
|
||||
|
||||
f"{str(bla, 'ascii')}, {str(bla, encoding='cp1255')}" # OK
|
||||
|
|
|
|||
|
|
@ -3648,7 +3648,7 @@ where
|
|||
.rules
|
||||
.enabled(Rule::ExplicitFStringTypeConversion)
|
||||
{
|
||||
ruff::rules::explicit_f_string_type_conversion(self, expr, value, *conversion);
|
||||
ruff::rules::explicit_f_string_type_conversion(self, value, *conversion);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,7 @@
|
|||
use ruff_text_size::TextSize;
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::helpers::unparse_expr;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::AsRule;
|
||||
|
|
@ -44,7 +42,6 @@ impl AlwaysAutofixableViolation for ExplicitFStringTypeConversion {
|
|||
/// RUF010
|
||||
pub(crate) fn explicit_f_string_type_conversion(
|
||||
checker: &mut Checker,
|
||||
expr: &Expr,
|
||||
formatted_value: &Expr,
|
||||
conversion: ast::Int,
|
||||
) {
|
||||
|
|
@ -70,43 +67,29 @@ pub(crate) fn explicit_f_string_type_conversion(
|
|||
return;
|
||||
};
|
||||
|
||||
if !matches!(id.as_str(), "str" | "repr" | "ascii") {
|
||||
return;
|
||||
let conversion = match id.as_str() {
|
||||
"ascii" => 'a',
|
||||
"str" => 's',
|
||||
"repr" => 'r',
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if !checker.ctx.is_builtin(id) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut diagnostic = Diagnostic::new(ExplicitFStringTypeConversion, formatted_value.range());
|
||||
let formatted_value_range = formatted_value.range();
|
||||
let mut diagnostic = Diagnostic::new(ExplicitFStringTypeConversion, formatted_value_range);
|
||||
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
// Replace the call node with its argument and a conversion flag.
|
||||
let mut conv_expr = expr.clone();
|
||||
let ExprKind::FormattedValue(ast::ExprFormattedValue {
|
||||
ref mut conversion,
|
||||
ref mut value,
|
||||
..
|
||||
}) = conv_expr.node else {
|
||||
return;
|
||||
};
|
||||
|
||||
*conversion = match id.as_str() {
|
||||
"ascii" => ast::Int::new(ast::ConversionFlag::Ascii as u32),
|
||||
"str" => ast::Int::new(ast::ConversionFlag::Str as u32),
|
||||
"repr" => ast::Int::new(ast::ConversionFlag::Repr as u32),
|
||||
&_ => unreachable!(),
|
||||
};
|
||||
|
||||
value.node = args[0].node.clone();
|
||||
|
||||
diagnostic.set_fix(Fix::automatic(Edit::range_replacement(
|
||||
unparse_expr(&conv_expr, checker.stylist),
|
||||
formatted_value
|
||||
.range()
|
||||
.sub_start(TextSize::from(1))
|
||||
.add_end(TextSize::from(1)),
|
||||
)));
|
||||
let arg_range = args[0].range();
|
||||
let remove_call = Edit::deletion(formatted_value_range.start(), arg_range.start());
|
||||
let add_conversion = Edit::replacement(
|
||||
format!("!{conversion}"),
|
||||
arg_range.end(),
|
||||
formatted_value_range.end(),
|
||||
);
|
||||
diagnostic.set_fix(Fix::automatic_edits(remove_call, [add_conversion]));
|
||||
}
|
||||
|
||||
checker.diagnostics.push(diagnostic);
|
||||
|
|
|
|||
|
|
@ -1,61 +1,124 @@
|
|||
---
|
||||
source: crates/ruff/src/rules/ruff/mod.rs
|
||||
---
|
||||
RUF010.py:8:4: RUF010 [*] Use conversion in f-string
|
||||
RUF010.py:9:4: RUF010 [*] Use conversion in f-string
|
||||
|
|
||||
8 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
| ^^^^^^^^ RUF010
|
||||
9 |
|
||||
10 | f"{foo(bla)}" # OK
|
||||
10 |
|
||||
11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
|
|
||||
= help: Replace f-string function call with conversion
|
||||
|
||||
ℹ Fix
|
||||
5 5 | pass
|
||||
6 6 |
|
||||
7 7 |
|
||||
8 |-f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
8 |+f"{bla!s}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 9 |
|
||||
10 10 | f"{foo(bla)}" # OK
|
||||
11 11 |
|
||||
6 6 | pass
|
||||
7 7 |
|
||||
8 8 |
|
||||
9 |-f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 |+f"{bla!s}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
10 10 |
|
||||
11 11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
|
||||
RUF010.py:8:16: RUF010 [*] Use conversion in f-string
|
||||
RUF010.py:9:16: RUF010 [*] Use conversion in f-string
|
||||
|
|
||||
8 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
| ^^^^^^^^^ RUF010
|
||||
9 |
|
||||
10 | f"{foo(bla)}" # OK
|
||||
10 |
|
||||
11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
|
|
||||
= help: Replace f-string function call with conversion
|
||||
|
||||
ℹ Fix
|
||||
5 5 | pass
|
||||
6 6 |
|
||||
7 7 |
|
||||
8 |-f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
8 |+f"{str(bla)}, {bla!r}, {ascii(bla)}" # RUF010
|
||||
9 9 |
|
||||
10 10 | f"{foo(bla)}" # OK
|
||||
11 11 |
|
||||
6 6 | pass
|
||||
7 7 |
|
||||
8 8 |
|
||||
9 |-f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 |+f"{str(bla)}, {bla!r}, {ascii(bla)}" # RUF010
|
||||
10 10 |
|
||||
11 11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
|
||||
RUF010.py:8:29: RUF010 [*] Use conversion in f-string
|
||||
RUF010.py:9:29: RUF010 [*] Use conversion in f-string
|
||||
|
|
||||
8 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
| ^^^^^^^^^^ RUF010
|
||||
9 |
|
||||
10 | f"{foo(bla)}" # OK
|
||||
10 |
|
||||
11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
|
|
||||
= help: Replace f-string function call with conversion
|
||||
|
||||
ℹ Fix
|
||||
5 5 | pass
|
||||
6 6 |
|
||||
7 7 |
|
||||
8 |-f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
8 |+f"{str(bla)}, {repr(bla)}, {bla!a}" # RUF010
|
||||
9 9 |
|
||||
10 10 | f"{foo(bla)}" # OK
|
||||
11 11 |
|
||||
6 6 | pass
|
||||
7 7 |
|
||||
8 8 |
|
||||
9 |-f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
9 |+f"{str(bla)}, {repr(bla)}, {bla!a}" # RUF010
|
||||
10 10 |
|
||||
11 11 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
|
||||
RUF010.py:11:4: RUF010 [*] Use conversion in f-string
|
||||
|
|
||||
11 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
12 |
|
||||
13 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
| ^^^^^^^^^^^ RUF010
|
||||
14 |
|
||||
15 | f"{foo(bla)}" # OK
|
||||
|
|
||||
= help: Replace f-string function call with conversion
|
||||
|
||||
ℹ Fix
|
||||
8 8 |
|
||||
9 9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
10 10 |
|
||||
11 |-f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
11 |+f"{d['a']!s}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
13 13 | f"{foo(bla)}" # OK
|
||||
14 14 |
|
||||
|
||||
RUF010.py:11:19: RUF010 [*] Use conversion in f-string
|
||||
|
|
||||
11 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
12 |
|
||||
13 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
| ^^^^^^^^^^^^ RUF010
|
||||
14 |
|
||||
15 | f"{foo(bla)}" # OK
|
||||
|
|
||||
= help: Replace f-string function call with conversion
|
||||
|
||||
ℹ Fix
|
||||
8 8 |
|
||||
9 9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
10 10 |
|
||||
11 |-f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
11 |+f"{str(d['a'])}, {d['b']!r}, {ascii(d['c'])}" # RUF010
|
||||
12 12 |
|
||||
13 13 | f"{foo(bla)}" # OK
|
||||
14 14 |
|
||||
|
||||
RUF010.py:11:35: RUF010 [*] Use conversion in f-string
|
||||
|
|
||||
11 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
12 |
|
||||
13 | f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
| ^^^^^^^^^^^^^ RUF010
|
||||
14 |
|
||||
15 | f"{foo(bla)}" # OK
|
||||
|
|
||||
= help: Replace f-string function call with conversion
|
||||
|
||||
ℹ Fix
|
||||
8 8 |
|
||||
9 9 | f"{str(bla)}, {repr(bla)}, {ascii(bla)}" # RUF010
|
||||
10 10 |
|
||||
11 |-f"{str(d['a'])}, {repr(d['b'])}, {ascii(d['c'])}" # RUF010
|
||||
11 |+f"{str(d['a'])}, {repr(d['b'])}, {d['c']!a}" # RUF010
|
||||
12 12 |
|
||||
13 13 | f"{foo(bla)}" # OK
|
||||
14 14 |
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue