mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-24 05:25:17 +00:00
Supported starred exceptions in length-one tuple detection (#7080)
This commit is contained in:
parent
b70dde4a77
commit
b0d171ac19
4 changed files with 49 additions and 17 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
retriable_exceptions = (FileExistsError, FileNotFoundError)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pass
|
pass
|
||||||
except (ValueError,):
|
except (ValueError,):
|
||||||
|
@ -6,3 +8,5 @@ except AttributeError:
|
||||||
pass
|
pass
|
||||||
except (ImportError, TypeError):
|
except (ImportError, TypeError):
|
||||||
pass
|
pass
|
||||||
|
except (*retriable_exceptions,):
|
||||||
|
pass
|
||||||
|
|
|
@ -2,6 +2,7 @@ use ruff_python_ast::{self as ast, ExceptHandler, Expr};
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
use ruff_python_ast::helpers::map_starred;
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
@ -41,11 +42,7 @@ pub struct RedundantTupleInExceptionHandler {
|
||||||
impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler {
|
impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler {
|
||||||
#[derive_message_formats]
|
#[derive_message_formats]
|
||||||
fn message(&self) -> String {
|
fn message(&self) -> String {
|
||||||
let RedundantTupleInExceptionHandler { name } = self;
|
format!("A length-one tuple literal is redundant in exception handlers")
|
||||||
format!(
|
|
||||||
"A length-one tuple literal is redundant. Write `except {name}` instead of `except \
|
|
||||||
({name},)`."
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn autofix_title(&self) -> String {
|
fn autofix_title(&self) -> String {
|
||||||
|
@ -70,9 +67,10 @@ pub(crate) fn redundant_tuple_in_exception_handler(
|
||||||
let Expr::Tuple(ast::ExprTuple { elts, .. }) = type_.as_ref() else {
|
let Expr::Tuple(ast::ExprTuple { elts, .. }) = type_.as_ref() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let [elt] = &elts[..] else {
|
let [elt] = elts.as_slice() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
let elt = map_starred(elt);
|
||||||
let mut diagnostic = Diagnostic::new(
|
let mut diagnostic = Diagnostic::new(
|
||||||
RedundantTupleInExceptionHandler {
|
RedundantTupleInExceptionHandler {
|
||||||
name: checker.generator().expr(elt),
|
name: checker.generator().expr(elt),
|
||||||
|
|
|
@ -1,24 +1,43 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff/src/rules/flake8_bugbear/mod.rs
|
source: crates/ruff/src/rules/flake8_bugbear/mod.rs
|
||||||
---
|
---
|
||||||
B013.py:3:8: B013 [*] A length-one tuple literal is redundant. Write `except ValueError` instead of `except (ValueError,)`.
|
B013.py:5:8: B013 [*] A length-one tuple literal is redundant in exception handlers
|
||||||
|
|
|
|
||||||
1 | try:
|
3 | try:
|
||||||
2 | pass
|
|
||||||
3 | except (ValueError,):
|
|
||||||
| ^^^^^^^^^^^^^ B013
|
|
||||||
4 | pass
|
4 | pass
|
||||||
5 | except AttributeError:
|
5 | except (ValueError,):
|
||||||
|
| ^^^^^^^^^^^^^ B013
|
||||||
|
6 | pass
|
||||||
|
7 | except AttributeError:
|
||||||
|
|
|
|
||||||
= help: Replace with `except ValueError`
|
= help: Replace with `except ValueError`
|
||||||
|
|
||||||
ℹ Fix
|
ℹ Fix
|
||||||
1 1 | try:
|
2 2 |
|
||||||
2 2 | pass
|
3 3 | try:
|
||||||
3 |-except (ValueError,):
|
|
||||||
3 |+except ValueError:
|
|
||||||
4 4 | pass
|
4 4 | pass
|
||||||
5 5 | except AttributeError:
|
5 |-except (ValueError,):
|
||||||
|
5 |+except ValueError:
|
||||||
6 6 | pass
|
6 6 | pass
|
||||||
|
7 7 | except AttributeError:
|
||||||
|
8 8 | pass
|
||||||
|
|
||||||
|
B013.py:11:8: B013 [*] A length-one tuple literal is redundant in exception handlers
|
||||||
|
|
|
||||||
|
9 | except (ImportError, TypeError):
|
||||||
|
10 | pass
|
||||||
|
11 | except (*retriable_exceptions,):
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^ B013
|
||||||
|
12 | pass
|
||||||
|
|
|
||||||
|
= help: Replace with `except retriable_exceptions`
|
||||||
|
|
||||||
|
ℹ Fix
|
||||||
|
8 8 | pass
|
||||||
|
9 9 | except (ImportError, TypeError):
|
||||||
|
10 10 | pass
|
||||||
|
11 |-except (*retriable_exceptions,):
|
||||||
|
11 |+except retriable_exceptions:
|
||||||
|
12 12 | pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -653,6 +653,17 @@ pub fn map_subscript(expr: &Expr) -> &Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Given an [`Expr`] that can be starred, return the underlying starred expression.
|
||||||
|
pub fn map_starred(expr: &Expr) -> &Expr {
|
||||||
|
if let Expr::Starred(ast::ExprStarred { value, .. }) = expr {
|
||||||
|
// Ex) `*args`
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
// Ex) `args`
|
||||||
|
expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Return `true` if the body uses `locals()`, `globals()`, `vars()`, `eval()`.
|
/// Return `true` if the body uses `locals()`, `globals()`, `vars()`, `eval()`.
|
||||||
///
|
///
|
||||||
/// Accepts a closure that determines whether a given name (e.g., `"list"`) is a Python builtin.
|
/// Accepts a closure that determines whether a given name (e.g., `"list"`) is a Python builtin.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue