diff --git a/crates/ruff_diagnostics/src/fix.rs b/crates/ruff_diagnostics/src/fix.rs index 751258508f718..2db9d799fe35b 100644 --- a/crates/ruff_diagnostics/src/fix.rs +++ b/crates/ruff_diagnostics/src/fix.rs @@ -11,15 +11,21 @@ use crate::edit::Edit; #[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))] pub enum Applicability { /// The fix is unsafe and should only be displayed for manual application by the user. + /// /// The fix is likely to be incorrect or the resulting code may have invalid syntax. DisplayOnly, /// The fix is unsafe and should only be applied with user opt-in. - /// The fix may be what the user intended, but it is uncertain; the resulting code will have valid syntax. + /// + /// The fix may be what the user intended, but it is uncertain. The resulting code will have + /// valid syntax, but may lead to a change in runtime behavior, the removal of user comments, + /// or both. Unsafe, /// The fix is safe and can always be applied. - /// The fix is definitely what the user intended, or it maintains the exact meaning of the code. + /// + /// The fix is definitely what the user intended, or maintains the exact meaning of the code. + /// User comments are preserved, unless the fix removes an entire statement or expression. Safe, } diff --git a/docs/linter.md b/docs/linter.md index 66e90bc83a8d7..c307bdbacabc4 100644 --- a/docs/linter.md +++ b/docs/linter.md @@ -161,7 +161,11 @@ whether a rule supports fixing, see [_Rules_](rules.md). ### Fix safety Ruff labels fixes as "safe" and "unsafe". The meaning and intent of your code will be retained when -applying safe fixes, but the meaning could be changed when applying unsafe fixes. +applying safe fixes, but the meaning could change when applying unsafe fixes. + +Specifically, an unsafe fix could lead to a change in runtime behavior, the removal of comments, or both, +while safe fixes are intended to preserve runtime behavior and will only remove comments when deleting +entire statements or expressions (e.g., removing unused imports). For example, [`unnecessary-iterable-allocation-for-first-element`](rules/unnecessary-iterable-allocation-for-first-element.md) (`RUF015`) is a rule which checks for potentially unperformant use of `list(...)[0]`. The fix @@ -177,7 +181,7 @@ $ python -m timeit "head = next(iter(range(99999999)))" 5000000 loops, best of 5: 70.8 nsec per loop ``` -However, when the collection is empty, this changes the raised exception from an `IndexError` to `StopIteration`: +However, when the collection is empty, this raised exception changes from an `IndexError` to `StopIteration`: ```console $ python -c 'list(range(0))[0]' @@ -193,7 +197,7 @@ Traceback (most recent call last): StopIteration ``` -Since this could break error handling, this fix is categorized as unsafe. +Since the change in exception type could break error handling upstream, this fix is categorized as unsafe. Ruff only enables safe fixes by default. Unsafe fixes can be enabled by settings [`unsafe-fixes`](settings.md#unsafe-fixes) in your configuration file or passing the `--unsafe-fixes` flag to `ruff check`: