From bd023c4500e6b0781c6ba0d570518c365ebdc78d Mon Sep 17 00:00:00 2001 From: InSync Date: Sat, 21 Dec 2024 21:23:26 +0700 Subject: [PATCH] [`ruff`] Detect more strict-integer expressions (`RUF046`) (#14833) Co-authored-by: Micha Reiser --- .../resources/test/fixtures/ruff/RUF046.py | 86 +++ .../ruff_linter/src/rules/ruff/rules/mod.rs | 4 +- ..._cast_to_int.rs => round_applicability.rs} | 107 +-- ...uff__tests__preview__RUF046_RUF046.py.snap | 725 ++++++++++++++---- 4 files changed, 719 insertions(+), 203 deletions(-) rename crates/ruff_linter/src/rules/ruff/rules/{unnecessary_cast_to_int.rs => round_applicability.rs} (67%) diff --git a/crates/ruff_linter/resources/test/fixtures/ruff/RUF046.py b/crates/ruff_linter/resources/test/fixtures/ruff/RUF046.py index 932782e0d3194..e857c0a67fa3c 100644 --- a/crates/ruff_linter/resources/test/fixtures/ruff/RUF046.py +++ b/crates/ruff_linter/resources/test/fixtures/ruff/RUF046.py @@ -29,6 +29,33 @@ int(round(1.)) int(round(1., None)) +int(1) +int(v := 1) +int(~1) +int(-1) +int(+1) + +int(1 + 1) +int(1 - 1) +int(1 * 1) +int(1 % 1) +int(1 ** 1) +int(1 << 1) +int(1 >> 1) +int(1 | 1) +int(1 ^ 1) +int(1 & 1) +int(1 // 1) + +int(1 if ... else 2) + +int(1 and 0) +int(0 or -1) + + +if int(1 + 2) * 3: + ... + ### Unsafe @@ -68,3 +95,62 @@ int(round(0, 0), base) int(round(0, 0, extra=keyword)) + +int(foo if ... else 4) + +int(3.14) +int(2.8j) + +async def f(): + int(await f()) + +int(foo.bar) +int(bar([1][False])) + +int(1 == 1) +int(1 != 1) +int(1 < 1) +int(1 <= 1) +int(1 > 1) +int(1 >= 1) +int(1 in 1) +int(1 not in 1) +int(1 is 1) +int(2 is not 3) +int(foo in 1) +int(foo not in 1) +int(foo is 1) +int(foo is not 1) + +int(1 == 2 == 3) +int(foo == 1) +int(foo != 1) +int(foo < 1) +int(foo <= 1) +int(foo > 1) +int(foo >= 1) + +int(v := {}[{}['']]) + +int(foo + 1) +int(foo - 1) +int(foo * 1) +int(foo @ 1) +int(foo / 1) +int(foo % 1) +int(foo ** 1) +int(foo << 1) +int(foo >> 1) +int(foo | 1) +int(foo ^ 1) +int(foo & 1) +int(foo // 1) + +int(v := 3.7) + +int(not 109) + +int(1 / 1) +int(1 @ 1) + +int(1. if ... else .2) diff --git a/crates/ruff_linter/src/rules/ruff/rules/mod.rs b/crates/ruff_linter/src/rules/ruff/rules/mod.rs index e9e74d1a534af..1c4e58f36354e 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/mod.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/mod.rs @@ -27,12 +27,12 @@ pub(crate) use pytest_raises_ambiguous_pattern::*; pub(crate) use quadratic_list_summation::*; pub(crate) use redirected_noqa::*; pub(crate) use redundant_bool_literal::*; +pub(crate) use round_applicability::*; pub(crate) use sort_dunder_all::*; pub(crate) use sort_dunder_slots::*; pub(crate) use static_key_dict_comprehension::*; #[cfg(any(feature = "test-rules", test))] pub(crate) use test_rules::*; -pub(crate) use unnecessary_cast_to_int::*; pub(crate) use unnecessary_iterable_allocation_for_first_element::*; pub(crate) use unnecessary_key_check::*; pub(crate) use unnecessary_nested_literal::*; @@ -76,6 +76,7 @@ mod pytest_raises_ambiguous_pattern; mod quadratic_list_summation; mod redirected_noqa; mod redundant_bool_literal; +mod round_applicability; mod sequence_sorting; mod sort_dunder_all; mod sort_dunder_slots; @@ -83,7 +84,6 @@ mod static_key_dict_comprehension; mod suppression_comment_visitor; #[cfg(any(feature = "test-rules", test))] pub(crate) mod test_rules; -mod unnecessary_cast_to_int; mod unnecessary_iterable_allocation_for_first_element; mod unnecessary_key_check; mod unnecessary_nested_literal; diff --git a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_cast_to_int.rs b/crates/ruff_linter/src/rules/ruff/rules/round_applicability.rs similarity index 67% rename from crates/ruff_linter/src/rules/ruff/rules/unnecessary_cast_to_int.rs rename to crates/ruff_linter/src/rules/ruff/rules/round_applicability.rs index b533c7ea45dcd..5dc71aba1a47b 100644 --- a/crates/ruff_linter/src/rules/ruff/rules/unnecessary_cast_to_int.rs +++ b/crates/ruff_linter/src/rules/ruff/rules/round_applicability.rs @@ -2,9 +2,10 @@ 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, ExprNumberLiteral, Number}; +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::TextRange; +use ruff_text_size::Ranged; /// ## What it does /// Checks for `int` conversions of values that are already integers. @@ -54,44 +55,74 @@ impl AlwaysFixableViolation for UnnecessaryCastToInt { pub(crate) fn unnecessary_cast_to_int(checker: &mut Checker, call: &ExprCall) { let semantic = checker.semantic(); - let Some(Expr::Call(inner_call)) = single_argument_to_int_call(semantic, call) else { + let Some(argument) = single_argument_to_int_call(semantic, call) else { return; }; - let (func, arguments) = (&inner_call.func, &inner_call.arguments); - let (outer_range, inner_range) = (call.range, inner_call.range); + let applicability = if matches!( + ResolvedPythonType::from(argument), + ResolvedPythonType::Atom(PythonType::Number(NumberLike::Integer)) + ) { + Some(Applicability::Safe) + } else if let Expr::Call(inner_call) = argument { + call_applicability(checker, inner_call) + } else { + None + }; - let Some(qualified_name) = checker.semantic().resolve_qualified_name(func) else { + let Some(applicability) = applicability else { return; }; - let fix = match qualified_name.segments() { + 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, + call: &ExprCall, + argument: &Expr, + applicability: Applicability, +) -> Fix { + let (locator, semantic) = (checker.locator(), checker.semantic()); + + let argument_expr = locator.slice(argument.range()); + + let has_parent_expr = semantic.current_expression_parent().is_some(); + let new_content = if has_parent_expr || argument.is_named_expr() { + format!("({argument_expr})") + } else { + argument_expr.to_string() + }; + + let edit = Edit::range_replacement(new_content, call.range); + Fix::applicable_edit(edit, applicability) +} + +/// Returns `Some` if `call` in `int(call(..))` is a method that returns an `int` and `None` +/// otherwise. +fn call_applicability(checker: &mut Checker, inner_call: &ExprCall) -> Option { + let (func, arguments) = (&inner_call.func, &inner_call.arguments); + + let qualified_name = checker.semantic().resolve_qualified_name(func)?; + + match qualified_name.segments() { // Always returns a strict instance of `int` ["" | "builtins", "len" | "id" | "hash" | "ord" | "int"] | ["math", "comb" | "factorial" | "gcd" | "lcm" | "isqrt" | "perm"] => { - Fix::safe_edit(replace_with_inner(checker, outer_range, inner_range)) + Some(Applicability::Safe) } // Depends on `ndigits` and `number.__round__` - ["" | "builtins", "round"] => { - if let Some(fix) = replace_with_round(checker, outer_range, inner_range, arguments) { - fix - } else { - return; - } - } + ["" | "builtins", "round"] => replace_with_round(checker, arguments), // Depends on `__ceil__`/`__floor__`/`__trunc__` - ["math", "ceil" | "floor" | "trunc"] => { - Fix::unsafe_edit(replace_with_inner(checker, outer_range, inner_range)) - } - - _ => return, - }; - - let diagnostic = Diagnostic::new(UnnecessaryCastToInt, call.range); + ["math", "ceil" | "floor" | "trunc"] => Some(Applicability::Unsafe), - checker.diagnostics.push(diagnostic.with_fix(fix)); + _ => None, + } } fn single_argument_to_int_call<'a>( @@ -136,12 +167,10 @@ enum Ndigits { Other, } -fn replace_with_round( - checker: &Checker, - outer_range: TextRange, - inner_range: TextRange, - arguments: &Arguments, -) -> Option { +/// Determines the [`Applicability`] for a `round(..)` call. +/// +/// The Applicability depends on the `ndigits` and the number argument. +fn replace_with_round(checker: &Checker, arguments: &Arguments) -> Option { if arguments.len() > 2 { return None; } @@ -181,28 +210,18 @@ fn replace_with_round( _ => Ndigits::Other, }; - let applicability = match (number_kind, ndigits_kind) { + match (number_kind, ndigits_kind) { (Rounded::LiteralInt, Ndigits::LiteralInt) | (Rounded::LiteralInt | Rounded::LiteralFloat, Ndigits::NotGiven | Ndigits::LiteralNone) => { - Applicability::Safe + Some(Applicability::Safe) } (Rounded::InferredInt, Ndigits::LiteralInt) | ( Rounded::InferredInt | Rounded::InferredFloat | Rounded::Other, Ndigits::NotGiven | Ndigits::LiteralNone, - ) => Applicability::Unsafe, + ) => Some(Applicability::Unsafe), - _ => return None, - }; - - let edit = replace_with_inner(checker, outer_range, inner_range); - - Some(Fix::applicable_edit(edit, applicability)) -} - -fn replace_with_inner(checker: &Checker, outer_range: TextRange, inner_range: TextRange) -> Edit { - let inner_expr = checker.locator().slice(inner_range); - - Edit::range_replacement(inner_expr.to_string(), outer_range) + _ => None, + } } diff --git a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__preview__RUF046_RUF046.py.snap b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__preview__RUF046_RUF046.py.snap index 867ba99180dc2..015d78d21bcf8 100644 --- a/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__preview__RUF046_RUF046.py.snap +++ b/crates/ruff_linter/src/rules/ruff/snapshots/ruff_linter__rules__ruff__tests__preview__RUF046_RUF046.py.snap @@ -327,13 +327,15 @@ RUF046.py:29:1: RUF046 [*] Value being casted is already an integer 29 |+round(1.) 30 30 | int(round(1., None)) 31 31 | -32 32 | +32 32 | int(1) RUF046.py:30:1: RUF046 [*] Value being casted is already an integer | 29 | int(round(1.)) 30 | int(round(1., None)) | ^^^^^^^^^^^^^^^^^^^^ RUF046 +31 | +32 | int(1) | = help: Remove unnecessary conversion to `int` @@ -344,224 +346,633 @@ RUF046.py:30:1: RUF046 [*] Value being casted is already an integer 30 |-int(round(1., None)) 30 |+round(1., None) 31 31 | -32 32 | -33 33 | ### Unsafe +32 32 | int(1) +33 33 | int(v := 1) + +RUF046.py:32:1: RUF046 [*] Value being casted is already an integer + | +30 | int(round(1., None)) +31 | +32 | int(1) + | ^^^^^^ RUF046 +33 | int(v := 1) +34 | int(~1) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +29 29 | int(round(1.)) +30 30 | int(round(1., None)) +31 31 | +32 |-int(1) + 32 |+1 +33 33 | int(v := 1) +34 34 | int(~1) +35 35 | int(-1) + +RUF046.py:33:1: RUF046 [*] Value being casted is already an integer + | +32 | int(1) +33 | int(v := 1) + | ^^^^^^^^^^^ RUF046 +34 | int(~1) +35 | int(-1) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +30 30 | int(round(1., None)) +31 31 | +32 32 | int(1) +33 |-int(v := 1) + 33 |+(v := 1) +34 34 | int(~1) +35 35 | int(-1) +36 36 | int(+1) + +RUF046.py:34:1: RUF046 [*] Value being casted is already an integer + | +32 | int(1) +33 | int(v := 1) +34 | int(~1) + | ^^^^^^^ RUF046 +35 | int(-1) +36 | int(+1) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +31 31 | +32 32 | int(1) +33 33 | int(v := 1) +34 |-int(~1) + 34 |+~1 +35 35 | int(-1) +36 36 | int(+1) +37 37 | RUF046.py:35:1: RUF046 [*] Value being casted is already an integer | -33 | ### Unsafe -34 | -35 | int(math.ceil()) - | ^^^^^^^^^^^^^^^^ RUF046 -36 | int(math.floor()) -37 | int(math.trunc()) +33 | int(v := 1) +34 | int(~1) +35 | int(-1) + | ^^^^^^^ RUF046 +36 | int(+1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -32 32 | -33 33 | ### Unsafe -34 34 | -35 |-int(math.ceil()) - 35 |+math.ceil() -36 36 | int(math.floor()) -37 37 | int(math.trunc()) -38 38 | +ℹ Safe fix +32 32 | int(1) +33 33 | int(v := 1) +34 34 | int(~1) +35 |-int(-1) + 35 |+-1 +36 36 | int(+1) +37 37 | +38 38 | int(1 + 1) RUF046.py:36:1: RUF046 [*] Value being casted is already an integer | -35 | int(math.ceil()) -36 | int(math.floor()) - | ^^^^^^^^^^^^^^^^^ RUF046 -37 | int(math.trunc()) +34 | int(~1) +35 | int(-1) +36 | int(+1) + | ^^^^^^^ RUF046 +37 | +38 | int(1 + 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -33 33 | ### Unsafe -34 34 | -35 35 | int(math.ceil()) -36 |-int(math.floor()) - 36 |+math.floor() -37 37 | int(math.trunc()) -38 38 | -39 39 | int(round(inferred_int, 0)) - -RUF046.py:37:1: RUF046 [*] Value being casted is already an integer - | -35 | int(math.ceil()) -36 | int(math.floor()) -37 | int(math.trunc()) - | ^^^^^^^^^^^^^^^^^ RUF046 -38 | -39 | int(round(inferred_int, 0)) +ℹ Safe fix +33 33 | int(v := 1) +34 34 | int(~1) +35 35 | int(-1) +36 |-int(+1) + 36 |++1 +37 37 | +38 38 | int(1 + 1) +39 39 | int(1 - 1) + +RUF046.py:38:1: RUF046 [*] Value being casted is already an integer + | +36 | int(+1) +37 | +38 | int(1 + 1) + | ^^^^^^^^^^ RUF046 +39 | int(1 - 1) +40 | int(1 * 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -34 34 | -35 35 | int(math.ceil()) -36 36 | int(math.floor()) -37 |-int(math.trunc()) - 37 |+math.trunc() -38 38 | -39 39 | int(round(inferred_int, 0)) -40 40 | int(round(inferred_int, 10)) +ℹ Safe fix +35 35 | int(-1) +36 36 | int(+1) +37 37 | +38 |-int(1 + 1) + 38 |+1 + 1 +39 39 | int(1 - 1) +40 40 | int(1 * 1) +41 41 | int(1 % 1) RUF046.py:39:1: RUF046 [*] Value being casted is already an integer | -37 | int(math.trunc()) -38 | -39 | int(round(inferred_int, 0)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 -40 | int(round(inferred_int, 10)) +38 | int(1 + 1) +39 | int(1 - 1) + | ^^^^^^^^^^ RUF046 +40 | int(1 * 1) +41 | int(1 % 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -36 36 | int(math.floor()) -37 37 | int(math.trunc()) -38 38 | -39 |-int(round(inferred_int, 0)) - 39 |+round(inferred_int, 0) -40 40 | int(round(inferred_int, 10)) -41 41 | -42 42 | int(round(inferred_int)) +ℹ Safe fix +36 36 | int(+1) +37 37 | +38 38 | int(1 + 1) +39 |-int(1 - 1) + 39 |+1 - 1 +40 40 | int(1 * 1) +41 41 | int(1 % 1) +42 42 | int(1 ** 1) RUF046.py:40:1: RUF046 [*] Value being casted is already an integer | -39 | int(round(inferred_int, 0)) -40 | int(round(inferred_int, 10)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 -41 | -42 | int(round(inferred_int)) +38 | int(1 + 1) +39 | int(1 - 1) +40 | int(1 * 1) + | ^^^^^^^^^^ RUF046 +41 | int(1 % 1) +42 | int(1 ** 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -37 37 | int(math.trunc()) -38 38 | -39 39 | int(round(inferred_int, 0)) -40 |-int(round(inferred_int, 10)) - 40 |+round(inferred_int, 10) -41 41 | -42 42 | int(round(inferred_int)) -43 43 | int(round(inferred_int, None)) +ℹ Safe fix +37 37 | +38 38 | int(1 + 1) +39 39 | int(1 - 1) +40 |-int(1 * 1) + 40 |+1 * 1 +41 41 | int(1 % 1) +42 42 | int(1 ** 1) +43 43 | int(1 << 1) + +RUF046.py:41:1: RUF046 [*] Value being casted is already an integer + | +39 | int(1 - 1) +40 | int(1 * 1) +41 | int(1 % 1) + | ^^^^^^^^^^ RUF046 +42 | int(1 ** 1) +43 | int(1 << 1) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +38 38 | int(1 + 1) +39 39 | int(1 - 1) +40 40 | int(1 * 1) +41 |-int(1 % 1) + 41 |+1 % 1 +42 42 | int(1 ** 1) +43 43 | int(1 << 1) +44 44 | int(1 >> 1) RUF046.py:42:1: RUF046 [*] Value being casted is already an integer | -40 | int(round(inferred_int, 10)) -41 | -42 | int(round(inferred_int)) - | ^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 -43 | int(round(inferred_int, None)) +40 | int(1 * 1) +41 | int(1 % 1) +42 | int(1 ** 1) + | ^^^^^^^^^^^ RUF046 +43 | int(1 << 1) +44 | int(1 >> 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -39 39 | int(round(inferred_int, 0)) -40 40 | int(round(inferred_int, 10)) -41 41 | -42 |-int(round(inferred_int)) - 42 |+round(inferred_int) -43 43 | int(round(inferred_int, None)) -44 44 | -45 45 | int(round(inferred_float)) +ℹ Safe fix +39 39 | int(1 - 1) +40 40 | int(1 * 1) +41 41 | int(1 % 1) +42 |-int(1 ** 1) + 42 |+1 ** 1 +43 43 | int(1 << 1) +44 44 | int(1 >> 1) +45 45 | int(1 | 1) RUF046.py:43:1: RUF046 [*] Value being casted is already an integer | -42 | int(round(inferred_int)) -43 | int(round(inferred_int, None)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 -44 | -45 | int(round(inferred_float)) +41 | int(1 % 1) +42 | int(1 ** 1) +43 | int(1 << 1) + | ^^^^^^^^^^^ RUF046 +44 | int(1 >> 1) +45 | int(1 | 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -40 40 | int(round(inferred_int, 10)) -41 41 | -42 42 | int(round(inferred_int)) -43 |-int(round(inferred_int, None)) - 43 |+round(inferred_int, None) -44 44 | -45 45 | int(round(inferred_float)) -46 46 | int(round(inferred_float, None)) +ℹ Safe fix +40 40 | int(1 * 1) +41 41 | int(1 % 1) +42 42 | int(1 ** 1) +43 |-int(1 << 1) + 43 |+1 << 1 +44 44 | int(1 >> 1) +45 45 | int(1 | 1) +46 46 | int(1 ^ 1) + +RUF046.py:44:1: RUF046 [*] Value being casted is already an integer + | +42 | int(1 ** 1) +43 | int(1 << 1) +44 | int(1 >> 1) + | ^^^^^^^^^^^ RUF046 +45 | int(1 | 1) +46 | int(1 ^ 1) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +41 41 | int(1 % 1) +42 42 | int(1 ** 1) +43 43 | int(1 << 1) +44 |-int(1 >> 1) + 44 |+1 >> 1 +45 45 | int(1 | 1) +46 46 | int(1 ^ 1) +47 47 | int(1 & 1) RUF046.py:45:1: RUF046 [*] Value being casted is already an integer | -43 | int(round(inferred_int, None)) -44 | -45 | int(round(inferred_float)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 -46 | int(round(inferred_float, None)) +43 | int(1 << 1) +44 | int(1 >> 1) +45 | int(1 | 1) + | ^^^^^^^^^^ RUF046 +46 | int(1 ^ 1) +47 | int(1 & 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -42 42 | int(round(inferred_int)) -43 43 | int(round(inferred_int, None)) -44 44 | -45 |-int(round(inferred_float)) - 45 |+round(inferred_float) -46 46 | int(round(inferred_float, None)) -47 47 | -48 48 | int(round(unknown)) +ℹ Safe fix +42 42 | int(1 ** 1) +43 43 | int(1 << 1) +44 44 | int(1 >> 1) +45 |-int(1 | 1) + 45 |+1 | 1 +46 46 | int(1 ^ 1) +47 47 | int(1 & 1) +48 48 | int(1 // 1) RUF046.py:46:1: RUF046 [*] Value being casted is already an integer | -45 | int(round(inferred_float)) -46 | int(round(inferred_float, None)) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 -47 | -48 | int(round(unknown)) +44 | int(1 >> 1) +45 | int(1 | 1) +46 | int(1 ^ 1) + | ^^^^^^^^^^ RUF046 +47 | int(1 & 1) +48 | int(1 // 1) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -43 43 | int(round(inferred_int, None)) -44 44 | -45 45 | int(round(inferred_float)) -46 |-int(round(inferred_float, None)) - 46 |+round(inferred_float, None) -47 47 | -48 48 | int(round(unknown)) -49 49 | int(round(unknown, None)) +ℹ Safe fix +43 43 | int(1 << 1) +44 44 | int(1 >> 1) +45 45 | int(1 | 1) +46 |-int(1 ^ 1) + 46 |+1 ^ 1 +47 47 | int(1 & 1) +48 48 | int(1 // 1) +49 49 | + +RUF046.py:47:1: RUF046 [*] Value being casted is already an integer + | +45 | int(1 | 1) +46 | int(1 ^ 1) +47 | int(1 & 1) + | ^^^^^^^^^^ RUF046 +48 | int(1 // 1) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +44 44 | int(1 >> 1) +45 45 | int(1 | 1) +46 46 | int(1 ^ 1) +47 |-int(1 & 1) + 47 |+1 & 1 +48 48 | int(1 // 1) +49 49 | +50 50 | int(1 if ... else 2) RUF046.py:48:1: RUF046 [*] Value being casted is already an integer | -46 | int(round(inferred_float, None)) -47 | -48 | int(round(unknown)) - | ^^^^^^^^^^^^^^^^^^^ RUF046 -49 | int(round(unknown, None)) +46 | int(1 ^ 1) +47 | int(1 & 1) +48 | int(1 // 1) + | ^^^^^^^^^^^ RUF046 +49 | +50 | int(1 if ... else 2) | = help: Remove unnecessary conversion to `int` -ℹ Unsafe fix -45 45 | int(round(inferred_float)) -46 46 | int(round(inferred_float, None)) -47 47 | -48 |-int(round(unknown)) - 48 |+round(unknown) -49 49 | int(round(unknown, None)) -50 50 | +ℹ Safe fix +45 45 | int(1 | 1) +46 46 | int(1 ^ 1) +47 47 | int(1 & 1) +48 |-int(1 // 1) + 48 |+1 // 1 +49 49 | +50 50 | int(1 if ... else 2) +51 51 | + +RUF046.py:50:1: RUF046 [*] Value being casted is already an integer + | +48 | int(1 // 1) +49 | +50 | int(1 if ... else 2) + | ^^^^^^^^^^^^^^^^^^^^ RUF046 +51 | +52 | int(1 and 0) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +47 47 | int(1 & 1) +48 48 | int(1 // 1) +49 49 | +50 |-int(1 if ... else 2) + 50 |+1 if ... else 2 +51 51 | +52 52 | int(1 and 0) +53 53 | int(0 or -1) + +RUF046.py:52:1: RUF046 [*] Value being casted is already an integer + | +50 | int(1 if ... else 2) +51 | +52 | int(1 and 0) + | ^^^^^^^^^^^^ RUF046 +53 | int(0 or -1) + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +49 49 | +50 50 | int(1 if ... else 2) 51 51 | +52 |-int(1 and 0) + 52 |+1 and 0 +53 53 | int(0 or -1) +54 54 | +55 55 | + +RUF046.py:53:1: RUF046 [*] Value being casted is already an integer + | +52 | int(1 and 0) +53 | int(0 or -1) + | ^^^^^^^^^^^^ RUF046 + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +50 50 | int(1 if ... else 2) +51 51 | +52 52 | int(1 and 0) +53 |-int(0 or -1) + 53 |+0 or -1 +54 54 | +55 55 | +56 56 | if int(1 + 2) * 3: + +RUF046.py:56:4: RUF046 [*] Value being casted is already an integer + | +56 | if int(1 + 2) * 3: + | ^^^^^^^^^^ RUF046 +57 | ... + | + = help: Remove unnecessary conversion to `int` + +ℹ Safe fix +53 53 | int(0 or -1) +54 54 | +55 55 | +56 |-if int(1 + 2) * 3: + 56 |+if (1 + 2) * 3: +57 57 | ... +58 58 | +59 59 | + +RUF046.py:62:1: RUF046 [*] Value being casted is already an integer + | +60 | ### Unsafe +61 | +62 | int(math.ceil()) + | ^^^^^^^^^^^^^^^^ RUF046 +63 | int(math.floor()) +64 | int(math.trunc()) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +59 59 | +60 60 | ### Unsafe +61 61 | +62 |-int(math.ceil()) + 62 |+math.ceil() +63 63 | int(math.floor()) +64 64 | int(math.trunc()) +65 65 | + +RUF046.py:63:1: RUF046 [*] Value being casted is already an integer + | +62 | int(math.ceil()) +63 | int(math.floor()) + | ^^^^^^^^^^^^^^^^^ RUF046 +64 | int(math.trunc()) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +60 60 | ### Unsafe +61 61 | +62 62 | int(math.ceil()) +63 |-int(math.floor()) + 63 |+math.floor() +64 64 | int(math.trunc()) +65 65 | +66 66 | int(round(inferred_int, 0)) + +RUF046.py:64:1: RUF046 [*] Value being casted is already an integer + | +62 | int(math.ceil()) +63 | int(math.floor()) +64 | int(math.trunc()) + | ^^^^^^^^^^^^^^^^^ RUF046 +65 | +66 | int(round(inferred_int, 0)) + | + = help: Remove unnecessary conversion to `int` -RUF046.py:49:1: RUF046 [*] Value being casted is already an integer +ℹ Unsafe fix +61 61 | +62 62 | int(math.ceil()) +63 63 | int(math.floor()) +64 |-int(math.trunc()) + 64 |+math.trunc() +65 65 | +66 66 | int(round(inferred_int, 0)) +67 67 | int(round(inferred_int, 10)) + +RUF046.py:66:1: RUF046 [*] Value being casted is already an integer + | +64 | int(math.trunc()) +65 | +66 | int(round(inferred_int, 0)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 +67 | int(round(inferred_int, 10)) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +63 63 | int(math.floor()) +64 64 | int(math.trunc()) +65 65 | +66 |-int(round(inferred_int, 0)) + 66 |+round(inferred_int, 0) +67 67 | int(round(inferred_int, 10)) +68 68 | +69 69 | int(round(inferred_int)) + +RUF046.py:67:1: RUF046 [*] Value being casted is already an integer + | +66 | int(round(inferred_int, 0)) +67 | int(round(inferred_int, 10)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 +68 | +69 | int(round(inferred_int)) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +64 64 | int(math.trunc()) +65 65 | +66 66 | int(round(inferred_int, 0)) +67 |-int(round(inferred_int, 10)) + 67 |+round(inferred_int, 10) +68 68 | +69 69 | int(round(inferred_int)) +70 70 | int(round(inferred_int, None)) + +RUF046.py:69:1: RUF046 [*] Value being casted is already an integer + | +67 | int(round(inferred_int, 10)) +68 | +69 | int(round(inferred_int)) + | ^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 +70 | int(round(inferred_int, None)) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +66 66 | int(round(inferred_int, 0)) +67 67 | int(round(inferred_int, 10)) +68 68 | +69 |-int(round(inferred_int)) + 69 |+round(inferred_int) +70 70 | int(round(inferred_int, None)) +71 71 | +72 72 | int(round(inferred_float)) + +RUF046.py:70:1: RUF046 [*] Value being casted is already an integer + | +69 | int(round(inferred_int)) +70 | int(round(inferred_int, None)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 +71 | +72 | int(round(inferred_float)) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +67 67 | int(round(inferred_int, 10)) +68 68 | +69 69 | int(round(inferred_int)) +70 |-int(round(inferred_int, None)) + 70 |+round(inferred_int, None) +71 71 | +72 72 | int(round(inferred_float)) +73 73 | int(round(inferred_float, None)) + +RUF046.py:72:1: RUF046 [*] Value being casted is already an integer + | +70 | int(round(inferred_int, None)) +71 | +72 | int(round(inferred_float)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 +73 | int(round(inferred_float, None)) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +69 69 | int(round(inferred_int)) +70 70 | int(round(inferred_int, None)) +71 71 | +72 |-int(round(inferred_float)) + 72 |+round(inferred_float) +73 73 | int(round(inferred_float, None)) +74 74 | +75 75 | int(round(unknown)) + +RUF046.py:73:1: RUF046 [*] Value being casted is already an integer + | +72 | int(round(inferred_float)) +73 | int(round(inferred_float, None)) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 +74 | +75 | int(round(unknown)) | -48 | int(round(unknown)) -49 | int(round(unknown, None)) + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +70 70 | int(round(inferred_int, None)) +71 71 | +72 72 | int(round(inferred_float)) +73 |-int(round(inferred_float, None)) + 73 |+round(inferred_float, None) +74 74 | +75 75 | int(round(unknown)) +76 76 | int(round(unknown, None)) + +RUF046.py:75:1: RUF046 [*] Value being casted is already an integer + | +73 | int(round(inferred_float, None)) +74 | +75 | int(round(unknown)) + | ^^^^^^^^^^^^^^^^^^^ RUF046 +76 | int(round(unknown, None)) + | + = help: Remove unnecessary conversion to `int` + +ℹ Unsafe fix +72 72 | int(round(inferred_float)) +73 73 | int(round(inferred_float, None)) +74 74 | +75 |-int(round(unknown)) + 75 |+round(unknown) +76 76 | int(round(unknown, None)) +77 77 | +78 78 | + +RUF046.py:76:1: RUF046 [*] Value being casted is already an integer + | +75 | int(round(unknown)) +76 | int(round(unknown, None)) | ^^^^^^^^^^^^^^^^^^^^^^^^^ RUF046 | = help: Remove unnecessary conversion to `int` ℹ Unsafe fix -46 46 | int(round(inferred_float, None)) -47 47 | -48 48 | int(round(unknown)) -49 |-int(round(unknown, None)) - 49 |+round(unknown, None) -50 50 | -51 51 | -52 52 | ### No errors +73 73 | int(round(inferred_float, None)) +74 74 | +75 75 | int(round(unknown)) +76 |-int(round(unknown, None)) + 76 |+round(unknown, None) +77 77 | +78 78 | +79 79 | ### No errors