mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +00:00
[refurb
] Mark int
and bool
cases for Decimal.from_float
as safe fixes in FURB164
tests (#19468)
## Summary Fixes #19460 --------- Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
This commit is contained in:
parent
2680f2ed81
commit
201b079084
3 changed files with 121 additions and 21 deletions
|
@ -55,3 +55,12 @@ _ = Decimal(0.1)
|
||||||
_ = Decimal(-0.5)
|
_ = Decimal(-0.5)
|
||||||
_ = Decimal(5.0)
|
_ = Decimal(5.0)
|
||||||
_ = decimal.Decimal(4.2)
|
_ = decimal.Decimal(4.2)
|
||||||
|
|
||||||
|
# Cases with int and bool - should produce safe fixes
|
||||||
|
_ = Decimal.from_float(1)
|
||||||
|
_ = Decimal.from_float(True)
|
||||||
|
|
||||||
|
# Cases with non-finite floats - should produce safe fixes
|
||||||
|
_ = Decimal.from_float(float("-nan"))
|
||||||
|
_ = Decimal.from_float(float("\x2dnan"))
|
||||||
|
_ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
|
|
@ -180,18 +180,18 @@ fn is_valid_argument_type(
|
||||||
typing::is_float(binding, semantic),
|
typing::is_float(binding, semantic),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.unwrap_or_default()
|
.unwrap_or((false, false))
|
||||||
} else {
|
} else {
|
||||||
(false, false)
|
(false, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
match (method_name, constructor) {
|
match (method_name, constructor) {
|
||||||
// Decimal.from_float accepts int, bool, float
|
// Decimal.from_float: Only int or bool are safe (float is unsafe due to FloatOperation trap)
|
||||||
(MethodName::FromFloat, Constructor::Decimal) => match resolved_type {
|
(MethodName::FromFloat, Constructor::Decimal) => match resolved_type {
|
||||||
ResolvedPythonType::Atom(PythonType::Number(
|
ResolvedPythonType::Atom(PythonType::Number(
|
||||||
NumberLike::Integer | NumberLike::Bool | NumberLike::Float,
|
NumberLike::Integer | NumberLike::Bool,
|
||||||
)) => true,
|
)) => true,
|
||||||
ResolvedPythonType::Unknown => is_int || is_float,
|
ResolvedPythonType::Unknown => is_int,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
// Fraction.from_float accepts int, bool, float
|
// Fraction.from_float accepts int, bool, float
|
||||||
|
@ -286,10 +286,8 @@ fn handle_non_finite_float_special_case(
|
||||||
let [float_arg] = arguments.args.as_ref() else {
|
let [float_arg] = arguments.args.as_ref() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
as_non_finite_float_string_literal(float_arg)?;
|
let normalized = as_non_finite_float_string_literal(float_arg)?;
|
||||||
|
let replacement_text = format!(r#"{constructor_name}("{normalized}")"#);
|
||||||
let replacement_arg = checker.locator().slice(float_arg).to_string();
|
|
||||||
let replacement_text = format!("{constructor_name}({replacement_arg})");
|
|
||||||
Some(Edit::range_replacement(replacement_text, call.range()))
|
Some(Edit::range_replacement(replacement_text, call.range()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,7 +158,7 @@ FURB164.py:13:27: FURB164 [*] Verbose method `from_float` in `Decimal` construct
|
||||||
|
|
|
|
||||||
= help: Replace with `Decimal` constructor
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
ℹ Safe fix
|
ℹ Unsafe fix
|
||||||
10 10 | _ = fractions.Fraction.from_float(4.2)
|
10 10 | _ = fractions.Fraction.from_float(4.2)
|
||||||
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
|
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
|
||||||
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
||||||
|
@ -179,7 +179,7 @@ FURB164.py:14:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
|
|
|
|
||||||
= help: Replace with `Decimal` constructor
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
ℹ Safe fix
|
ℹ Unsafe fix
|
||||||
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
|
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
|
||||||
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
||||||
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
||||||
|
@ -200,7 +200,7 @@ FURB164.py:15:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
|
|
|
|
||||||
= help: Replace with `Decimal` constructor
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
ℹ Safe fix
|
ℹ Unsafe fix
|
||||||
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
||||||
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
||||||
14 14 | _ = Decimal.from_float(0.1)
|
14 14 | _ = Decimal.from_float(0.1)
|
||||||
|
@ -221,7 +221,7 @@ FURB164.py:16:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
|
|
|
|
||||||
= help: Replace with `Decimal` constructor
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
ℹ Safe fix
|
ℹ Unsafe fix
|
||||||
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
||||||
14 14 | _ = Decimal.from_float(0.1)
|
14 14 | _ = Decimal.from_float(0.1)
|
||||||
15 15 | _ = Decimal.from_float(-0.5)
|
15 15 | _ = Decimal.from_float(-0.5)
|
||||||
|
@ -242,7 +242,7 @@ FURB164.py:17:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
|
|
|
|
||||||
= help: Replace with `Decimal` constructor
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
ℹ Safe fix
|
ℹ Unsafe fix
|
||||||
14 14 | _ = Decimal.from_float(0.1)
|
14 14 | _ = Decimal.from_float(0.1)
|
||||||
15 15 | _ = Decimal.from_float(-0.5)
|
15 15 | _ = Decimal.from_float(-0.5)
|
||||||
16 16 | _ = Decimal.from_float(5.0)
|
16 16 | _ = Decimal.from_float(5.0)
|
||||||
|
@ -310,7 +310,7 @@ FURB164.py:20:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
18 18 | _ = Decimal.from_float(float("inf"))
|
18 18 | _ = Decimal.from_float(float("inf"))
|
||||||
19 19 | _ = Decimal.from_float(float("-inf"))
|
19 19 | _ = Decimal.from_float(float("-inf"))
|
||||||
20 |-_ = Decimal.from_float(float("Infinity"))
|
20 |-_ = Decimal.from_float(float("Infinity"))
|
||||||
20 |+_ = Decimal("Infinity")
|
20 |+_ = Decimal("infinity")
|
||||||
21 21 | _ = Decimal.from_float(float("-Infinity"))
|
21 21 | _ = Decimal.from_float(float("-Infinity"))
|
||||||
22 22 | _ = Decimal.from_float(float("nan"))
|
22 22 | _ = Decimal.from_float(float("nan"))
|
||||||
23 23 | _ = Decimal.from_float(float("-NaN "))
|
23 23 | _ = Decimal.from_float(float("-NaN "))
|
||||||
|
@ -331,7 +331,7 @@ FURB164.py:21:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
19 19 | _ = Decimal.from_float(float("-inf"))
|
19 19 | _ = Decimal.from_float(float("-inf"))
|
||||||
20 20 | _ = Decimal.from_float(float("Infinity"))
|
20 20 | _ = Decimal.from_float(float("Infinity"))
|
||||||
21 |-_ = Decimal.from_float(float("-Infinity"))
|
21 |-_ = Decimal.from_float(float("-Infinity"))
|
||||||
21 |+_ = Decimal("-Infinity")
|
21 |+_ = Decimal("-infinity")
|
||||||
22 22 | _ = Decimal.from_float(float("nan"))
|
22 22 | _ = Decimal.from_float(float("nan"))
|
||||||
23 23 | _ = Decimal.from_float(float("-NaN "))
|
23 23 | _ = Decimal.from_float(float("-NaN "))
|
||||||
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
||||||
|
@ -373,7 +373,7 @@ FURB164.py:23:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
21 21 | _ = Decimal.from_float(float("-Infinity"))
|
21 21 | _ = Decimal.from_float(float("-Infinity"))
|
||||||
22 22 | _ = Decimal.from_float(float("nan"))
|
22 22 | _ = Decimal.from_float(float("nan"))
|
||||||
23 |-_ = Decimal.from_float(float("-NaN "))
|
23 |-_ = Decimal.from_float(float("-NaN "))
|
||||||
23 |+_ = Decimal("-NaN ")
|
23 |+_ = Decimal("-nan")
|
||||||
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
||||||
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
||||||
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
||||||
|
@ -394,7 +394,7 @@ FURB164.py:24:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
22 22 | _ = Decimal.from_float(float("nan"))
|
22 22 | _ = Decimal.from_float(float("nan"))
|
||||||
23 23 | _ = Decimal.from_float(float("-NaN "))
|
23 23 | _ = Decimal.from_float(float("-NaN "))
|
||||||
24 |-_ = Decimal.from_float(float(" \n+nan \t"))
|
24 |-_ = Decimal.from_float(float(" \n+nan \t"))
|
||||||
24 |+_ = Decimal(" \n+nan \t")
|
24 |+_ = Decimal("+nan")
|
||||||
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
||||||
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
||||||
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
||||||
|
@ -415,7 +415,7 @@ FURB164.py:25:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
23 23 | _ = Decimal.from_float(float("-NaN "))
|
23 23 | _ = Decimal.from_float(float("-NaN "))
|
||||||
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
||||||
25 |-_ = Decimal.from_float(float(" iNf \n\t "))
|
25 |-_ = Decimal.from_float(float(" iNf \n\t "))
|
||||||
25 |+_ = Decimal(" iNf \n\t ")
|
25 |+_ = Decimal("inf")
|
||||||
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
||||||
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
||||||
28 28 | _ = Decimal.from_float(float(" -InfinIty\n \t"))
|
28 28 | _ = Decimal.from_float(float(" -InfinIty\n \t"))
|
||||||
|
@ -436,7 +436,7 @@ FURB164.py:26:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
24 24 | _ = Decimal.from_float(float(" \n+nan \t"))
|
||||||
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
||||||
26 |-_ = Decimal.from_float(float(" -inF\n \t"))
|
26 |-_ = Decimal.from_float(float(" -inF\n \t"))
|
||||||
26 |+_ = Decimal(" -inF\n \t")
|
26 |+_ = Decimal("-inf")
|
||||||
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
||||||
28 28 | _ = Decimal.from_float(float(" -InfinIty\n \t"))
|
28 28 | _ = Decimal.from_float(float(" -InfinIty\n \t"))
|
||||||
29 29 |
|
29 29 |
|
||||||
|
@ -456,7 +456,7 @@ FURB164.py:27:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
25 25 | _ = Decimal.from_float(float(" iNf \n\t "))
|
||||||
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
||||||
27 |-_ = Decimal.from_float(float(" InfinIty \n\t "))
|
27 |-_ = Decimal.from_float(float(" InfinIty \n\t "))
|
||||||
27 |+_ = Decimal(" InfinIty \n\t ")
|
27 |+_ = Decimal("infinity")
|
||||||
28 28 | _ = Decimal.from_float(float(" -InfinIty\n \t"))
|
28 28 | _ = Decimal.from_float(float(" -InfinIty\n \t"))
|
||||||
29 29 |
|
29 29 |
|
||||||
30 30 | # Cases with keyword arguments - should produce unsafe fixes
|
30 30 | # Cases with keyword arguments - should produce unsafe fixes
|
||||||
|
@ -477,7 +477,7 @@ FURB164.py:28:5: FURB164 [*] Verbose method `from_float` in `Decimal` constructi
|
||||||
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
26 26 | _ = Decimal.from_float(float(" -inF\n \t"))
|
||||||
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
27 27 | _ = Decimal.from_float(float(" InfinIty \n\t "))
|
||||||
28 |-_ = Decimal.from_float(float(" -InfinIty\n \t"))
|
28 |-_ = Decimal.from_float(float(" -InfinIty\n \t"))
|
||||||
28 |+_ = Decimal(" -InfinIty\n \t")
|
28 |+_ = Decimal("-infinity")
|
||||||
29 29 |
|
29 29 |
|
||||||
30 30 | # Cases with keyword arguments - should produce unsafe fixes
|
30 30 | # Cases with keyword arguments - should produce unsafe fixes
|
||||||
31 31 | _ = Fraction.from_decimal(dec=Decimal("4.2"))
|
31 31 | _ = Fraction.from_decimal(dec=Decimal("4.2"))
|
||||||
|
@ -612,3 +612,96 @@ FURB164.py:45:5: FURB164 [*] Verbose method `from_float` in `Fraction` construct
|
||||||
46 46 |
|
46 46 |
|
||||||
47 47 | # OK - should not trigger the rule
|
47 47 | # OK - should not trigger the rule
|
||||||
48 48 | _ = Fraction(0.1)
|
48 48 | _ = Fraction(0.1)
|
||||||
|
|
||||||
|
FURB164.py:60:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
|
|
|
||||||
|
59 | # Cases with int and bool - should produce safe fixes
|
||||||
|
60 | _ = Decimal.from_float(1)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ FURB164
|
||||||
|
61 | _ = Decimal.from_float(True)
|
||||||
|
|
|
||||||
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
57 57 | _ = decimal.Decimal(4.2)
|
||||||
|
58 58 |
|
||||||
|
59 59 | # Cases with int and bool - should produce safe fixes
|
||||||
|
60 |-_ = Decimal.from_float(1)
|
||||||
|
60 |+_ = Decimal(1)
|
||||||
|
61 61 | _ = Decimal.from_float(True)
|
||||||
|
62 62 |
|
||||||
|
63 63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
|
||||||
|
FURB164.py:61:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
|
|
|
||||||
|
59 | # Cases with int and bool - should produce safe fixes
|
||||||
|
60 | _ = Decimal.from_float(1)
|
||||||
|
61 | _ = Decimal.from_float(True)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
|
||||||
|
62 |
|
||||||
|
63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
|
|
||||||
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
58 58 |
|
||||||
|
59 59 | # Cases with int and bool - should produce safe fixes
|
||||||
|
60 60 | _ = Decimal.from_float(1)
|
||||||
|
61 |-_ = Decimal.from_float(True)
|
||||||
|
61 |+_ = Decimal(True)
|
||||||
|
62 62 |
|
||||||
|
63 63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
64 64 | _ = Decimal.from_float(float("-nan"))
|
||||||
|
|
||||||
|
FURB164.py:64:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
|
|
|
||||||
|
63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
64 | _ = Decimal.from_float(float("-nan"))
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
|
||||||
|
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
|
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
|
|
||||||
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
61 61 | _ = Decimal.from_float(True)
|
||||||
|
62 62 |
|
||||||
|
63 63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
64 |-_ = Decimal.from_float(float("-nan"))
|
||||||
|
64 |+_ = Decimal("-nan")
|
||||||
|
65 65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
|
66 66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
|
||||||
|
FURB164.py:65:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
|
|
|
||||||
|
63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
64 | _ = Decimal.from_float(float("-nan"))
|
||||||
|
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
|
||||||
|
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
|
|
||||||
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
62 62 |
|
||||||
|
63 63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
64 64 | _ = Decimal.from_float(float("-nan"))
|
||||||
|
65 |-_ = Decimal.from_float(float("\x2dnan"))
|
||||||
|
65 |+_ = Decimal("-nan")
|
||||||
|
66 66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
|
||||||
|
FURB164.py:66:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
||||||
|
|
|
||||||
|
64 | _ = Decimal.from_float(float("-nan"))
|
||||||
|
65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
|
66 | _ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
|
||||||
|
|
|
||||||
|
= help: Replace with `Decimal` constructor
|
||||||
|
|
||||||
|
ℹ Safe fix
|
||||||
|
63 63 | # Cases with non-finite floats - should produce safe fixes
|
||||||
|
64 64 | _ = Decimal.from_float(float("-nan"))
|
||||||
|
65 65 | _ = Decimal.from_float(float("\x2dnan"))
|
||||||
|
66 |-_ = Decimal.from_float(float("\N{HYPHEN-MINUS}nan"))
|
||||||
|
66 |+_ = Decimal("-nan")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue