mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-29 13:24:57 +00:00
[flake8-blind-except
] Fix BLE001
false-positive on raise ... from None
(#19755)
## Summary - Refactored `BLE001` logic for clarity and minor speed-up. - Improved documentation and comments (previously, `BLE001` docs claimed it catches bare `except:`s, but it doesn't). - Fixed a false-positive bug with `from None` cause: ```python # somefile.py try: pass except BaseException as e: raise e from None ``` ### main branch ``` somefile.py:3:8: BLE001 Do not catch blind exception: `BaseException` | 1 | try: 2 | pass 3 | except BaseException as e: | ^^^^^^^^^^^^^ BLE001 4 | raise e from None | Found 1 error. ``` ### this change ```cargo run -p ruff -- check somefile.py --no-cache --select=BLE001``` ``` All checks passed! ``` ## Test Plan - Added a test case to cover `raise X from Y` clause - Added a test case to cover `raise X from None` clause
This commit is contained in:
parent
f0b03c3e86
commit
df0648aae0
3 changed files with 88 additions and 70 deletions
|
@ -154,6 +154,11 @@ try:
|
|||
except Exception as e:
|
||||
raise ValueError from e
|
||||
|
||||
try:
|
||||
...
|
||||
except Exception as e:
|
||||
raise e from ValueError("hello")
|
||||
|
||||
|
||||
try:
|
||||
pass
|
||||
|
@ -245,3 +250,9 @@ try:
|
|||
pass
|
||||
except (Exception, ValueError) as e:
|
||||
raise e
|
||||
|
||||
# `from None` cause
|
||||
try:
|
||||
pass
|
||||
except BaseException as e:
|
||||
raise e from None
|
||||
|
|
|
@ -11,7 +11,7 @@ use crate::checkers::ast::Checker;
|
|||
|
||||
/// ## What it does
|
||||
/// Checks for `except` clauses that catch all exceptions. This includes
|
||||
/// bare `except`, `except BaseException` and `except Exception`.
|
||||
/// `except BaseException` and `except Exception`.
|
||||
///
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
|
@ -149,24 +149,28 @@ impl<'a> ReraiseVisitor<'a> {
|
|||
|
||||
impl<'a> StatementVisitor<'a> for ReraiseVisitor<'a> {
|
||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||
if self.seen {
|
||||
return;
|
||||
}
|
||||
match stmt {
|
||||
Stmt::Raise(ast::StmtRaise { exc, cause, .. }) => {
|
||||
if let Some(cause) = cause {
|
||||
if let Expr::Name(ast::ExprName { id, .. }) = cause.as_ref() {
|
||||
if self.name.is_some_and(|name| id == name) {
|
||||
self.seen = true;
|
||||
}
|
||||
// except Exception [as <name>]:
|
||||
// raise [<exc> [from <cause>]]
|
||||
let reraised = match (self.name, exc.as_deref(), cause.as_deref()) {
|
||||
// `raise`
|
||||
(_, None, None) => true,
|
||||
// `raise SomeExc from <name>`
|
||||
(Some(name), _, Some(Expr::Name(ast::ExprName { id, .. }))) if name == id => {
|
||||
true
|
||||
}
|
||||
} else {
|
||||
if let Some(exc) = exc {
|
||||
if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() {
|
||||
if self.name.is_some_and(|name| id == name) {
|
||||
self.seen = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.seen = true;
|
||||
// `raise <name>` and `raise <name> from SomeCause`
|
||||
(Some(name), Some(Expr::Name(ast::ExprName { id, .. })), _) if name == id => {
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if reraised {
|
||||
self.seen = true;
|
||||
}
|
||||
}
|
||||
Stmt::Try(_) | Stmt::FunctionDef(_) | Stmt::ClassDef(_) => {}
|
||||
|
@ -200,6 +204,9 @@ impl<'a> LogExceptionVisitor<'a> {
|
|||
|
||||
impl<'a> StatementVisitor<'a> for LogExceptionVisitor<'a> {
|
||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||
if self.seen {
|
||||
return;
|
||||
}
|
||||
match stmt {
|
||||
Stmt::Expr(ast::StmtExpr { value, .. }) => {
|
||||
if let Expr::Call(ast::ExprCall {
|
||||
|
|
|
@ -164,33 +164,23 @@ BLE001 Do not catch blind exception: `Exception`
|
|||
132 | critical("...", exc_info=None)
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `Exception`
|
||||
--> BLE.py:169:9
|
||||
|
|
||||
167 | try:
|
||||
168 | pass
|
||||
169 | except (Exception,):
|
||||
| ^^^^^^^^^
|
||||
170 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `Exception`
|
||||
--> BLE.py:174:9
|
||||
|
|
||||
172 | try:
|
||||
173 | pass
|
||||
174 | except (Exception, ValueError):
|
||||
174 | except (Exception,):
|
||||
| ^^^^^^^^^
|
||||
175 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `Exception`
|
||||
--> BLE.py:179:21
|
||||
--> BLE.py:179:9
|
||||
|
|
||||
177 | try:
|
||||
178 | pass
|
||||
179 | except (ValueError, Exception):
|
||||
| ^^^^^^^^^
|
||||
179 | except (Exception, ValueError):
|
||||
| ^^^^^^^^^
|
||||
180 | pass
|
||||
|
|
||||
|
||||
|
@ -199,67 +189,77 @@ BLE001 Do not catch blind exception: `Exception`
|
|||
|
|
||||
182 | try:
|
||||
183 | pass
|
||||
184 | except (ValueError, Exception) as e:
|
||||
184 | except (ValueError, Exception):
|
||||
| ^^^^^^^^^
|
||||
185 | print(e)
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `BaseException`
|
||||
--> BLE.py:189:9
|
||||
|
|
||||
187 | try:
|
||||
188 | pass
|
||||
189 | except (BaseException, TypeError):
|
||||
| ^^^^^^^^^^^^^
|
||||
190 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `BaseException`
|
||||
--> BLE.py:194:20
|
||||
|
|
||||
192 | try:
|
||||
193 | pass
|
||||
194 | except (TypeError, BaseException):
|
||||
| ^^^^^^^^^^^^^
|
||||
195 | pass
|
||||
185 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `Exception`
|
||||
--> BLE.py:199:9
|
||||
--> BLE.py:189:21
|
||||
|
|
||||
197 | try:
|
||||
198 | pass
|
||||
199 | except (Exception, BaseException):
|
||||
| ^^^^^^^^^
|
||||
200 | pass
|
||||
187 | try:
|
||||
188 | pass
|
||||
189 | except (ValueError, Exception) as e:
|
||||
| ^^^^^^^^^
|
||||
190 | print(e)
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `BaseException`
|
||||
--> BLE.py:194:9
|
||||
|
|
||||
192 | try:
|
||||
193 | pass
|
||||
194 | except (BaseException, TypeError):
|
||||
| ^^^^^^^^^^^^^
|
||||
195 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `BaseException`
|
||||
--> BLE.py:199:20
|
||||
|
|
||||
197 | try:
|
||||
198 | pass
|
||||
199 | except (TypeError, BaseException):
|
||||
| ^^^^^^^^^^^^^
|
||||
200 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `Exception`
|
||||
--> BLE.py:204:9
|
||||
|
|
||||
202 | try:
|
||||
203 | pass
|
||||
204 | except (BaseException, Exception):
|
||||
| ^^^^^^^^^^^^^
|
||||
204 | except (Exception, BaseException):
|
||||
| ^^^^^^^^^
|
||||
205 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `Exception`
|
||||
--> BLE.py:210:10
|
||||
BLE001 Do not catch blind exception: `BaseException`
|
||||
--> BLE.py:209:9
|
||||
|
|
||||
208 | try:
|
||||
209 | pass
|
||||
210 | except ((Exception, ValueError), TypeError):
|
||||
| ^^^^^^^^^
|
||||
211 | pass
|
||||
207 | try:
|
||||
208 | pass
|
||||
209 | except (BaseException, Exception):
|
||||
| ^^^^^^^^^^^^^
|
||||
210 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `BaseException`
|
||||
--> BLE.py:215:22
|
||||
BLE001 Do not catch blind exception: `Exception`
|
||||
--> BLE.py:215:10
|
||||
|
|
||||
213 | try:
|
||||
214 | pass
|
||||
215 | except (ValueError, (BaseException, TypeError)):
|
||||
| ^^^^^^^^^^^^^
|
||||
215 | except ((Exception, ValueError), TypeError):
|
||||
| ^^^^^^^^^
|
||||
216 | pass
|
||||
|
|
||||
|
||||
BLE001 Do not catch blind exception: `BaseException`
|
||||
--> BLE.py:220:22
|
||||
|
|
||||
218 | try:
|
||||
219 | pass
|
||||
220 | except (ValueError, (BaseException, TypeError)):
|
||||
| ^^^^^^^^^^^^^
|
||||
221 | pass
|
||||
|
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue