mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:37 +00:00
[ruff
] Unnecessary rounding (RUF057
) (#14828)
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
f8c9665742
commit
89ea0371a4
9 changed files with 660 additions and 67 deletions
59
crates/ruff_linter/resources/test/fixtures/ruff/RUF057.py
vendored
Normal file
59
crates/ruff_linter/resources/test/fixtures/ruff/RUF057.py
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
inferred_int = 1
|
||||
inferred_float = 1.
|
||||
|
||||
|
||||
|
||||
round(42) # Error (safe)
|
||||
round(42, None) # Error (safe)
|
||||
round(42, 2) # Error (safe)
|
||||
round(42, inferred_int) # Error (safe)
|
||||
round(42, 3 + 4) # Error (safe)
|
||||
round(42, foo) # Error (unsafe)
|
||||
|
||||
|
||||
round(42.) # No error
|
||||
round(42., None) # No error
|
||||
round(42., 2) # No error
|
||||
round(42., inferred_int) # No error
|
||||
round(42., 3 + 4) # No error
|
||||
round(42., foo) # No error
|
||||
|
||||
|
||||
round(4 + 2) # Error (safe)
|
||||
round(4 + 2, None) # Error (safe)
|
||||
round(4 + 2, 2) # Error (safe)
|
||||
round(4 + 2, inferred_int) # Error (safe)
|
||||
round(4 + 2, 3 + 4) # Error (safe)
|
||||
round(4 + 2, foo) # Error (unsafe)
|
||||
|
||||
|
||||
round(4. + 2.) # No error
|
||||
round(4. + 2., None) # No error
|
||||
round(4. + 2., 2) # No error
|
||||
round(4. + 2., inferred_int) # No error
|
||||
round(4. + 2., 3 + 4) # No error
|
||||
round(4. + 2., foo) # No error
|
||||
|
||||
|
||||
round(inferred_int) # Error (unsafe)
|
||||
round(inferred_int, None) # Error (unsafe)
|
||||
round(inferred_int, 2) # Error (unsafe)
|
||||
round(inferred_int, inferred_int) # Error (unsafe)
|
||||
round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
round(inferred_int, foo) # No error
|
||||
|
||||
|
||||
round(inferred_float) # No error
|
||||
round(inferred_float, None) # No error
|
||||
round(inferred_float, 2) # No error
|
||||
round(inferred_float, inferred_int) # No error
|
||||
round(inferred_float, 3 + 4) # No error
|
||||
round(inferred_float, foo) # No error
|
||||
|
||||
|
||||
round(lorem) # No error
|
||||
round(lorem, None) # No error
|
||||
round(lorem, 2) # No error
|
||||
round(lorem, inferred_int) # No error
|
||||
round(lorem, 3 + 4) # No error
|
||||
round(lorem, foo) # No error
|
|
@ -1114,6 +1114,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
|||
if checker.enabled(Rule::FalsyDictGetFallback) {
|
||||
ruff::rules::falsy_dict_get_fallback(checker, expr);
|
||||
}
|
||||
if checker.enabled(Rule::UnnecessaryRound) {
|
||||
ruff::rules::unnecessary_round(checker, call);
|
||||
}
|
||||
}
|
||||
Expr::Dict(dict) => {
|
||||
if checker.any_enabled(&[
|
||||
|
|
|
@ -992,6 +992,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
(Ruff, "052") => (RuleGroup::Preview, rules::ruff::rules::UsedDummyVariable),
|
||||
(Ruff, "055") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryRegularExpression),
|
||||
(Ruff, "056") => (RuleGroup::Preview, rules::ruff::rules::FalsyDictGetFallback),
|
||||
(Ruff, "057") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryRound),
|
||||
(Ruff, "100") => (RuleGroup::Stable, rules::ruff::rules::UnusedNOQA),
|
||||
(Ruff, "101") => (RuleGroup::Stable, rules::ruff::rules::RedirectedNOQA),
|
||||
|
||||
|
|
|
@ -419,6 +419,7 @@ mod tests {
|
|||
#[test_case(Rule::UnnecessaryRegularExpression, Path::new("RUF055_1.py"))]
|
||||
#[test_case(Rule::UnnecessaryCastToInt, Path::new("RUF046.py"))]
|
||||
#[test_case(Rule::PytestRaisesAmbiguousPattern, Path::new("RUF043.py"))]
|
||||
#[test_case(Rule::UnnecessaryRound, Path::new("RUF057.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
|
|
|
@ -38,6 +38,7 @@ pub(crate) use unnecessary_iterable_allocation_for_first_element::*;
|
|||
pub(crate) use unnecessary_key_check::*;
|
||||
pub(crate) use unnecessary_nested_literal::*;
|
||||
pub(crate) use unnecessary_regular_expression::*;
|
||||
pub(crate) use unnecessary_round::*;
|
||||
pub(crate) use unraw_re_pattern::*;
|
||||
pub(crate) use unsafe_markup_use::*;
|
||||
pub(crate) use unused_async::*;
|
||||
|
@ -90,6 +91,7 @@ mod unnecessary_iterable_allocation_for_first_element;
|
|||
mod unnecessary_key_check;
|
||||
mod unnecessary_nested_literal;
|
||||
mod unnecessary_regular_expression;
|
||||
mod unnecessary_round;
|
||||
mod unraw_re_pattern;
|
||||
mod unsafe_markup_use;
|
||||
mod unused_async;
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use crate::checkers::ast::Checker;
|
||||
use crate::rules::ruff::rules::unnecessary_round::{
|
||||
rounded_and_ndigits, InferredType, NdigitsValue, RoundedValue,
|
||||
};
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast::{Arguments, Expr, ExprCall, ExprNumberLiteral, Number};
|
||||
use ruff_python_ast::{Arguments, Expr, ExprCall};
|
||||
use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType};
|
||||
use ruff_python_semantic::analyze::typing;
|
||||
use ruff_python_semantic::SemanticModel;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
|
@ -76,12 +78,13 @@ pub(crate) fn unnecessary_cast_to_int(checker: &mut Checker, call: &ExprCall) {
|
|||
|
||||
let fix = unwrap_int_expression(checker, call, argument, applicability);
|
||||
let diagnostic = Diagnostic::new(UnnecessaryCastToInt, call.range);
|
||||
|
||||
checker.diagnostics.push(diagnostic.with_fix(fix));
|
||||
}
|
||||
|
||||
/// Creates a fix that replaces `int(expression)` with `expression`.
|
||||
fn unwrap_int_expression(
|
||||
checker: &mut Checker,
|
||||
checker: &Checker,
|
||||
call: &ExprCall,
|
||||
argument: &Expr,
|
||||
applicability: Applicability,
|
||||
|
@ -148,78 +151,56 @@ fn single_argument_to_int_call<'a>(
|
|||
Some(argument)
|
||||
}
|
||||
|
||||
/// The type of the first argument to `round()`
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum Rounded {
|
||||
InferredInt,
|
||||
InferredFloat,
|
||||
LiteralInt,
|
||||
LiteralFloat,
|
||||
Other,
|
||||
}
|
||||
|
||||
/// The type of the second argument to `round()`
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum Ndigits {
|
||||
NotGiven,
|
||||
LiteralInt,
|
||||
LiteralNone,
|
||||
Other,
|
||||
}
|
||||
|
||||
/// Determines the [`Applicability`] for a `round(..)` call.
|
||||
///
|
||||
/// The Applicability depends on the `ndigits` and the number argument.
|
||||
fn round_applicability(checker: &Checker, arguments: &Arguments) -> Option<Applicability> {
|
||||
if arguments.len() > 2 {
|
||||
return None;
|
||||
}
|
||||
let (_rounded, rounded_value, ndigits_value) = rounded_and_ndigits(checker, arguments)?;
|
||||
|
||||
let number = arguments.find_argument_value("number", 0)?;
|
||||
let ndigits = arguments.find_argument_value("ndigits", 1);
|
||||
match (rounded_value, ndigits_value) {
|
||||
// ```python
|
||||
// int(round(2, 0))
|
||||
// int(round(2))
|
||||
// int(round(2, None))
|
||||
// ```
|
||||
(
|
||||
RoundedValue::Int(InferredType::Equivalent),
|
||||
NdigitsValue::Int(InferredType::Equivalent)
|
||||
| NdigitsValue::NotGiven
|
||||
| NdigitsValue::LiteralNone,
|
||||
) => Some(Applicability::Safe),
|
||||
|
||||
let number_kind = match number {
|
||||
Expr::Name(name) => {
|
||||
let semantic = checker.semantic();
|
||||
// ```python
|
||||
// int(round(2.0))
|
||||
// int(round(2.0, None))
|
||||
// ```
|
||||
(
|
||||
RoundedValue::Float(InferredType::Equivalent),
|
||||
NdigitsValue::NotGiven | NdigitsValue::LiteralNone,
|
||||
) => Some(Applicability::Safe),
|
||||
|
||||
match semantic.only_binding(name).map(|id| semantic.binding(id)) {
|
||||
Some(binding) if typing::is_int(binding, semantic) => Rounded::InferredInt,
|
||||
Some(binding) if typing::is_float(binding, semantic) => Rounded::InferredFloat,
|
||||
_ => Rounded::Other,
|
||||
}
|
||||
}
|
||||
// ```python
|
||||
// a: int = 2 # or True
|
||||
// int(round(a, 1))
|
||||
// int(round(a))
|
||||
// int(round(a, None))
|
||||
// ```
|
||||
(
|
||||
RoundedValue::Int(InferredType::AssignableTo),
|
||||
NdigitsValue::Int(InferredType::Equivalent)
|
||||
| NdigitsValue::NotGiven
|
||||
| NdigitsValue::LiteralNone,
|
||||
) => Some(Applicability::Unsafe),
|
||||
|
||||
Expr::NumberLiteral(ExprNumberLiteral { value, .. }) => match value {
|
||||
Number::Int(..) => Rounded::LiteralInt,
|
||||
Number::Float(..) => Rounded::LiteralFloat,
|
||||
Number::Complex { .. } => Rounded::Other,
|
||||
},
|
||||
|
||||
_ => Rounded::Other,
|
||||
};
|
||||
|
||||
let ndigits_kind = match ndigits {
|
||||
None => Ndigits::NotGiven,
|
||||
Some(Expr::NoneLiteral(_)) => Ndigits::LiteralNone,
|
||||
|
||||
Some(Expr::NumberLiteral(ExprNumberLiteral {
|
||||
value: Number::Int(..),
|
||||
..
|
||||
})) => Ndigits::LiteralInt,
|
||||
|
||||
_ => Ndigits::Other,
|
||||
};
|
||||
|
||||
match (number_kind, ndigits_kind) {
|
||||
(Rounded::LiteralInt, Ndigits::LiteralInt)
|
||||
| (Rounded::LiteralInt | Rounded::LiteralFloat, Ndigits::NotGiven | Ndigits::LiteralNone) => {
|
||||
Some(Applicability::Safe)
|
||||
}
|
||||
|
||||
(Rounded::InferredInt, Ndigits::LiteralInt)
|
||||
| (
|
||||
Rounded::InferredInt | Rounded::InferredFloat | Rounded::Other,
|
||||
Ndigits::NotGiven | Ndigits::LiteralNone,
|
||||
// ```python
|
||||
// int(round(2.0))
|
||||
// int(round(2.0, None))
|
||||
// int(round(x))
|
||||
// int(round(x, None))
|
||||
// ```
|
||||
(
|
||||
RoundedValue::Float(InferredType::AssignableTo) | RoundedValue::Other,
|
||||
NdigitsValue::NotGiven | NdigitsValue::LiteralNone,
|
||||
) => Some(Applicability::Unsafe),
|
||||
|
||||
_ => None,
|
||||
|
|
201
crates/ruff_linter/src/rules/ruff/rules/unnecessary_round.rs
Normal file
201
crates/ruff_linter/src/rules/ruff/rules/unnecessary_round.rs
Normal file
|
@ -0,0 +1,201 @@
|
|||
use crate::checkers::ast::Checker;
|
||||
use ruff_diagnostics::{AlwaysFixableViolation, Applicability, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, ViolationMetadata};
|
||||
use ruff_python_ast::{Arguments, Expr, ExprCall};
|
||||
use ruff_python_semantic::analyze::type_inference::{NumberLike, PythonType, ResolvedPythonType};
|
||||
use ruff_python_semantic::analyze::typing;
|
||||
use ruff_text_size::Ranged;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for `round()` calls that have no effect on the input.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Rounding a value that's already an integer is unnecessary.
|
||||
/// It's clearer to use the value directly.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```python
|
||||
/// a = round(1, 0)
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
///
|
||||
/// ```python
|
||||
/// a = 1
|
||||
/// ```
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct UnnecessaryRound;
|
||||
|
||||
impl AlwaysFixableViolation for UnnecessaryRound {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"Value being rounded is already an integer".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> String {
|
||||
"Remove unnecessary `round` call".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// RUF057
|
||||
pub(crate) fn unnecessary_round(checker: &mut Checker, call: &ExprCall) {
|
||||
let arguments = &call.arguments;
|
||||
|
||||
if !checker.semantic().match_builtin_expr(&call.func, "round") {
|
||||
return;
|
||||
}
|
||||
|
||||
let Some((rounded, rounded_value, ndigits_value)) = rounded_and_ndigits(checker, arguments)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let applicability = match (rounded_value, ndigits_value) {
|
||||
// ```python
|
||||
// rounded(1, unknown)
|
||||
// ```
|
||||
(RoundedValue::Int(InferredType::Equivalent), NdigitsValue::Other) => Applicability::Unsafe,
|
||||
|
||||
(_, NdigitsValue::Other) => return,
|
||||
|
||||
// ```python
|
||||
// some_int: int
|
||||
//
|
||||
// rounded(1)
|
||||
// rounded(1, None)
|
||||
// rounded(1, 42)
|
||||
// rounded(1, 4 + 2)
|
||||
// rounded(1, some_int)
|
||||
// ```
|
||||
(RoundedValue::Int(InferredType::Equivalent), _) => Applicability::Safe,
|
||||
|
||||
// ```python
|
||||
// some_int: int
|
||||
// some_other_int: int
|
||||
//
|
||||
// rounded(some_int)
|
||||
// rounded(some_int, None)
|
||||
// rounded(some_int, 42)
|
||||
// rounded(some_int, 4 + 2)
|
||||
// rounded(some_int, some_other_int)
|
||||
// ```
|
||||
(RoundedValue::Int(InferredType::AssignableTo), _) => Applicability::Unsafe,
|
||||
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let edit = unwrap_round_call(checker, call, rounded);
|
||||
let fix = Fix::applicable_edit(edit, applicability);
|
||||
|
||||
let diagnostic = Diagnostic::new(UnnecessaryRound, call.range);
|
||||
|
||||
checker.diagnostics.push(diagnostic.with_fix(fix));
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(super) enum InferredType {
|
||||
/// The value is an exact instance of the type in question.
|
||||
Equivalent,
|
||||
/// The value is an instance of the type in question or a subtype thereof.
|
||||
AssignableTo,
|
||||
}
|
||||
|
||||
/// The type of the first argument to `round()`
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(super) enum RoundedValue {
|
||||
Int(InferredType),
|
||||
Float(InferredType),
|
||||
Other,
|
||||
}
|
||||
|
||||
/// The type of the second argument to `round()`
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub(super) enum NdigitsValue {
|
||||
NotGiven,
|
||||
LiteralNone,
|
||||
Int(InferredType),
|
||||
Other,
|
||||
}
|
||||
|
||||
/// Extracts the rounded and `ndigits` values from `arguments`.
|
||||
///
|
||||
/// Returns a tripled where the first element is the rounded value's expression, the second is the rounded value,
|
||||
///and the third is the `ndigits` value.
|
||||
pub(super) fn rounded_and_ndigits<'a>(
|
||||
checker: &Checker,
|
||||
arguments: &'a Arguments,
|
||||
) -> Option<(&'a Expr, RoundedValue, NdigitsValue)> {
|
||||
if arguments.len() > 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let rounded = arguments.find_argument_value("number", 0)?;
|
||||
let ndigits = arguments.find_argument_value("ndigits", 1);
|
||||
|
||||
let rounded_kind = match rounded {
|
||||
Expr::Name(name) => {
|
||||
let semantic = checker.semantic();
|
||||
|
||||
match semantic.only_binding(name).map(|id| semantic.binding(id)) {
|
||||
Some(binding) if typing::is_int(binding, semantic) => {
|
||||
RoundedValue::Int(InferredType::AssignableTo)
|
||||
}
|
||||
Some(binding) if typing::is_float(binding, semantic) => {
|
||||
RoundedValue::Float(InferredType::AssignableTo)
|
||||
}
|
||||
_ => RoundedValue::Other,
|
||||
}
|
||||
}
|
||||
|
||||
_ => match ResolvedPythonType::from(rounded) {
|
||||
ResolvedPythonType::Atom(PythonType::Number(NumberLike::Integer)) => {
|
||||
RoundedValue::Int(InferredType::Equivalent)
|
||||
}
|
||||
ResolvedPythonType::Atom(PythonType::Number(NumberLike::Float)) => {
|
||||
RoundedValue::Float(InferredType::Equivalent)
|
||||
}
|
||||
_ => RoundedValue::Other,
|
||||
},
|
||||
};
|
||||
|
||||
let ndigits_kind = match ndigits {
|
||||
None => NdigitsValue::NotGiven,
|
||||
Some(Expr::NoneLiteral(_)) => NdigitsValue::LiteralNone,
|
||||
|
||||
Some(Expr::Name(name)) => {
|
||||
let semantic = checker.semantic();
|
||||
|
||||
match semantic.only_binding(name).map(|id| semantic.binding(id)) {
|
||||
Some(binding) if typing::is_int(binding, semantic) => {
|
||||
NdigitsValue::Int(InferredType::AssignableTo)
|
||||
}
|
||||
_ => NdigitsValue::Other,
|
||||
}
|
||||
}
|
||||
|
||||
Some(ndigits) => match ResolvedPythonType::from(ndigits) {
|
||||
ResolvedPythonType::Atom(PythonType::Number(NumberLike::Integer)) => {
|
||||
NdigitsValue::Int(InferredType::Equivalent)
|
||||
}
|
||||
_ => NdigitsValue::Other,
|
||||
},
|
||||
};
|
||||
|
||||
Some((rounded, rounded_kind, ndigits_kind))
|
||||
}
|
||||
|
||||
fn unwrap_round_call(checker: &Checker, call: &ExprCall, rounded: &Expr) -> Edit {
|
||||
let (locator, semantic) = (checker.locator(), checker.semantic());
|
||||
|
||||
let rounded_expr = locator.slice(rounded.range());
|
||||
|
||||
let has_parent_expr = semantic.current_expression_parent().is_some();
|
||||
let new_content = if has_parent_expr || rounded.is_named_expr() {
|
||||
format!("({rounded_expr})")
|
||||
} else {
|
||||
rounded_expr.to_string()
|
||||
};
|
||||
|
||||
Edit::range_replacement(new_content, call.range)
|
||||
}
|
|
@ -0,0 +1,344 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
RUF057.py:6:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
6 | round(42) # Error (safe)
|
||||
| ^^^^^^^^^ RUF057
|
||||
7 | round(42, None) # Error (safe)
|
||||
8 | round(42, 2) # Error (safe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
3 3 |
|
||||
4 4 |
|
||||
5 5 |
|
||||
6 |-round(42) # Error (safe)
|
||||
6 |+42 # Error (safe)
|
||||
7 7 | round(42, None) # Error (safe)
|
||||
8 8 | round(42, 2) # Error (safe)
|
||||
9 9 | round(42, inferred_int) # Error (safe)
|
||||
|
||||
RUF057.py:7:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
6 | round(42) # Error (safe)
|
||||
7 | round(42, None) # Error (safe)
|
||||
| ^^^^^^^^^^^^^^^ RUF057
|
||||
8 | round(42, 2) # Error (safe)
|
||||
9 | round(42, inferred_int) # Error (safe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 |
|
||||
5 5 |
|
||||
6 6 | round(42) # Error (safe)
|
||||
7 |-round(42, None) # Error (safe)
|
||||
7 |+42 # Error (safe)
|
||||
8 8 | round(42, 2) # Error (safe)
|
||||
9 9 | round(42, inferred_int) # Error (safe)
|
||||
10 10 | round(42, 3 + 4) # Error (safe)
|
||||
|
||||
RUF057.py:8:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
6 | round(42) # Error (safe)
|
||||
7 | round(42, None) # Error (safe)
|
||||
8 | round(42, 2) # Error (safe)
|
||||
| ^^^^^^^^^^^^ RUF057
|
||||
9 | round(42, inferred_int) # Error (safe)
|
||||
10 | round(42, 3 + 4) # Error (safe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
5 5 |
|
||||
6 6 | round(42) # Error (safe)
|
||||
7 7 | round(42, None) # Error (safe)
|
||||
8 |-round(42, 2) # Error (safe)
|
||||
8 |+42 # Error (safe)
|
||||
9 9 | round(42, inferred_int) # Error (safe)
|
||||
10 10 | round(42, 3 + 4) # Error (safe)
|
||||
11 11 | round(42, foo) # Error (unsafe)
|
||||
|
||||
RUF057.py:9:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
7 | round(42, None) # Error (safe)
|
||||
8 | round(42, 2) # Error (safe)
|
||||
9 | round(42, inferred_int) # Error (safe)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
10 | round(42, 3 + 4) # Error (safe)
|
||||
11 | round(42, foo) # Error (unsafe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
6 6 | round(42) # Error (safe)
|
||||
7 7 | round(42, None) # Error (safe)
|
||||
8 8 | round(42, 2) # Error (safe)
|
||||
9 |-round(42, inferred_int) # Error (safe)
|
||||
9 |+42 # Error (safe)
|
||||
10 10 | round(42, 3 + 4) # Error (safe)
|
||||
11 11 | round(42, foo) # Error (unsafe)
|
||||
12 12 |
|
||||
|
||||
RUF057.py:10:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
8 | round(42, 2) # Error (safe)
|
||||
9 | round(42, inferred_int) # Error (safe)
|
||||
10 | round(42, 3 + 4) # Error (safe)
|
||||
| ^^^^^^^^^^^^^^^^ RUF057
|
||||
11 | round(42, foo) # Error (unsafe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
7 7 | round(42, None) # Error (safe)
|
||||
8 8 | round(42, 2) # Error (safe)
|
||||
9 9 | round(42, inferred_int) # Error (safe)
|
||||
10 |-round(42, 3 + 4) # Error (safe)
|
||||
10 |+42 # Error (safe)
|
||||
11 11 | round(42, foo) # Error (unsafe)
|
||||
12 12 |
|
||||
13 13 |
|
||||
|
||||
RUF057.py:11:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
9 | round(42, inferred_int) # Error (safe)
|
||||
10 | round(42, 3 + 4) # Error (safe)
|
||||
11 | round(42, foo) # Error (unsafe)
|
||||
| ^^^^^^^^^^^^^^ RUF057
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Unsafe fix
|
||||
8 8 | round(42, 2) # Error (safe)
|
||||
9 9 | round(42, inferred_int) # Error (safe)
|
||||
10 10 | round(42, 3 + 4) # Error (safe)
|
||||
11 |-round(42, foo) # Error (unsafe)
|
||||
11 |+42 # Error (unsafe)
|
||||
12 12 |
|
||||
13 13 |
|
||||
14 14 | round(42.) # No error
|
||||
|
||||
RUF057.py:22:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
22 | round(4 + 2) # Error (safe)
|
||||
| ^^^^^^^^^^^^ RUF057
|
||||
23 | round(4 + 2, None) # Error (safe)
|
||||
24 | round(4 + 2, 2) # Error (safe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
19 19 | round(42., foo) # No error
|
||||
20 20 |
|
||||
21 21 |
|
||||
22 |-round(4 + 2) # Error (safe)
|
||||
22 |+4 + 2 # Error (safe)
|
||||
23 23 | round(4 + 2, None) # Error (safe)
|
||||
24 24 | round(4 + 2, 2) # Error (safe)
|
||||
25 25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
|
||||
RUF057.py:23:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
22 | round(4 + 2) # Error (safe)
|
||||
23 | round(4 + 2, None) # Error (safe)
|
||||
| ^^^^^^^^^^^^^^^^^^ RUF057
|
||||
24 | round(4 + 2, 2) # Error (safe)
|
||||
25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
20 20 |
|
||||
21 21 |
|
||||
22 22 | round(4 + 2) # Error (safe)
|
||||
23 |-round(4 + 2, None) # Error (safe)
|
||||
23 |+4 + 2 # Error (safe)
|
||||
24 24 | round(4 + 2, 2) # Error (safe)
|
||||
25 25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
26 26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
|
||||
RUF057.py:24:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
22 | round(4 + 2) # Error (safe)
|
||||
23 | round(4 + 2, None) # Error (safe)
|
||||
24 | round(4 + 2, 2) # Error (safe)
|
||||
| ^^^^^^^^^^^^^^^ RUF057
|
||||
25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
21 21 |
|
||||
22 22 | round(4 + 2) # Error (safe)
|
||||
23 23 | round(4 + 2, None) # Error (safe)
|
||||
24 |-round(4 + 2, 2) # Error (safe)
|
||||
24 |+4 + 2 # Error (safe)
|
||||
25 25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
26 26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
27 27 | round(4 + 2, foo) # Error (unsafe)
|
||||
|
||||
RUF057.py:25:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
23 | round(4 + 2, None) # Error (safe)
|
||||
24 | round(4 + 2, 2) # Error (safe)
|
||||
25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
27 | round(4 + 2, foo) # Error (unsafe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
22 22 | round(4 + 2) # Error (safe)
|
||||
23 23 | round(4 + 2, None) # Error (safe)
|
||||
24 24 | round(4 + 2, 2) # Error (safe)
|
||||
25 |-round(4 + 2, inferred_int) # Error (safe)
|
||||
25 |+4 + 2 # Error (safe)
|
||||
26 26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
27 27 | round(4 + 2, foo) # Error (unsafe)
|
||||
28 28 |
|
||||
|
||||
RUF057.py:26:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
24 | round(4 + 2, 2) # Error (safe)
|
||||
25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
| ^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
27 | round(4 + 2, foo) # Error (unsafe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Safe fix
|
||||
23 23 | round(4 + 2, None) # Error (safe)
|
||||
24 24 | round(4 + 2, 2) # Error (safe)
|
||||
25 25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
26 |-round(4 + 2, 3 + 4) # Error (safe)
|
||||
26 |+4 + 2 # Error (safe)
|
||||
27 27 | round(4 + 2, foo) # Error (unsafe)
|
||||
28 28 |
|
||||
29 29 |
|
||||
|
||||
RUF057.py:27:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
27 | round(4 + 2, foo) # Error (unsafe)
|
||||
| ^^^^^^^^^^^^^^^^^ RUF057
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Unsafe fix
|
||||
24 24 | round(4 + 2, 2) # Error (safe)
|
||||
25 25 | round(4 + 2, inferred_int) # Error (safe)
|
||||
26 26 | round(4 + 2, 3 + 4) # Error (safe)
|
||||
27 |-round(4 + 2, foo) # Error (unsafe)
|
||||
27 |+4 + 2 # Error (unsafe)
|
||||
28 28 |
|
||||
29 29 |
|
||||
30 30 | round(4. + 2.) # No error
|
||||
|
||||
RUF057.py:38:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
38 | round(inferred_int) # Error (unsafe)
|
||||
| ^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
39 | round(inferred_int, None) # Error (unsafe)
|
||||
40 | round(inferred_int, 2) # Error (unsafe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Unsafe fix
|
||||
35 35 | round(4. + 2., foo) # No error
|
||||
36 36 |
|
||||
37 37 |
|
||||
38 |-round(inferred_int) # Error (unsafe)
|
||||
38 |+inferred_int # Error (unsafe)
|
||||
39 39 | round(inferred_int, None) # Error (unsafe)
|
||||
40 40 | round(inferred_int, 2) # Error (unsafe)
|
||||
41 41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
|
||||
RUF057.py:39:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
38 | round(inferred_int) # Error (unsafe)
|
||||
39 | round(inferred_int, None) # Error (unsafe)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
40 | round(inferred_int, 2) # Error (unsafe)
|
||||
41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Unsafe fix
|
||||
36 36 |
|
||||
37 37 |
|
||||
38 38 | round(inferred_int) # Error (unsafe)
|
||||
39 |-round(inferred_int, None) # Error (unsafe)
|
||||
39 |+inferred_int # Error (unsafe)
|
||||
40 40 | round(inferred_int, 2) # Error (unsafe)
|
||||
41 41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
42 42 | round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
|
||||
RUF057.py:40:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
38 | round(inferred_int) # Error (unsafe)
|
||||
39 | round(inferred_int, None) # Error (unsafe)
|
||||
40 | round(inferred_int, 2) # Error (unsafe)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
42 | round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Unsafe fix
|
||||
37 37 |
|
||||
38 38 | round(inferred_int) # Error (unsafe)
|
||||
39 39 | round(inferred_int, None) # Error (unsafe)
|
||||
40 |-round(inferred_int, 2) # Error (unsafe)
|
||||
40 |+inferred_int # Error (unsafe)
|
||||
41 41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
42 42 | round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
43 43 | round(inferred_int, foo) # No error
|
||||
|
||||
RUF057.py:41:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
39 | round(inferred_int, None) # Error (unsafe)
|
||||
40 | round(inferred_int, 2) # Error (unsafe)
|
||||
41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
42 | round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
43 | round(inferred_int, foo) # No error
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Unsafe fix
|
||||
38 38 | round(inferred_int) # Error (unsafe)
|
||||
39 39 | round(inferred_int, None) # Error (unsafe)
|
||||
40 40 | round(inferred_int, 2) # Error (unsafe)
|
||||
41 |-round(inferred_int, inferred_int) # Error (unsafe)
|
||||
41 |+inferred_int # Error (unsafe)
|
||||
42 42 | round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
43 43 | round(inferred_int, foo) # No error
|
||||
44 44 |
|
||||
|
||||
RUF057.py:42:1: RUF057 [*] Value being rounded is already an integer
|
||||
|
|
||||
40 | round(inferred_int, 2) # Error (unsafe)
|
||||
41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
42 | round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF057
|
||||
43 | round(inferred_int, foo) # No error
|
||||
|
|
||||
= help: Remove unnecessary `round` call
|
||||
|
||||
ℹ Unsafe fix
|
||||
39 39 | round(inferred_int, None) # Error (unsafe)
|
||||
40 40 | round(inferred_int, 2) # Error (unsafe)
|
||||
41 41 | round(inferred_int, inferred_int) # Error (unsafe)
|
||||
42 |-round(inferred_int, 3 + 4) # Error (unsafe)
|
||||
42 |+inferred_int # Error (unsafe)
|
||||
43 43 | round(inferred_int, foo) # No error
|
||||
44 44 |
|
||||
45 45 |
|
1
ruff.schema.json
generated
1
ruff.schema.json
generated
|
@ -3873,6 +3873,7 @@
|
|||
"RUF052",
|
||||
"RUF055",
|
||||
"RUF056",
|
||||
"RUF057",
|
||||
"RUF1",
|
||||
"RUF10",
|
||||
"RUF100",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue