mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
[ruff
] Unnecessary cast to int
(RUF046
) (#14697)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
## Summary Resolves #11412. ## Test Plan `cargo nextest run` and `cargo insta test`. --------- Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
2d3f557875
commit
fda8b1f884
9 changed files with 672 additions and 1 deletions
50
crates/ruff_linter/resources/test/fixtures/ruff/RUF046.py
vendored
Normal file
50
crates/ruff_linter/resources/test/fixtures/ruff/RUF046.py
vendored
Normal file
|
@ -0,0 +1,50 @@
|
|||
import math
|
||||
|
||||
|
||||
### Safely fixable
|
||||
|
||||
# Arguments are not checked
|
||||
int(id())
|
||||
int(len([]))
|
||||
int(ord(foo))
|
||||
int(hash(foo, bar))
|
||||
int(int(''))
|
||||
|
||||
int(math.comb())
|
||||
int(math.factorial())
|
||||
int(math.gcd())
|
||||
int(math.lcm())
|
||||
int(math.isqrt())
|
||||
int(math.perm())
|
||||
|
||||
|
||||
### Unsafe
|
||||
|
||||
int(math.ceil())
|
||||
int(math.floor())
|
||||
int(math.trunc())
|
||||
|
||||
|
||||
### `round()`
|
||||
|
||||
## Errors
|
||||
int(round(0))
|
||||
int(round(0, 0))
|
||||
int(round(0, None))
|
||||
|
||||
int(round(0.1))
|
||||
int(round(0.1, None))
|
||||
|
||||
# Argument type is not checked
|
||||
foo = type("Foo", (), {"__round__": lambda self: 4.2})()
|
||||
|
||||
int(round(foo))
|
||||
int(round(foo, 0))
|
||||
int(round(foo, None))
|
||||
|
||||
## No errors
|
||||
int(round(0, 3.14))
|
||||
int(round(0, non_literal))
|
||||
int(round(0, 0), base)
|
||||
int(round(0, 0, extra=keyword))
|
||||
int(round(0.1, 0))
|
|
@ -1093,6 +1093,9 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
|
|||
if checker.enabled(Rule::Airflow3Removal) {
|
||||
airflow::rules::removed_in_3(checker, expr);
|
||||
}
|
||||
if checker.enabled(Rule::UnnecessaryCastToInt) {
|
||||
ruff::rules::unnecessary_cast_to_int(checker, call);
|
||||
}
|
||||
}
|
||||
Expr::Dict(dict) => {
|
||||
if checker.any_enabled(&[
|
||||
|
|
|
@ -983,6 +983,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
|
|||
(Ruff, "039") => (RuleGroup::Preview, rules::ruff::rules::UnrawRePattern),
|
||||
(Ruff, "040") => (RuleGroup::Preview, rules::ruff::rules::InvalidAssertMessageLiteralArgument),
|
||||
(Ruff, "041") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryNestedLiteral),
|
||||
(Ruff, "046") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryCastToInt),
|
||||
(Ruff, "048") => (RuleGroup::Preview, rules::ruff::rules::MapIntVersionParsing),
|
||||
(Ruff, "052") => (RuleGroup::Preview, rules::ruff::rules::UsedDummyVariable),
|
||||
(Ruff, "055") => (RuleGroup::Preview, rules::ruff::rules::UnnecessaryRegularExpression),
|
||||
|
|
|
@ -413,6 +413,7 @@ mod tests {
|
|||
#[test_case(Rule::UnrawRePattern, Path::new("RUF039_concat.py"))]
|
||||
#[test_case(Rule::UnnecessaryRegularExpression, Path::new("RUF055_0.py"))]
|
||||
#[test_case(Rule::UnnecessaryRegularExpression, Path::new("RUF055_1.py"))]
|
||||
#[test_case(Rule::UnnecessaryCastToInt, Path::new("RUF046.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"preview__{}_{}",
|
||||
|
|
|
@ -30,6 +30,7 @@ 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::*;
|
||||
|
@ -78,6 +79,7 @@ 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;
|
||||
|
|
|
@ -0,0 +1,183 @@
|
|||
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, ExprName, ExprNumberLiteral, Number};
|
||||
use ruff_python_semantic::analyze::typing;
|
||||
use ruff_python_semantic::SemanticModel;
|
||||
use ruff_text_size::TextRange;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for `int` conversions of values that are already integers.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Such a conversion is unnecessary.
|
||||
///
|
||||
/// ## Known problems
|
||||
/// This rule may produce false positives for `round`, `math.ceil`, `math.floor`,
|
||||
/// and `math.trunc` calls when values override the `__round__`, `__ceil__`, `__floor__`,
|
||||
/// or `__trunc__` operators such that they don't return an integer.
|
||||
///
|
||||
/// ## Example
|
||||
///
|
||||
/// ```python
|
||||
/// int(len([]))
|
||||
/// int(round(foo, None))
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
///
|
||||
/// ```python
|
||||
/// len([])
|
||||
/// round(foo)
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// The fix for `round`, `math.ceil`, `math.floor`, and `math.truncate` is unsafe
|
||||
/// because removing the `int` conversion can change the semantics for values
|
||||
/// overriding the `__round__`, `__ceil__`, `__floor__`, or `__trunc__` dunder methods
|
||||
/// such that they don't return an integer.
|
||||
#[derive(ViolationMetadata)]
|
||||
pub(crate) struct UnnecessaryCastToInt;
|
||||
|
||||
impl AlwaysFixableViolation for UnnecessaryCastToInt {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
"Value being casted is already an integer".to_string()
|
||||
}
|
||||
|
||||
fn fix_title(&self) -> String {
|
||||
"Remove unnecessary conversion to `int`".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
/// RUF046
|
||||
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 {
|
||||
return;
|
||||
};
|
||||
|
||||
let (func, arguments) = (&inner_call.func, &inner_call.arguments);
|
||||
let (outer_range, inner_range) = (call.range, inner_call.range);
|
||||
|
||||
let Some(qualified_name) = checker.semantic().resolve_qualified_name(func) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let fix = 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))
|
||||
}
|
||||
|
||||
// Depends on `ndigits` and `number.__round__`
|
||||
["" | "builtins", "round"] => {
|
||||
if let Some(fix) = replace_with_shortened_round_call(checker, outer_range, arguments) {
|
||||
fix
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Depends on `__ceil__`/`__floor__`/`__trunc__`
|
||||
["math", "ceil" | "floor" | "trunc"] => {
|
||||
Fix::unsafe_edit(replace_with_inner(checker, outer_range, inner_range))
|
||||
}
|
||||
|
||||
_ => return,
|
||||
};
|
||||
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(UnnecessaryCastToInt, call.range).with_fix(fix));
|
||||
}
|
||||
|
||||
fn single_argument_to_int_call<'a>(
|
||||
semantic: &SemanticModel,
|
||||
call: &'a ExprCall,
|
||||
) -> Option<&'a Expr> {
|
||||
let ExprCall {
|
||||
func, arguments, ..
|
||||
} = call;
|
||||
|
||||
if !semantic.match_builtin_expr(func, "int") {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !arguments.keywords.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let [argument] = &*arguments.args else {
|
||||
return None;
|
||||
};
|
||||
|
||||
Some(argument)
|
||||
}
|
||||
|
||||
/// Returns an [`Edit`] when the call is of any of the forms:
|
||||
/// * `round(integer)`, `round(integer, 0)`, `round(integer, None)`
|
||||
/// * `round(whatever)`, `round(whatever, None)`
|
||||
fn replace_with_shortened_round_call(
|
||||
checker: &Checker,
|
||||
outer_range: TextRange,
|
||||
arguments: &Arguments,
|
||||
) -> Option<Fix> {
|
||||
if arguments.len() > 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let number = arguments.find_argument("number", 0)?;
|
||||
let ndigits = arguments.find_argument("ndigits", 1);
|
||||
|
||||
let number_is_int = match number {
|
||||
Expr::Name(name) => is_int(checker.semantic(), name),
|
||||
Expr::NumberLiteral(ExprNumberLiteral { value, .. }) => matches!(value, Number::Int(..)),
|
||||
_ => false,
|
||||
};
|
||||
|
||||
match ndigits {
|
||||
Some(Expr::NumberLiteral(ExprNumberLiteral { value, .. }))
|
||||
if is_literal_zero(value) && number_is_int => {}
|
||||
Some(Expr::NoneLiteral(_)) | None => {}
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
let number_expr = checker.locator().slice(number);
|
||||
let new_content = format!("round({number_expr})");
|
||||
|
||||
let applicability = if number_is_int {
|
||||
Applicability::Safe
|
||||
} else {
|
||||
Applicability::Unsafe
|
||||
};
|
||||
|
||||
Some(Fix::applicable_edit(
|
||||
Edit::range_replacement(new_content, outer_range),
|
||||
applicability,
|
||||
))
|
||||
}
|
||||
|
||||
fn is_int(semantic: &SemanticModel, name: &ExprName) -> bool {
|
||||
let Some(binding) = semantic.only_binding(name).map(|id| semantic.binding(id)) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
typing::is_int(binding, semantic)
|
||||
}
|
||||
|
||||
fn is_literal_zero(value: &Number) -> bool {
|
||||
let Number::Int(int) = value else {
|
||||
return false;
|
||||
};
|
||||
|
||||
matches!(int.as_u8(), Some(0))
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
|
@ -0,0 +1,430 @@
|
|||
---
|
||||
source: crates/ruff_linter/src/rules/ruff/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
RUF046.py:7:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
6 | # Arguments are not checked
|
||||
7 | int(id())
|
||||
| ^^^^^^^^^ RUF046
|
||||
8 | int(len([]))
|
||||
9 | int(ord(foo))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
4 4 | ### Safely fixable
|
||||
5 5 |
|
||||
6 6 | # Arguments are not checked
|
||||
7 |-int(id())
|
||||
7 |+id()
|
||||
8 8 | int(len([]))
|
||||
9 9 | int(ord(foo))
|
||||
10 10 | int(hash(foo, bar))
|
||||
|
||||
RUF046.py:8:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
6 | # Arguments are not checked
|
||||
7 | int(id())
|
||||
8 | int(len([]))
|
||||
| ^^^^^^^^^^^^ RUF046
|
||||
9 | int(ord(foo))
|
||||
10 | int(hash(foo, bar))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
5 5 |
|
||||
6 6 | # Arguments are not checked
|
||||
7 7 | int(id())
|
||||
8 |-int(len([]))
|
||||
8 |+len([])
|
||||
9 9 | int(ord(foo))
|
||||
10 10 | int(hash(foo, bar))
|
||||
11 11 | int(int(''))
|
||||
|
||||
RUF046.py:9:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
7 | int(id())
|
||||
8 | int(len([]))
|
||||
9 | int(ord(foo))
|
||||
| ^^^^^^^^^^^^^ RUF046
|
||||
10 | int(hash(foo, bar))
|
||||
11 | int(int(''))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
6 6 | # Arguments are not checked
|
||||
7 7 | int(id())
|
||||
8 8 | int(len([]))
|
||||
9 |-int(ord(foo))
|
||||
9 |+ord(foo)
|
||||
10 10 | int(hash(foo, bar))
|
||||
11 11 | int(int(''))
|
||||
12 12 |
|
||||
|
||||
RUF046.py:10:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
8 | int(len([]))
|
||||
9 | int(ord(foo))
|
||||
10 | int(hash(foo, bar))
|
||||
| ^^^^^^^^^^^^^^^^^^^ RUF046
|
||||
11 | int(int(''))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
7 7 | int(id())
|
||||
8 8 | int(len([]))
|
||||
9 9 | int(ord(foo))
|
||||
10 |-int(hash(foo, bar))
|
||||
10 |+hash(foo, bar)
|
||||
11 11 | int(int(''))
|
||||
12 12 |
|
||||
13 13 | int(math.comb())
|
||||
|
||||
RUF046.py:11:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
9 | int(ord(foo))
|
||||
10 | int(hash(foo, bar))
|
||||
11 | int(int(''))
|
||||
| ^^^^^^^^^^^^ RUF046
|
||||
12 |
|
||||
13 | int(math.comb())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
8 8 | int(len([]))
|
||||
9 9 | int(ord(foo))
|
||||
10 10 | int(hash(foo, bar))
|
||||
11 |-int(int(''))
|
||||
11 |+int('')
|
||||
12 12 |
|
||||
13 13 | int(math.comb())
|
||||
14 14 | int(math.factorial())
|
||||
|
||||
RUF046.py:13:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
11 | int(int(''))
|
||||
12 |
|
||||
13 | int(math.comb())
|
||||
| ^^^^^^^^^^^^^^^^ RUF046
|
||||
14 | int(math.factorial())
|
||||
15 | int(math.gcd())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
10 10 | int(hash(foo, bar))
|
||||
11 11 | int(int(''))
|
||||
12 12 |
|
||||
13 |-int(math.comb())
|
||||
13 |+math.comb()
|
||||
14 14 | int(math.factorial())
|
||||
15 15 | int(math.gcd())
|
||||
16 16 | int(math.lcm())
|
||||
|
||||
RUF046.py:14:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
13 | int(math.comb())
|
||||
14 | int(math.factorial())
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ RUF046
|
||||
15 | int(math.gcd())
|
||||
16 | int(math.lcm())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
11 11 | int(int(''))
|
||||
12 12 |
|
||||
13 13 | int(math.comb())
|
||||
14 |-int(math.factorial())
|
||||
14 |+math.factorial()
|
||||
15 15 | int(math.gcd())
|
||||
16 16 | int(math.lcm())
|
||||
17 17 | int(math.isqrt())
|
||||
|
||||
RUF046.py:15:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
13 | int(math.comb())
|
||||
14 | int(math.factorial())
|
||||
15 | int(math.gcd())
|
||||
| ^^^^^^^^^^^^^^^ RUF046
|
||||
16 | int(math.lcm())
|
||||
17 | int(math.isqrt())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
12 12 |
|
||||
13 13 | int(math.comb())
|
||||
14 14 | int(math.factorial())
|
||||
15 |-int(math.gcd())
|
||||
15 |+math.gcd()
|
||||
16 16 | int(math.lcm())
|
||||
17 17 | int(math.isqrt())
|
||||
18 18 | int(math.perm())
|
||||
|
||||
RUF046.py:16:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
14 | int(math.factorial())
|
||||
15 | int(math.gcd())
|
||||
16 | int(math.lcm())
|
||||
| ^^^^^^^^^^^^^^^ RUF046
|
||||
17 | int(math.isqrt())
|
||||
18 | int(math.perm())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
13 13 | int(math.comb())
|
||||
14 14 | int(math.factorial())
|
||||
15 15 | int(math.gcd())
|
||||
16 |-int(math.lcm())
|
||||
16 |+math.lcm()
|
||||
17 17 | int(math.isqrt())
|
||||
18 18 | int(math.perm())
|
||||
19 19 |
|
||||
|
||||
RUF046.py:17:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
15 | int(math.gcd())
|
||||
16 | int(math.lcm())
|
||||
17 | int(math.isqrt())
|
||||
| ^^^^^^^^^^^^^^^^^ RUF046
|
||||
18 | int(math.perm())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
14 14 | int(math.factorial())
|
||||
15 15 | int(math.gcd())
|
||||
16 16 | int(math.lcm())
|
||||
17 |-int(math.isqrt())
|
||||
17 |+math.isqrt()
|
||||
18 18 | int(math.perm())
|
||||
19 19 |
|
||||
20 20 |
|
||||
|
||||
RUF046.py:18:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
16 | int(math.lcm())
|
||||
17 | int(math.isqrt())
|
||||
18 | int(math.perm())
|
||||
| ^^^^^^^^^^^^^^^^ RUF046
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
15 15 | int(math.gcd())
|
||||
16 16 | int(math.lcm())
|
||||
17 17 | int(math.isqrt())
|
||||
18 |-int(math.perm())
|
||||
18 |+math.perm()
|
||||
19 19 |
|
||||
20 20 |
|
||||
21 21 | ### Unsafe
|
||||
|
||||
RUF046.py:23:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
21 | ### Unsafe
|
||||
22 |
|
||||
23 | int(math.ceil())
|
||||
| ^^^^^^^^^^^^^^^^ RUF046
|
||||
24 | int(math.floor())
|
||||
25 | int(math.trunc())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Unsafe fix
|
||||
20 20 |
|
||||
21 21 | ### Unsafe
|
||||
22 22 |
|
||||
23 |-int(math.ceil())
|
||||
23 |+math.ceil()
|
||||
24 24 | int(math.floor())
|
||||
25 25 | int(math.trunc())
|
||||
26 26 |
|
||||
|
||||
RUF046.py:24:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
23 | int(math.ceil())
|
||||
24 | int(math.floor())
|
||||
| ^^^^^^^^^^^^^^^^^ RUF046
|
||||
25 | int(math.trunc())
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Unsafe fix
|
||||
21 21 | ### Unsafe
|
||||
22 22 |
|
||||
23 23 | int(math.ceil())
|
||||
24 |-int(math.floor())
|
||||
24 |+math.floor()
|
||||
25 25 | int(math.trunc())
|
||||
26 26 |
|
||||
27 27 |
|
||||
|
||||
RUF046.py:25:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
23 | int(math.ceil())
|
||||
24 | int(math.floor())
|
||||
25 | int(math.trunc())
|
||||
| ^^^^^^^^^^^^^^^^^ RUF046
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Unsafe fix
|
||||
22 22 |
|
||||
23 23 | int(math.ceil())
|
||||
24 24 | int(math.floor())
|
||||
25 |-int(math.trunc())
|
||||
25 |+math.trunc()
|
||||
26 26 |
|
||||
27 27 |
|
||||
28 28 | ### `round()`
|
||||
|
||||
RUF046.py:31:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
30 | ## Errors
|
||||
31 | int(round(0))
|
||||
| ^^^^^^^^^^^^^ RUF046
|
||||
32 | int(round(0, 0))
|
||||
33 | int(round(0, None))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
28 28 | ### `round()`
|
||||
29 29 |
|
||||
30 30 | ## Errors
|
||||
31 |-int(round(0))
|
||||
31 |+round(0)
|
||||
32 32 | int(round(0, 0))
|
||||
33 33 | int(round(0, None))
|
||||
34 34 |
|
||||
|
||||
RUF046.py:32:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
30 | ## Errors
|
||||
31 | int(round(0))
|
||||
32 | int(round(0, 0))
|
||||
| ^^^^^^^^^^^^^^^^ RUF046
|
||||
33 | int(round(0, None))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
29 29 |
|
||||
30 30 | ## Errors
|
||||
31 31 | int(round(0))
|
||||
32 |-int(round(0, 0))
|
||||
32 |+round(0)
|
||||
33 33 | int(round(0, None))
|
||||
34 34 |
|
||||
35 35 | int(round(0.1))
|
||||
|
||||
RUF046.py:33:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
31 | int(round(0))
|
||||
32 | int(round(0, 0))
|
||||
33 | int(round(0, None))
|
||||
| ^^^^^^^^^^^^^^^^^^^ RUF046
|
||||
34 |
|
||||
35 | int(round(0.1))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Safe fix
|
||||
30 30 | ## Errors
|
||||
31 31 | int(round(0))
|
||||
32 32 | int(round(0, 0))
|
||||
33 |-int(round(0, None))
|
||||
33 |+round(0)
|
||||
34 34 |
|
||||
35 35 | int(round(0.1))
|
||||
36 36 | int(round(0.1, None))
|
||||
|
||||
RUF046.py:35:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
33 | int(round(0, None))
|
||||
34 |
|
||||
35 | int(round(0.1))
|
||||
| ^^^^^^^^^^^^^^^ RUF046
|
||||
36 | int(round(0.1, None))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Unsafe fix
|
||||
32 32 | int(round(0, 0))
|
||||
33 33 | int(round(0, None))
|
||||
34 34 |
|
||||
35 |-int(round(0.1))
|
||||
35 |+round(0.1)
|
||||
36 36 | int(round(0.1, None))
|
||||
37 37 |
|
||||
38 38 | # Argument type is not checked
|
||||
|
||||
RUF046.py:36:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
35 | int(round(0.1))
|
||||
36 | int(round(0.1, None))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ RUF046
|
||||
37 |
|
||||
38 | # Argument type is not checked
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Unsafe fix
|
||||
33 33 | int(round(0, None))
|
||||
34 34 |
|
||||
35 35 | int(round(0.1))
|
||||
36 |-int(round(0.1, None))
|
||||
36 |+round(0.1)
|
||||
37 37 |
|
||||
38 38 | # Argument type is not checked
|
||||
39 39 | foo = type("Foo", (), {"__round__": lambda self: 4.2})()
|
||||
|
||||
RUF046.py:41:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
39 | foo = type("Foo", (), {"__round__": lambda self: 4.2})()
|
||||
40 |
|
||||
41 | int(round(foo))
|
||||
| ^^^^^^^^^^^^^^^ RUF046
|
||||
42 | int(round(foo, 0))
|
||||
43 | int(round(foo, None))
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Unsafe fix
|
||||
38 38 | # Argument type is not checked
|
||||
39 39 | foo = type("Foo", (), {"__round__": lambda self: 4.2})()
|
||||
40 40 |
|
||||
41 |-int(round(foo))
|
||||
41 |+round(foo)
|
||||
42 42 | int(round(foo, 0))
|
||||
43 43 | int(round(foo, None))
|
||||
44 44 |
|
||||
|
||||
RUF046.py:43:1: RUF046 [*] Value being casted is already an integer
|
||||
|
|
||||
41 | int(round(foo))
|
||||
42 | int(round(foo, 0))
|
||||
43 | int(round(foo, None))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ RUF046
|
||||
44 |
|
||||
45 | ## No errors
|
||||
|
|
||||
= help: Remove unnecessary conversion to `int`
|
||||
|
||||
ℹ Unsafe fix
|
||||
40 40 |
|
||||
41 41 | int(round(foo))
|
||||
42 42 | int(round(foo, 0))
|
||||
43 |-int(round(foo, None))
|
||||
43 |+round(foo)
|
||||
44 44 |
|
||||
45 45 | ## No errors
|
||||
46 46 | int(round(0, 3.14))
|
|
@ -96,7 +96,7 @@ impl Int {
|
|||
}
|
||||
}
|
||||
|
||||
/// Return the [`Int`] as an u64, if it can be represented as that data type.
|
||||
/// Return the [`Int`] as an usize, if it can be represented as that data type.
|
||||
pub fn as_usize(&self) -> Option<usize> {
|
||||
match &self.0 {
|
||||
Number::Small(small) => usize::try_from(*small).ok(),
|
||||
|
|
1
ruff.schema.json
generated
1
ruff.schema.json
generated
|
@ -3843,6 +3843,7 @@
|
|||
"RUF04",
|
||||
"RUF040",
|
||||
"RUF041",
|
||||
"RUF046",
|
||||
"RUF048",
|
||||
"RUF05",
|
||||
"RUF052",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue