mirror of
https://github.com/astral-sh/ruff
synced 2026-01-22 05:51:03 -05:00
[flake8-bugbear] Make fix unsafe if it deletes comments (B014) (#22659)
<!-- 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:
@@ -88,3 +88,14 @@ try:
|
||||
pas
|
||||
except(re.error, re.error):
|
||||
p
|
||||
|
||||
|
||||
try:
|
||||
pass
|
||||
except (
|
||||
ValueError,
|
||||
ValueError,
|
||||
# text
|
||||
TypeError,
|
||||
):
|
||||
pass
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use ruff_diagnostics::Applicability;
|
||||
use ruff_macros::{ViolationMetadata, derive_message_formats};
|
||||
use ruff_python_ast::name::UnqualifiedName;
|
||||
use ruff_python_ast::{self as ast, ExceptHandler, Expr, ExprContext};
|
||||
use ruff_text_size::{Ranged, TextRange};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::fix::edits::pad;
|
||||
@@ -37,6 +37,9 @@ use crate::{Edit, Fix};
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as safe, unless the exception handler contains comments.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `except` clause](https://docs.python.org/3/reference/compound_stmts.html#except-clause)
|
||||
#[derive(ViolationMetadata)]
|
||||
@@ -154,22 +157,32 @@ fn duplicate_handler_exceptions<'a>(
|
||||
},
|
||||
expr.range(),
|
||||
);
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
// Single exceptions don't require parentheses, but since we're _removing_
|
||||
// parentheses, insert whitespace as needed.
|
||||
if let [elt] = unique_elts.as_slice() {
|
||||
pad(
|
||||
checker.generator().expr(elt),
|
||||
expr.range(),
|
||||
checker.locator(),
|
||||
)
|
||||
} else {
|
||||
// Multiple exceptions must always be parenthesized. This is done
|
||||
// manually as the generator never parenthesizes lone tuples.
|
||||
format!("({})", checker.generator().expr(&type_pattern(unique_elts)))
|
||||
},
|
||||
expr.range(),
|
||||
)));
|
||||
|
||||
let applicability = if checker.comment_ranges().intersects(expr.range()) {
|
||||
Applicability::Unsafe
|
||||
} else {
|
||||
Applicability::Safe
|
||||
};
|
||||
|
||||
diagnostic.set_fix(Fix::applicable_edit(
|
||||
Edit::range_replacement(
|
||||
// Single exceptions don't require parentheses, but since we're _removing_
|
||||
// parentheses, insert whitespace as needed.
|
||||
if let [elt] = unique_elts.as_slice() {
|
||||
pad(
|
||||
checker.generator().expr(elt),
|
||||
expr.range(),
|
||||
checker.locator(),
|
||||
)
|
||||
} else {
|
||||
// Multiple exceptions must always be parenthesized. This is done
|
||||
// manually as the generator never parenthesizes lone tuples.
|
||||
format!("({})", checker.generator().expr(&type_pattern(unique_elts)))
|
||||
},
|
||||
expr.range(),
|
||||
),
|
||||
applicability,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,3 +96,34 @@ help: De-duplicate exceptions
|
||||
- except(re.error, re.error):
|
||||
89 + except re.error:
|
||||
90 | p
|
||||
91 |
|
||||
92 |
|
||||
|
||||
B014 [*] Exception handler with duplicate exception: `ValueError`
|
||||
--> B014.py:95:8
|
||||
|
|
||||
93 | try:
|
||||
94 | pass
|
||||
95 | except (
|
||||
| ________^
|
||||
96 | | ValueError,
|
||||
97 | | ValueError,
|
||||
98 | | # text
|
||||
99 | | TypeError,
|
||||
100 | | ):
|
||||
| |_^
|
||||
101 | pass
|
||||
|
|
||||
help: De-duplicate exceptions
|
||||
92 |
|
||||
93 | try:
|
||||
94 | pass
|
||||
- except (
|
||||
- ValueError,
|
||||
- ValueError,
|
||||
- # text
|
||||
- TypeError,
|
||||
- ):
|
||||
95 + except (ValueError, TypeError):
|
||||
96 | pass
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
Reference in New Issue
Block a user