mirror of https://github.com/astral-sh/ruff
[`refurb`] Expand fix safety for keyword arguments and `Decimal`s (`FURB164`) (#21259)
## Summary Fixes https://github.com/astral-sh/ruff/issues/21257 ## Test Plan `cargo nextest run furb164`
This commit is contained in:
parent
d2fe6347fb
commit
79a02711c1
|
|
@ -64,3 +64,8 @@ _ = Decimal.from_float(True)
|
|||
_ = Decimal.from_float(float("-nan"))
|
||||
_ = Decimal.from_float(float("\x2dnan"))
|
||||
_ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||
|
||||
# See: https://github.com/astral-sh/ruff/issues/21257
|
||||
# fixes must be safe
|
||||
_ = Fraction.from_float(f=4.2)
|
||||
_ = Fraction.from_decimal(dec=4)
|
||||
|
|
@ -149,10 +149,9 @@ pub(crate) fn unnecessary_from_float(checker: &Checker, call: &ExprCall) {
|
|||
|
||||
// Check if we should suppress the fix due to type validation concerns
|
||||
let is_type_safe = is_valid_argument_type(arg_value, method_name, constructor, checker);
|
||||
let has_keywords = !call.arguments.keywords.is_empty();
|
||||
|
||||
// Determine fix safety
|
||||
let applicability = if is_type_safe && !has_keywords {
|
||||
let applicability = if is_type_safe {
|
||||
Applicability::Safe
|
||||
} else {
|
||||
Applicability::Unsafe
|
||||
|
|
@ -210,21 +209,27 @@ fn is_valid_argument_type(
|
|||
_ => false,
|
||||
},
|
||||
// Fraction.from_decimal accepts int, bool, Decimal
|
||||
(MethodName::FromDecimal, Constructor::Fraction) => match resolved_type {
|
||||
ResolvedPythonType::Atom(PythonType::Number(
|
||||
NumberLike::Integer | NumberLike::Bool,
|
||||
)) => true,
|
||||
ResolvedPythonType::Unknown => is_int,
|
||||
_ => {
|
||||
// Check if it's a Decimal instance
|
||||
arg_expr
|
||||
.as_call_expr()
|
||||
.and_then(|call| semantic.resolve_qualified_name(&call.func))
|
||||
.is_some_and(|qualified_name| {
|
||||
matches!(qualified_name.segments(), ["decimal", "Decimal"])
|
||||
})
|
||||
(MethodName::FromDecimal, Constructor::Fraction) => {
|
||||
// First check if it's a Decimal constructor call
|
||||
let is_decimal_call = arg_expr
|
||||
.as_call_expr()
|
||||
.and_then(|call| semantic.resolve_qualified_name(&call.func))
|
||||
.is_some_and(|qualified_name| {
|
||||
matches!(qualified_name.segments(), ["decimal", "Decimal"])
|
||||
});
|
||||
|
||||
if is_decimal_call {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
|
||||
match resolved_type {
|
||||
ResolvedPythonType::Atom(PythonType::Number(
|
||||
NumberLike::Integer | NumberLike::Bool,
|
||||
)) => true,
|
||||
ResolvedPythonType::Unknown => is_int,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
@ -274,7 +279,7 @@ fn handle_non_finite_float_special_case(
|
|||
return None;
|
||||
}
|
||||
|
||||
let Expr::Call(ast::ExprCall {
|
||||
let Expr::Call(ExprCall {
|
||||
func, arguments, ..
|
||||
}) = arg_value
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@ help: Replace with `Fraction` constructor
|
|||
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
||||
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
||||
14 | _ = Decimal.from_float(0.1)
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FURB164 [*] Verbose method `from_decimal` in `Fraction` construction
|
||||
--> FURB164.py:12:5
|
||||
|
|
@ -120,7 +119,6 @@ help: Replace with `Fraction` constructor
|
|||
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
||||
14 | _ = Decimal.from_float(0.1)
|
||||
15 | _ = Decimal.from_float(-0.5)
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FURB164 [*] Verbose method `from_decimal` in `Fraction` construction
|
||||
--> FURB164.py:13:5
|
||||
|
|
@ -484,7 +482,6 @@ help: Replace with `Fraction` constructor
|
|||
32 | _ = Decimal.from_float(f=4.2)
|
||||
33 |
|
||||
34 | # Cases with invalid argument counts - should not get fixes
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FURB164 Verbose method `from_float` in `Decimal` construction
|
||||
--> FURB164.py:32:5
|
||||
|
|
@ -658,6 +655,7 @@ help: Replace with `Decimal` constructor
|
|||
64 + _ = Decimal("nan")
|
||||
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||
67 |
|
||||
|
||||
FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||
--> FURB164.py:65:5
|
||||
|
|
@ -675,6 +673,8 @@ help: Replace with `Decimal` constructor
|
|||
- _ = Decimal.from_float(float("\x2dnan"))
|
||||
65 + _ = Decimal("nan")
|
||||
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||
67 |
|
||||
68 | # See: https://github.com/astral-sh/ruff/issues/21257
|
||||
|
||||
FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||
--> FURB164.py:66:5
|
||||
|
|
@ -683,6 +683,8 @@ FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
|||
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
67 |
|
||||
68 | # See: https://github.com/astral-sh/ruff/issues/21257
|
||||
|
|
||||
help: Replace with `Decimal` constructor
|
||||
63 | # Cases with non-finite floats - should produce safe fixes
|
||||
|
|
@ -690,3 +692,38 @@ help: Replace with `Decimal` constructor
|
|||
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||
- _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||
66 + _ = Decimal("nan")
|
||||
67 |
|
||||
68 | # See: https://github.com/astral-sh/ruff/issues/21257
|
||||
69 | # fixes must be safe
|
||||
|
||||
FURB164 [*] Verbose method `from_float` in `Fraction` construction
|
||||
--> FURB164.py:70:5
|
||||
|
|
||||
68 | # See: https://github.com/astral-sh/ruff/issues/21257
|
||||
69 | # fixes must be safe
|
||||
70 | _ = Fraction.from_float(f=4.2)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
71 | _ = Fraction.from_decimal(dec=4)
|
||||
|
|
||||
help: Replace with `Fraction` constructor
|
||||
67 |
|
||||
68 | # See: https://github.com/astral-sh/ruff/issues/21257
|
||||
69 | # fixes must be safe
|
||||
- _ = Fraction.from_float(f=4.2)
|
||||
70 + _ = Fraction(4.2)
|
||||
71 | _ = Fraction.from_decimal(dec=4)
|
||||
|
||||
FURB164 [*] Verbose method `from_decimal` in `Fraction` construction
|
||||
--> FURB164.py:71:5
|
||||
|
|
||||
69 | # fixes must be safe
|
||||
70 | _ = Fraction.from_float(f=4.2)
|
||||
71 | _ = Fraction.from_decimal(dec=4)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: Replace with `Fraction` constructor
|
||||
68 | # See: https://github.com/astral-sh/ruff/issues/21257
|
||||
69 | # fixes must be safe
|
||||
70 | _ = Fraction.from_float(f=4.2)
|
||||
- _ = Fraction.from_decimal(dec=4)
|
||||
71 + _ = Fraction(4)
|
||||
|
|
|
|||
Loading…
Reference in New Issue