mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-30 13:51:16 +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:
|
except Exception as e:
|
||||||
raise ValueError from e
|
raise ValueError from e
|
||||||
|
|
||||||
|
try:
|
||||||
|
...
|
||||||
|
except Exception as e:
|
||||||
|
raise e from ValueError("hello")
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pass
|
pass
|
||||||
|
@ -245,3 +250,9 @@ try:
|
||||||
pass
|
pass
|
||||||
except (Exception, ValueError) as e:
|
except (Exception, ValueError) as e:
|
||||||
raise 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
|
/// ## What it does
|
||||||
/// Checks for `except` clauses that catch all exceptions. This includes
|
/// 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?
|
/// ## Why is this bad?
|
||||||
|
@ -149,26 +149,30 @@ impl<'a> ReraiseVisitor<'a> {
|
||||||
|
|
||||||
impl<'a> StatementVisitor<'a> for ReraiseVisitor<'a> {
|
impl<'a> StatementVisitor<'a> for ReraiseVisitor<'a> {
|
||||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||||
|
if self.seen {
|
||||||
|
return;
|
||||||
|
}
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Raise(ast::StmtRaise { exc, cause, .. }) => {
|
Stmt::Raise(ast::StmtRaise { exc, cause, .. }) => {
|
||||||
if let Some(cause) = cause {
|
// except Exception [as <name>]:
|
||||||
if let Expr::Name(ast::ExprName { id, .. }) = cause.as_ref() {
|
// raise [<exc> [from <cause>]]
|
||||||
if self.name.is_some_and(|name| id == name) {
|
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
|
||||||
|
}
|
||||||
|
// `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;
|
self.seen = 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Stmt::Try(_) | Stmt::FunctionDef(_) | Stmt::ClassDef(_) => {}
|
Stmt::Try(_) | Stmt::FunctionDef(_) | Stmt::ClassDef(_) => {}
|
||||||
_ => walk_stmt(self, stmt),
|
_ => walk_stmt(self, stmt),
|
||||||
}
|
}
|
||||||
|
@ -200,6 +204,9 @@ impl<'a> LogExceptionVisitor<'a> {
|
||||||
|
|
||||||
impl<'a> StatementVisitor<'a> for LogExceptionVisitor<'a> {
|
impl<'a> StatementVisitor<'a> for LogExceptionVisitor<'a> {
|
||||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||||
|
if self.seen {
|
||||||
|
return;
|
||||||
|
}
|
||||||
match stmt {
|
match stmt {
|
||||||
Stmt::Expr(ast::StmtExpr { value, .. }) => {
|
Stmt::Expr(ast::StmtExpr { value, .. }) => {
|
||||||
if let Expr::Call(ast::ExprCall {
|
if let Expr::Call(ast::ExprCall {
|
||||||
|
|
|
@ -164,32 +164,22 @@ BLE001 Do not catch blind exception: `Exception`
|
||||||
132 | critical("...", exc_info=None)
|
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`
|
BLE001 Do not catch blind exception: `Exception`
|
||||||
--> BLE.py:174:9
|
--> BLE.py:174:9
|
||||||
|
|
|
|
||||||
172 | try:
|
172 | try:
|
||||||
173 | pass
|
173 | pass
|
||||||
174 | except (Exception, ValueError):
|
174 | except (Exception,):
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
175 | pass
|
175 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
BLE001 Do not catch blind exception: `Exception`
|
BLE001 Do not catch blind exception: `Exception`
|
||||||
--> BLE.py:179:21
|
--> BLE.py:179:9
|
||||||
|
|
|
|
||||||
177 | try:
|
177 | try:
|
||||||
178 | pass
|
178 | pass
|
||||||
179 | except (ValueError, Exception):
|
179 | except (Exception, ValueError):
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
180 | pass
|
180 | pass
|
||||||
|
|
|
|
||||||
|
@ -199,67 +189,77 @@ BLE001 Do not catch blind exception: `Exception`
|
||||||
|
|
|
|
||||||
182 | try:
|
182 | try:
|
||||||
183 | pass
|
183 | pass
|
||||||
184 | except (ValueError, Exception) as e:
|
184 | except (ValueError, Exception):
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
185 | print(e)
|
185 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
BLE001 Do not catch blind exception: `BaseException`
|
BLE001 Do not catch blind exception: `Exception`
|
||||||
--> BLE.py:189:9
|
--> BLE.py:189:21
|
||||||
|
|
|
|
||||||
187 | try:
|
187 | try:
|
||||||
188 | pass
|
188 | pass
|
||||||
189 | except (BaseException, TypeError):
|
189 | except (ValueError, Exception) as e:
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
190 | pass
|
190 | print(e)
|
||||||
|
|
|
|
||||||
|
|
||||||
BLE001 Do not catch blind exception: `BaseException`
|
BLE001 Do not catch blind exception: `BaseException`
|
||||||
--> BLE.py:194:20
|
--> BLE.py:194:9
|
||||||
|
|
|
|
||||||
192 | try:
|
192 | try:
|
||||||
193 | pass
|
193 | pass
|
||||||
194 | except (TypeError, BaseException):
|
194 | except (BaseException, TypeError):
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
195 | pass
|
195 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
BLE001 Do not catch blind exception: `Exception`
|
BLE001 Do not catch blind exception: `BaseException`
|
||||||
--> BLE.py:199:9
|
--> BLE.py:199:20
|
||||||
|
|
|
|
||||||
197 | try:
|
197 | try:
|
||||||
198 | pass
|
198 | pass
|
||||||
199 | except (Exception, BaseException):
|
199 | except (TypeError, BaseException):
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
200 | pass
|
200 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
BLE001 Do not catch blind exception: `BaseException`
|
BLE001 Do not catch blind exception: `Exception`
|
||||||
--> BLE.py:204:9
|
--> BLE.py:204:9
|
||||||
|
|
|
|
||||||
202 | try:
|
202 | try:
|
||||||
203 | pass
|
203 | pass
|
||||||
204 | except (BaseException, Exception):
|
204 | except (Exception, BaseException):
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
205 | pass
|
205 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
BLE001 Do not catch blind exception: `Exception`
|
BLE001 Do not catch blind exception: `BaseException`
|
||||||
--> BLE.py:210:10
|
--> BLE.py:209:9
|
||||||
|
|
|
|
||||||
208 | try:
|
207 | try:
|
||||||
209 | pass
|
208 | pass
|
||||||
210 | except ((Exception, ValueError), TypeError):
|
209 | except (BaseException, Exception):
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
211 | pass
|
210 | pass
|
||||||
|
|
|
|
||||||
|
|
||||||
BLE001 Do not catch blind exception: `BaseException`
|
BLE001 Do not catch blind exception: `Exception`
|
||||||
--> BLE.py:215:22
|
--> BLE.py:215:10
|
||||||
|
|
|
|
||||||
213 | try:
|
213 | try:
|
||||||
214 | pass
|
214 | pass
|
||||||
215 | except (ValueError, (BaseException, TypeError)):
|
215 | except ((Exception, ValueError), TypeError):
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
216 | pass
|
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