[refurb] Make fix unsafe if it deletes comments (FURB145) (#22670)

<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

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

## Test Plan

<!-- How was it tested? -->
This commit is contained in:
chiri
2026-01-20 18:07:05 +03:00
committed by GitHub
parent 7b16239f29
commit 94ccbd28cf
3 changed files with 42 additions and 5 deletions

View File

@@ -19,3 +19,9 @@ h = l[1:]
i = l[:3]
j = l[1:3:2]
k = l[::2]
b = l[
# text
:
]

View File

@@ -1,3 +1,4 @@
use ruff_diagnostics::Applicability;
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::name::Name;
use ruff_python_ast::{self as ast, Expr};
@@ -34,6 +35,9 @@ use crate::rules::refurb::helpers::generate_method_call;
/// b = a.copy()
/// ```
///
/// ## Fix safety
/// This rule's fix is marked as safe, unless the slice expression contains comments.
///
/// ## References
/// - [Python documentation: Mutable Sequence Types](https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types)
#[derive(ViolationMetadata)]
@@ -64,11 +68,17 @@ pub(crate) fn slice_copy(checker: &Checker, subscript: &ast::ExprSubscript) {
};
let mut diagnostic = checker.report_diagnostic(SliceCopy, subscript.range());
let replacement = generate_method_call(name.clone(), "copy", checker.generator());
diagnostic.set_fix(Fix::safe_edit(Edit::replacement(
replacement,
subscript.start(),
subscript.end(),
)));
let applicability = if checker.comment_ranges().intersects(subscript.range()) {
Applicability::Unsafe
} else {
Applicability::Safe
};
diagnostic.set_fix(Fix::applicable_edit(
Edit::replacement(replacement, subscript.start(), subscript.end()),
applicability,
));
}
/// Matches `obj[:]` where `obj` is a list.

View File

@@ -118,3 +118,24 @@ help: Replace with `copy()`
10 |
11 | # False negatives.
12 | aa = a[:] # Type inference.
FURB145 [*] Prefer `copy` method over slicing
--> FURB145.py:24:5
|
24 | b = l[
| _____^
25 | | # text
26 | | :
27 | | ]
| |_^
|
help: Replace with `copy()`
21 | k = l[::2]
22 |
23 |
- b = l[
- # text
- :
- ]
24 + b = l.copy()
note: This is an unsafe fix and may change runtime behavior