[refurb] Implement unnecessary-from-float (FURB164) (#10647)

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->

Implement FURB164 in the issue #1348.
Relevant Refurb docs is here:
https://github.com/dosisod/refurb/blob/v2.0.0/docs/checks.md#furb164-no-from-float

I've changed the name from `no-from-float` to
`verbose-decimal-fraction-construction`.

## Test Plan

<!-- How was it tested? -->

I've written it in the `FURB164.py`.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
This commit is contained in:
hikaru-kajita 2024-03-30 20:04:01 +09:00 committed by GitHub
parent 75e01420fa
commit 9ad9cea952
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 606 additions and 2 deletions

View file

@ -0,0 +1,34 @@
from decimal import Decimal
from fractions import Fraction
import decimal
import fractions
# Errors
_ = Fraction.from_float(0.1)
_ = Fraction.from_float(-0.5)
_ = Fraction.from_float(5.0)
_ = fractions.Fraction.from_float(4.2)
_ = Fraction.from_decimal(Decimal("4.2"))
_ = Fraction.from_decimal(Decimal("-4.2"))
_ = Fraction.from_decimal(Decimal.from_float(4.2))
_ = Decimal.from_float(0.1)
_ = Decimal.from_float(-0.5)
_ = Decimal.from_float(5.0)
_ = decimal.Decimal.from_float(4.2)
_ = Decimal.from_float(float("inf"))
_ = Decimal.from_float(float("-inf"))
_ = Decimal.from_float(float("Infinity"))
_ = Decimal.from_float(float("-Infinity"))
_ = Decimal.from_float(float("nan"))
# OK
_ = Fraction(0.1)
_ = Fraction(-0.5)
_ = Fraction(5.0)
_ = fractions.Fraction(4.2)
_ = Fraction(Decimal("4.2"))
_ = Fraction(Decimal("-4.2"))
_ = Decimal(0.1)
_ = Decimal(-0.5)
_ = Decimal(5.0)
_ = decimal.Decimal(4.2)

View file

@ -929,6 +929,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
if checker.enabled(Rule::VerboseDecimalConstructor) { if checker.enabled(Rule::VerboseDecimalConstructor) {
refurb::rules::verbose_decimal_constructor(checker, call); refurb::rules::verbose_decimal_constructor(checker, call);
} }
if checker.enabled(Rule::UnnecessaryFromFloat) {
refurb::rules::unnecessary_from_float(checker, call);
}
if checker.enabled(Rule::QuadraticListSummation) { if checker.enabled(Rule::QuadraticListSummation) {
ruff::rules::quadratic_list_summation(checker, call); ruff::rules::quadratic_list_summation(checker, call);
} }

View file

@ -1051,6 +1051,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Refurb, "157") => (RuleGroup::Preview, rules::refurb::rules::VerboseDecimalConstructor), (Refurb, "157") => (RuleGroup::Preview, rules::refurb::rules::VerboseDecimalConstructor),
(Refurb, "161") => (RuleGroup::Preview, rules::refurb::rules::BitCount), (Refurb, "161") => (RuleGroup::Preview, rules::refurb::rules::BitCount),
(Refurb, "163") => (RuleGroup::Preview, rules::refurb::rules::RedundantLogBase), (Refurb, "163") => (RuleGroup::Preview, rules::refurb::rules::RedundantLogBase),
(Refurb, "164") => (RuleGroup::Preview, rules::refurb::rules::UnnecessaryFromFloat),
(Refurb, "167") => (RuleGroup::Preview, rules::refurb::rules::RegexFlagAlias), (Refurb, "167") => (RuleGroup::Preview, rules::refurb::rules::RegexFlagAlias),
(Refurb, "168") => (RuleGroup::Preview, rules::refurb::rules::IsinstanceTypeNone), (Refurb, "168") => (RuleGroup::Preview, rules::refurb::rules::IsinstanceTypeNone),
(Refurb, "169") => (RuleGroup::Preview, rules::refurb::rules::TypeNoneComparison), (Refurb, "169") => (RuleGroup::Preview, rules::refurb::rules::TypeNoneComparison),

View file

