mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 18:58:04 +00:00
[ruff
] add fix safety section (RUF007
) (#17755)
The PR add the `fix safety` section for rule `RUF007` (#15584 ) It seems that the fix was always marked as unsafe #14401 ## Unsafety example This first example is a little extreme. In fact, the class `Foo` overrides the `__getitem__` method but in a very special, way. The difference lies in the fact that `zip(letters, letters[1:])` call the slice `letters[1:]` which is behaving weird in this case, while `itertools.pairwise(letters)` call just `__getitem__(0), __getitem__(1), ...` and so on. Note that the diagnostic is emitted: [playground](https://play.ruff.rs) I don't know if we want to mention this problem, as there is a subtile bug in the python implementation of `Foo` which make the rule unsafe. ```python from dataclasses import dataclass import itertools @dataclass class Foo: letters: str def __getitem__(self, index): return self.letters[index] + "_foo" letters = Foo("ABCD") zip_ = zip(letters, letters[1:]) for a, b in zip_: print(a, b) # A_foo B, B_foo C, C_foo D, D_foo _ pair = itertools.pairwise(letters) for a, b in pair: print(a, b) # A_foo B_foo, B_foo C_foo, C_foo D_foo ``` This other example is much probable. here, `itertools.pairwise` was shadowed by a costume function [(playground)](https://play.ruff.rs) ```python from dataclasses import dataclass from itertools import pairwise def pairwise(a): return [] letters = "ABCD" zip_ = zip(letters, letters[1:]) print([(a, b) for a, b in zip_]) # [('A', 'B'), ('B', 'C'), ('C', 'D')] pair = pairwise(letters) print(pair) # [] ```
This commit is contained in:
parent
1b4f7de840
commit
1e4377c9c6
1 changed files with 8 additions and 0 deletions
|
@ -29,6 +29,14 @@ use crate::{checkers::ast::Checker, importer::ImportRequest};
|
|||
/// pairwise(letters) # ("A", "B"), ("B", "C"), ("C", "D")
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
///
|
||||
/// The fix is always marked unsafe because it assumes that slicing an object
|
||||
/// (e.g., `obj[1:]`) produces a value with the same type and iteration behavior
|
||||
/// as the original object, which is not guaranteed for user-defined types that
|
||||
/// override `__getitem__` without properly handling slices. Moreover, the fix
|
||||
/// could delete comments.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `itertools.pairwise`](https://docs.python.org/3/library/itertools.html#itertools.pairwise)
|
||||
#[derive(ViolationMetadata)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue