diff --git a/crates/ruff_linter/resources/test/fixtures/refurb/FURB157.py b/crates/ruff_linter/resources/test/fixtures/refurb/FURB157.py index db49315f54..737da53643 100644 --- a/crates/ruff_linter/resources/test/fixtures/refurb/FURB157.py +++ b/crates/ruff_linter/resources/test/fixtures/refurb/FURB157.py @@ -91,3 +91,11 @@ Decimal("000_000") Decimal("_-1") # Should flag as verbose Decimal("_+1") # Should flag as verbose Decimal("_-1_000") # Should flag as verbose + + +Decimal( + float( + # text + "Infinity" + ) +) diff --git a/crates/ruff_linter/src/rules/refurb/rules/verbose_decimal_constructor.rs b/crates/ruff_linter/src/rules/refurb/rules/verbose_decimal_constructor.rs index 28779b021a..3923e66ace 100644 --- a/crates/ruff_linter/src/rules/refurb/rules/verbose_decimal_constructor.rs +++ b/crates/ruff_linter/src/rules/refurb/rules/verbose_decimal_constructor.rs @@ -1,15 +1,15 @@ -use ruff_macros::{ViolationMetadata, derive_message_formats}; +use std::borrow::Cow; use itertools::Itertools; +use ruff_diagnostics::Applicability; +use ruff_macros::{ViolationMetadata, derive_message_formats}; use ruff_python_ast::{self as ast, Expr}; use ruff_python_trivia::PythonWhitespace; use ruff_text_size::Ranged; -use std::borrow::Cow; use crate::checkers::ast::Checker; use crate::linter::float::as_non_finite_float_string_literal; use crate::{Edit, Fix, FixAvailability, Violation}; - /// ## What it does /// Checks for unnecessary string literal or float casts in `Decimal` /// constructors. @@ -45,6 +45,9 @@ use crate::{Edit, Fix, FixAvailability, Violation}; /// Decimal("Infinity") /// ``` /// +/// ## Fix safety +/// This rule's fix is marked as safe, unless the expression contains comments. +/// /// ## References /// - [Python documentation: `decimal`](https://docs.python.org/3/library/decimal.html) #[derive(ViolationMetadata)] @@ -153,10 +156,16 @@ pub(crate) fn verbose_decimal_constructor(checker: &Checker, call: &ast::ExprCal value.range(), ); - diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( - replacement, - value.range(), - ))); + let applicability = if checker.comment_ranges().intersects(value.range()) { + Applicability::Unsafe + } else { + Applicability::Safe + }; + + diagnostic.set_fix(Fix::applicable_edit( + Edit::range_replacement(replacement, value.range()), + applicability, + )); } Expr::Call(ast::ExprCall { func, arguments, .. @@ -193,10 +202,16 @@ pub(crate) fn verbose_decimal_constructor(checker: &Checker, call: &ast::ExprCal value.range(), ); - diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement( - replacement, - value.range(), - ))); + let applicability = if checker.comment_ranges().intersects(value.range()) { + Applicability::Unsafe + } else { + Applicability::Safe + }; + + diagnostic.set_fix(Fix::applicable_edit( + Edit::range_replacement(replacement, value.range()), + applicability, + )); } _ => {} } diff --git a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB157_FURB157.py.snap b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB157_FURB157.py.snap index 3f0a1c2cf6..db856f4057 100644 --- a/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB157_FURB157.py.snap +++ b/crates/ruff_linter/src/rules/refurb/snapshots/ruff_linter__rules__refurb__tests__FURB157_FURB157.py.snap @@ -728,6 +728,7 @@ help: Replace with `-1` 91 + Decimal(-1) # Should flag as verbose 92 | Decimal("_+1") # Should flag as verbose 93 | Decimal("_-1_000") # Should flag as verbose +94 | FURB157 [*] Verbose expression in `Decimal` constructor --> FURB157.py:92:9 @@ -745,6 +746,8 @@ help: Replace with `+1` - Decimal("_+1") # Should flag as verbose 92 + Decimal(+1) # Should flag as verbose 93 | Decimal("_-1_000") # Should flag as verbose +94 | +95 | FURB157 [*] Verbose expression in `Decimal` constructor --> FURB157.py:93:9 @@ -760,3 +763,29 @@ help: Replace with `-1_000` 92 | Decimal("_+1") # Should flag as verbose - Decimal("_-1_000") # Should flag as verbose 93 + Decimal(-1_000) # Should flag as verbose +94 | +95 | +96 | Decimal( + +FURB157 [*] Verbose expression in `Decimal` constructor + --> FURB157.py:97:5 + | + 96 | Decimal( + 97 | / float( + 98 | | # text + 99 | | "Infinity" +100 | | ) + | |_____^ +101 | ) + | +help: Replace with `"Infinity"` +94 | +95 | +96 | Decimal( + - float( + - # text + - "Infinity" + - ) +97 + "Infinity" +98 | ) +note: This is an unsafe fix and may change runtime behavior