@ -27,6 +27,7 @@ mod tests {
#[test_case(Rule::UnnecessaryEnumerate, Path::new("FURB148.py"))] #[test_case(Rule::UnnecessaryEnumerate, Path::new("FURB148.py"))]
#[test_case(Rule::MathConstant, Path::new("FURB152.py"))] #[test_case(Rule::MathConstant, Path::new("FURB152.py"))]
#[test_case(Rule::VerboseDecimalConstructor, Path::new("FURB157.py"))] #[test_case(Rule::VerboseDecimalConstructor, Path::new("FURB157.py"))]
#[test_case(Rule::UnnecessaryFromFloat, Path::new("FURB164.py"))]
#[test_case(Rule::PrintEmptyString, Path::new("FURB105.py"))] #[test_case(Rule::PrintEmptyString, Path::new("FURB105.py"))]
#[test_case(Rule::ImplicitCwd, Path::new("FURB177.py"))] #[test_case(Rule::ImplicitCwd, Path::new("FURB177.py"))]
#[test_case(Rule::SingleItemMembershipTest, Path::new("FURB171.py"))] #[test_case(Rule::SingleItemMembershipTest, Path::new("FURB171.py"))]

View file

@ -21,6 +21,7 @@ pub(crate) use single_item_membership_test::*;
pub(crate) use slice_copy::*; pub(crate) use slice_copy::*;
pub(crate) use type_none_comparison::*; pub(crate) use type_none_comparison::*;
pub(crate) use unnecessary_enumerate::*; pub(crate) use unnecessary_enumerate::*;
pub(crate) use unnecessary_from_float::*;
pub(crate) use verbose_decimal_constructor::*; pub(crate) use verbose_decimal_constructor::*;
mod bit_count; mod bit_count;
@ -46,4 +47,5 @@ mod single_item_membership_test;
mod slice_copy; mod slice_copy;
mod type_none_comparison; mod type_none_comparison;
mod unnecessary_enumerate; mod unnecessary_enumerate;
mod unnecessary_from_float;
mod verbose_decimal_constructor; mod verbose_decimal_constructor;

View file

@ -0,0 +1,205 @@
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Expr, ExprCall};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
/// ## What it does
/// Checks for unnecessary `from_float` and `from_decimal` usages to construct
/// `Decimal` and `Fraction` instances.
///
/// ## Why is this bad?
/// Since Python 3.2, the `Fraction` and `Decimal` classes can be constructed
/// by passing float or decimal instances to the constructor directly. As such,
/// the use of `from_float` and `from_decimal` methods is unnecessary, and
/// should be avoided in favor of the more concise constructor syntax.
///
/// ## Examples
/// ```python
/// Decimal.from_float(4.2)
/// Decimal.from_float(float("inf"))
/// Fraction.from_float(4.2)
/// Fraction.from_decimal(Decimal("4.2"))
/// ```
///
/// Use instead:
/// ```python
/// Decimal(4.2)
/// Decimal("inf")
/// Fraction(4.2)
/// Fraction(Decimal(4.2))
/// ```
///
/// ## References
/// - [Python documentation: `decimal`](https://docs.python.org/3/library/decimal.html)
/// - [Python documentation: `fractions`](https://docs.python.org/3/library/fractions.html)
#[violation]
pub struct UnnecessaryFromFloat {
method_name: MethodName,
constructor: Constructor,
}
impl Violation for UnnecessaryFromFloat {
const FIX_AVAILABILITY: FixAvailability = FixAvailability::Sometimes;
#[derive_message_formats]
fn message(&self) -> String {
let UnnecessaryFromFloat {
method_name,
constructor,
} = self;
format!("Verbose method `{method_name}` in `{constructor}` construction",)
}
fn fix_title(&self) -> Option<String> {
let UnnecessaryFromFloat { constructor, .. } = self;
Some(format!("Replace with `{constructor}` constructor"))
}
}
/// FURB164
pub(crate) fn unnecessary_from_float(checker: &mut Checker, call: &ExprCall) {
let Expr::Attribute(ast::ExprAttribute { value, attr, .. }) = &*call.func else {
return;
};
// The method name must be either `from_float` or `from_decimal`.
let method_name = match attr.as_str() {
"from_float" => MethodName::FromFloat,
"from_decimal" => MethodName::FromDecimal,
_ => return,
};
// The value must be either `decimal.Decimal` or `fractions.Fraction`.
let Some(constructor) =
checker
.semantic()
.resolve_qualified_name(value)
.and_then(|qualified_name| match qualified_name.segments() {
["decimal", "Decimal"] => Some(Constructor::Decimal),
["fractions", "Fraction"] => Some(Constructor::Fraction),
_ => None,
})
else {
return;
};
// `Decimal.from_decimal` doesn't exist.
if matches!(
(method_name, constructor),
(MethodName::FromDecimal, Constructor::Decimal)
) {
return;
}
let mut diagnostic = Diagnostic::new(
UnnecessaryFromFloat {
method_name,
constructor,
},
call.range(),
);
let edit = Edit::range_replacement(
checker.locator().slice(&**value).to_string(),
call.func.range(),
);
// Short-circuit case for special values, such as: `Decimal.from_float(float("inf"))` to `Decimal("inf")`.
'short_circuit: {
if !matches!(constructor, Constructor::Decimal) {
break 'short_circuit;
};
if !(method_name == MethodName::FromFloat) {
break 'short_circuit;
};
let Some(value) = (match method_name {
MethodName::FromFloat => call.arguments.find_argument("f", 0),
MethodName::FromDecimal => call.arguments.find_argument("dec", 0),
}) else {
return;
};
let Expr::Call(
call @ ast::ExprCall {
func, arguments, ..
},
) = value
else {
break 'short_circuit;
};
// Must be a call to the `float` builtin.
let Some(func_name) = func.as_name_expr() else {
break 'short_circuit;
};
if func_name.id != "float" {
break 'short_circuit;
};
// Must have exactly one argument, which is a string literal.
if arguments.keywords.len() != 0 {
break 'short_circuit;
};
let [float] = arguments.args.as_ref() else {
break 'short_circuit;
};
let Some(float) = float.as_string_literal_expr() else {
break 'short_circuit;
};
if !matches!(
float.value.to_str().to_lowercase().as_str(),
"inf" | "-inf" | "infinity" | "-infinity" | "nan"
) {
break 'short_circuit;
}
if !checker.semantic().is_builtin("float") {
break 'short_circuit;
};
let replacement = checker.locator().slice(float).to_string();
diagnostic.set_fix(Fix::safe_edits(
edit,
[Edit::range_replacement(replacement, call.range())],
));
checker.diagnostics.push(diagnostic);
return;
}
diagnostic.set_fix(Fix::safe_edit(edit));
checker.diagnostics.push(diagnostic);
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum MethodName {
FromFloat,
FromDecimal,
}
impl std::fmt::Display for MethodName {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
MethodName::FromFloat => fmt.write_str("from_float"),
MethodName::FromDecimal => fmt.write_str("from_decimal"),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Constructor {
Decimal,
Fraction,
}
impl std::fmt::Display for Constructor {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Constructor::Decimal => fmt.write_str("Decimal"),
Constructor::Fraction => fmt.write_str("Fraction"),
}
}
}

View file

@ -1,6 +1,6 @@
use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation}; use ruff_diagnostics::{Diagnostic, Edit, Fix, FixAvailability, Violation};
use ruff_macros::{derive_message_formats, violation}; use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::{self as ast, Expr, ExprCall}; use ruff_python_ast::{self as ast, Expr};
use ruff_python_trivia::PythonWhitespace; use ruff_python_trivia::PythonWhitespace;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
@ -56,7 +56,7 @@ impl Violation for VerboseDecimalConstructor {
} }
/// FURB157 /// FURB157
pub(crate) fn verbose_decimal_constructor(checker: &mut Checker, call: &ExprCall) { pub(crate) fn verbose_decimal_constructor(checker: &mut Checker, call: &ast::ExprCall) {
if !checker if !checker
.semantic() .semantic()
.resolve_qualified_name(&call.func) .resolve_qualified_name(&call.func)

View file

@ -0,0 +1,357 @@
---
source: crates/ruff_linter/src/rules/refurb/mod.rs
---
FURB164.py:7:5: FURB164 [*] Verbose method `from_float` in `Fraction` construction
|
6 | # Errors
7 | _ = Fraction.from_float(0.1)
| ^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
8 | _ = Fraction.from_float(-0.5)
9 | _ = Fraction.from_float(5.0)
|
= help: Replace with `Fraction` constructor
Safe fix
4 4 | import fractions
5 5 |
6 6 | # Errors
7 |-_ = Fraction.from_float(0.1)
7 |+_ = Fraction(0.1)
8 8 | _ = Fraction.from_float(-0.5)
9 9 | _ = Fraction.from_float(5.0)
10 10 | _ = fractions.Fraction.from_float(4.2)
FURB164.py:8:5: FURB164 [*] Verbose method `from_float` in `Fraction` construction
|
6 | # Errors
7 | _ = Fraction.from_float(0.1)
8 | _ = Fraction.from_float(-0.5)
| ^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
9 | _ = Fraction.from_float(5.0)
10 | _ = fractions.Fraction.from_float(4.2)
|
= help: Replace with `Fraction` constructor
Safe fix
5 5 |
6 6 | # Errors
7 7 | _ = Fraction.from_float(0.1)
8 |-_ = Fraction.from_float(-0.5)
8 |+_ = Fraction(-0.5)
9 9 | _ = Fraction.from_float(5.0)
10 10 | _ = fractions.Fraction.from_float(4.2)
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
FURB164.py:9:5: FURB164 [*] Verbose method `from_float` in `Fraction` construction
|
7 | _ = Fraction.from_float(0.1)
8 | _ = Fraction.from_float(-0.5)
9 | _ = Fraction.from_float(5.0)
| ^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
10 | _ = fractions.Fraction.from_float(4.2)
11 | _ = Fraction.from_decimal(Decimal("4.2"))
|
= help: Replace with `Fraction` constructor
Safe fix
6 6 | # Errors
7 7 | _ = Fraction.from_float(0.1)
8 8 | _ = Fraction.from_float(-0.5)
9 |-_ = Fraction.from_float(5.0)
9 |+_ = Fraction(5.0)
10 10 | _ = fractions.Fraction.from_float(4.2)
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
FURB164.py:10:5: FURB164 [*] Verbose method `from_float` in `Fraction` construction
|
8 | _ = Fraction.from_float(-0.5)
9 | _ = Fraction.from_float(5.0)
10 | _ = fractions.Fraction.from_float(4.2)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
|
= help: Replace with `Fraction` constructor
Safe fix
7 7 | _ = Fraction.from_float(0.1)
8 8 | _ = Fraction.from_float(-0.5)
9 9 | _ = Fraction.from_float(5.0)
10 |-_ = fractions.Fraction.from_float(4.2)
10 |+_ = fractions.Fraction(4.2)
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
FURB164.py:11:5: FURB164 [*] Verbose method `from_decimal` in `Fraction` construction
|
9 | _ = Fraction.from_float(5.0)
10 | _ = fractions.Fraction.from_float(4.2)
11 | _ = Fraction.from_decimal(Decimal("4.2"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
|
= help: Replace with `Fraction` constructor
Safe fix
8 8 | _ = Fraction.from_float(-0.5)
9 9 | _ = Fraction.from_float(5.0)
10 10 | _ = fractions.Fraction.from_float(4.2)
11 |-_ = Fraction.from_decimal(Decimal("4.2"))
11 |+_ = Fraction(Decimal("4.2"))
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 14 | _ = Decimal.from_float(0.1)
FURB164.py:12:5: FURB164 [*] Verbose method `from_decimal` in `Fraction` construction
|
10 | _ = fractions.Fraction.from_float(4.2)
11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 | _ = Decimal.from_float(0.1)
|
= help: Replace with `Fraction` constructor
Safe fix
9 9 | _ = Fraction.from_float(5.0)
10 10 | _ = fractions.Fraction.from_float(4.2)
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 |-_ = Fraction.from_decimal(Decimal("-4.2"))
12 |+_ = Fraction(Decimal("-4.2"))
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 14 | _ = Decimal.from_float(0.1)
15 15 | _ = Decimal.from_float(-0.5)
FURB164.py:13:5: FURB164 [*] Verbose method `from_decimal` in `Fraction` construction
|
11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
14 | _ = Decimal.from_float(0.1)
15 | _ = Decimal.from_float(-0.5)
|
= help: Replace with `Fraction` constructor
Safe fix
10 10 | _ = fractions.Fraction.from_float(4.2)
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 |-_ = Fraction.from_decimal(Decimal.from_float(4.2))
13 |+_ = Fraction(Decimal.from_float(4.2))
14 14 | _ = Decimal.from_float(0.1)
15 15 | _ = Decimal.from_float(-0.5)
16 16 | _ = Decimal.from_float(5.0)
FURB164.py:13:27: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB164
14 | _ = Decimal.from_float(0.1)
15 | _ = Decimal.from_float(-0.5)
|
= help: Replace with `Decimal` constructor
Safe fix
10 10 | _ = fractions.Fraction.from_float(4.2)
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 |-_ = Fraction.from_decimal(Decimal.from_float(4.2))
13 |+_ = Fraction.from_decimal(Decimal(4.2))
14 14 | _ = Decimal.from_float(0.1)
15 15 | _ = Decimal.from_float(-0.5)
16 16 | _ = Decimal.from_float(5.0)
FURB164.py:14:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 | _ = Decimal.from_float(0.1)
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB164
15 | _ = Decimal.from_float(-0.5)
16 | _ = Decimal.from_float(5.0)
|
= help: Replace with `Decimal` constructor
Safe fix
11 11 | _ = Fraction.from_decimal(Decimal("4.2"))
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 |-_ = Decimal.from_float(0.1)
14 |+_ = Decimal(0.1)
15 15 | _ = Decimal.from_float(-0.5)
16 16 | _ = Decimal.from_float(5.0)
17 17 | _ = decimal.Decimal.from_float(4.2)
FURB164.py:15:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 | _ = Decimal.from_float(0.1)
15 | _ = Decimal.from_float(-0.5)
| ^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
16 | _ = Decimal.from_float(5.0)
17 | _ = decimal.Decimal.from_float(4.2)
|
= help: Replace with `Decimal` constructor
Safe fix
12 12 | _ = Fraction.from_decimal(Decimal("-4.2"))
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 14 | _ = Decimal.from_float(0.1)
15 |-_ = Decimal.from_float(-0.5)
15 |+_ = Decimal(-0.5)
16 16 | _ = Decimal.from_float(5.0)
17 17 | _ = decimal.Decimal.from_float(4.2)
18 18 | _ = Decimal.from_float(float("inf"))
FURB164.py:16:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
14 | _ = Decimal.from_float(0.1)
15 | _ = Decimal.from_float(-0.5)
16 | _ = Decimal.from_float(5.0)
| ^^^^^^^^^^^^^^^^^^^^^^^ FURB164
17 | _ = decimal.Decimal.from_float(4.2)
18 | _ = Decimal.from_float(float("inf"))
|
= help: Replace with `Decimal` constructor
Safe fix
13 13 | _ = Fraction.from_decimal(Decimal.from_float(4.2))
14 14 | _ = Decimal.from_float(0.1)
15 15 | _ = Decimal.from_float(-0.5)
16 |-_ = Decimal.from_float(5.0)
16 |+_ = Decimal(5.0)
17 17 | _ = decimal.Decimal.from_float(4.2)
18 18 | _ = Decimal.from_float(float("inf"))
19 19 | _ = Decimal.from_float(float("-inf"))
FURB164.py:17:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
15 | _ = Decimal.from_float(-0.5)
16 | _ = Decimal.from_float(5.0)
17 | _ = decimal.Decimal.from_float(4.2)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
18 | _ = Decimal.from_float(float("inf"))
19 | _ = Decimal.from_float(float("-inf"))
|
= help: Replace with `Decimal` constructor
Safe fix
14 14 | _ = Decimal.from_float(0.1)
15 15 | _ = Decimal.from_float(-0.5)
16 16 | _ = Decimal.from_float(5.0)
17 |-_ = decimal.Decimal.from_float(4.2)
17 |+_ = decimal.Decimal(4.2)
18 18 | _ = Decimal.from_float(float("inf"))
19 19 | _ = Decimal.from_float(float("-inf"))
20 20 | _ = Decimal.from_float(float("Infinity"))
FURB164.py:18:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
16 | _ = Decimal.from_float(5.0)
17 | _ = decimal.Decimal.from_float(4.2)
18 | _ = Decimal.from_float(float("inf"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
19 | _ = Decimal.from_float(float("-inf"))
20 | _ = Decimal.from_float(float("Infinity"))
|
= help: Replace with `Decimal` constructor
Safe fix
15 15 | _ = Decimal.from_float(-0.5)
16 16 | _ = Decimal.from_float(5.0)
17 17 | _ = decimal.Decimal.from_float(4.2)
18 |-_ = Decimal.from_float(float("inf"))
18 |+_ = Decimal("inf")
19 19 | _ = Decimal.from_float(float("-inf"))
20 20 | _ = Decimal.from_float(float("Infinity"))
21 21 | _ = Decimal.from_float(float("-Infinity"))
FURB164.py:19:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
17 | _ = decimal.Decimal.from_float(4.2)
18 | _ = Decimal.from_float(float("inf"))
19 | _ = Decimal.from_float(float("-inf"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
20 | _ = Decimal.from_float(float("Infinity"))
21 | _ = Decimal.from_float(float("-Infinity"))
|
= help: Replace with `Decimal` constructor
Safe fix
16 16 | _ = Decimal.from_float(5.0)
17 17 | _ = decimal.Decimal.from_float(4.2)
18 18 | _ = Decimal.from_float(float("inf"))
19 |-_ = Decimal.from_float(float("-inf"))
19 |+_ = Decimal("-inf")
20 20 | _ = Decimal.from_float(float("Infinity"))
21 21 | _ = Decimal.from_float(float("-Infinity"))
22 22 | _ = Decimal.from_float(float("nan"))
FURB164.py:20:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
18 | _ = Decimal.from_float(float("inf"))
19 | _ = Decimal.from_float(float("-inf"))
20 | _ = Decimal.from_float(float("Infinity"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
21 | _ = Decimal.from_float(float("-Infinity"))
22 | _ = Decimal.from_float(float("nan"))
|
= help: Replace with `Decimal` constructor
Safe fix
17 17 | _ = decimal.Decimal.from_float(4.2)
18 18 | _ = Decimal.from_float(float("inf"))
19 19 | _ = Decimal.from_float(float("-inf"))
20 |-_ = Decimal.from_float(float("Infinity"))
20 |+_ = Decimal("Infinity")
21 21 | _ = Decimal.from_float(float("-Infinity"))
22 22 | _ = Decimal.from_float(float("nan"))
23 23 |
FURB164.py:21:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
19 | _ = Decimal.from_float(float("-inf"))
20 | _ = Decimal.from_float(float("Infinity"))
21 | _ = Decimal.from_float(float("-Infinity"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
22 | _ = Decimal.from_float(float("nan"))
|
= help: Replace with `Decimal` constructor
Safe fix
18 18 | _ = Decimal.from_float(float("inf"))
19 19 | _ = Decimal.from_float(float("-inf"))
20 20 | _ = Decimal.from_float(float("Infinity"))
21 |-_ = Decimal.from_float(float("-Infinity"))
21 |+_ = Decimal("-Infinity")
22 22 | _ = Decimal.from_float(float("nan"))
23 23 |
24 24 | # OK
FURB164.py:22:5: FURB164 [*] Verbose method `from_float` in `Decimal` construction
|
20 | _ = Decimal.from_float(float("Infinity"))
21 | _ = Decimal.from_float(float("-Infinity"))
22 | _ = Decimal.from_float(float("nan"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB164
23 |
24 | # OK
|
= help: Replace with `Decimal` constructor
Safe fix
19 19 | _ = Decimal.from_float(float("-inf"))
20 20 | _ = Decimal.from_float(float("Infinity"))
21 21 | _ = Decimal.from_float(float("-Infinity"))
22 |-_ = Decimal.from_float(float("nan"))
22 |+_ = Decimal("nan")
23 23 |
24 24 | # OK
25 25 | _ = Fraction(0.1)

1
ruff.schema.json generated
View file

@ -3062,6 +3062,7 @@
"FURB16", "FURB16",
"FURB161", "FURB161",
"FURB163", "FURB163",
"FURB164",
"FURB167", "FURB167",
"FURB168", "FURB168",
"FURB169", "FURB169",