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("-nan"))
|
||||||
_ = Decimal.from_float(float("\x2dnan"))
|
_ = Decimal.from_float(float("\x2dnan"))
|
||||||
_ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
_ = 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
|
// 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 is_type_safe = is_valid_argument_type(arg_value, method_name, constructor, checker);
|
||||||
let has_keywords = !call.arguments.keywords.is_empty();
|
|
||||||
|
|
||||||
// Determine fix safety
|
// Determine fix safety
|
||||||
let applicability = if is_type_safe && !has_keywords {
|
let applicability = if is_type_safe {
|
||||||
Applicability::Safe
|
Applicability::Safe
|
||||||
} else {
|
} else {
|
||||||
Applicability::Unsafe
|
Applicability::Unsafe
|
||||||
|
|
@ -210,21 +209,27 @@ fn is_valid_argument_type(
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
// Fraction.from_decimal accepts int, bool, Decimal
|
// Fraction.from_decimal accepts int, bool, Decimal
|
||||||
(MethodName::FromDecimal, Constructor::Fraction) => match resolved_type {
|
(MethodName::FromDecimal, Constructor::Fraction) => {
|
||||||
ResolvedPythonType::Atom(PythonType::Number(
|
// First check if it's a Decimal constructor call
|
||||||
NumberLike::Integer | NumberLike::Bool,
|
let is_decimal_call = arg_expr
|
||||||
)) => true,
|
.as_call_expr()
|
||||||
ResolvedPythonType::Unknown => is_int,
|
.and_then(|call| semantic.resolve_qualified_name(&call.func))
|
||||||
_ => {
|
.is_some_and(|qualified_name| {
|
||||||
// Check if it's a Decimal instance
|
matches!(qualified_name.segments(), ["decimal", "Decimal"])
|
||||||
arg_expr
|
});
|
||||||
.as_call_expr()
|
|
||||||
.and_then(|call| semantic.resolve_qualified_name(&call.func))
|
if is_decimal_call {
|
||||||
.is_some_and(|qualified_name| {
|
return true;
|
||||||
matches!(qualified_name.segments(), ["decimal", "Decimal"])
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
match resolved_type {
|
||||||
|
ResolvedPythonType::Atom(PythonType::Number(
|
||||||
|
NumberLike::Integer | NumberLike::Bool,
|
||||||
|
)) => true,
|
||||||
|
ResolvedPythonType::Unknown => is_int,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -274,7 +279,7 @@ fn handle_non_finite_float_special_case(
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let Expr::Call(ast::ExprCall {
|
let Expr::Call(ExprCall {
|
||||||
func, arguments, ..
|
func, arguments, ..
|
||||||
}) = arg_value
|
}) = arg_value
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,6 @@ help: Replace with `Fraction` constructor
|
||||||
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
||||||
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
||||||
14 | _ = Decimal.from_float(0.1)
|
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 [*] Verbose method `from_decimal` in `Fraction` construction
|
||||||
--> FURB164.py:12:5
|
--> FURB164.py:12:5
|
||||||
|
|
@ -120,7 +119,6 @@ help: Replace with `Fraction` constructor
|
||||||
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
||||||
14 | _ = Decimal.from_float(0.1)
|
14 | _ = Decimal.from_float(0.1)
|
||||||
15 | _ = Decimal.from_float(-0.5)
|
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 [*] Verbose method `from_decimal` in `Fraction` construction
|
||||||
--> FURB164.py:13:5
|
--> FURB164.py:13:5
|
||||||
|
|
@ -484,7 +482,6 @@ help: Replace with `Fraction` constructor
|
||||||
32 | _ = Decimal.from_float(f=4.2)
|
32 | _ = Decimal.from_float(f=4.2)
|
||||||
33 |
|
33 |
|
||||||
34 | # Cases with invalid argument counts - should not get fixes
|
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 Verbose method `from_float` in `Decimal` construction
|
||||||
--> FURB164.py:32:5
|
--> FURB164.py:32:5
|
||||||
|
|
@ -658,6 +655,7 @@ help: Replace with `Decimal` constructor
|
||||||
64 + _ = Decimal("nan")
|
64 + _ = Decimal("nan")
|
||||||
65 | _ = Decimal.from_float(float("\x2dnan"))
|
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
67 |
|
||||||
|
|
||||||
FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
--> FURB164.py:65:5
|
--> FURB164.py:65:5
|
||||||
|
|
@ -675,6 +673,8 @@ help: Replace with `Decimal` constructor
|
||||||
- _ = Decimal.from_float(float("\x2dnan"))
|
- _ = Decimal.from_float(float("\x2dnan"))
|
||||||
65 + _ = Decimal("nan")
|
65 + _ = Decimal("nan")
|
||||||
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}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 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
--> FURB164.py:66:5
|
--> FURB164.py:66:5
|
||||||
|
|
@ -683,6 +683,8 @@ FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
65 | _ = Decimal.from_float(float("\x2dnan"))
|
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
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
|
help: Replace with `Decimal` constructor
|
||||||
63 | # Cases with non-finite floats - should produce safe fixes
|
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"))
|
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
- _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
- _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
66 + _ = Decimal("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