Skip to content

Commit df0648a

Browse files
authored
[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
1 parent f0b03c3 commit df0648a

File tree

3 files changed

+74
-56
lines changed

3 files changed

+74
-56
lines changed

crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,11 @@
154154
except Exception as e:
155155
raise ValueError from e
156156

157+
try:
158+
...
159+
except Exception as e:
160+
raise e from ValueError("hello")
161+
157162

158163
try:
159164
pass
@@ -245,3 +250,9 @@
245250
pass
246251
except (Exception, ValueError) as e:
247252
raise e
253+
254+
# `from None` cause
255+
try:
256+
pass
257+
except BaseException as e:
258+
raise e from None

crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::checkers::ast::Checker;
1111

1212
/// ## What it does
1313
/// Checks for `except` clauses that catch all exceptions. This includes
14-
/// bare `except`, `except BaseException` and `except Exception`.
14+
/// `except BaseException` and `except Exception`.
1515
///
1616
///
1717
/// ## Why is this bad?
@@ -149,24 +149,28 @@ impl<'a> ReraiseVisitor<'a> {
149149

150150
impl<'a> StatementVisitor<'a> for ReraiseVisitor<'a> {
151151
fn visit_stmt(&mut self, stmt: &'a Stmt) {
152+
if self.seen {
153+
return;
154+
}
152155
match stmt {
153156
Stmt::Raise(ast::StmtRaise { exc, cause, .. }) => {
154-
if let Some(cause) = cause {
155-
if let Expr::Name(ast::ExprName { id, .. }) = cause.as_ref() {
156-
if self.name.is_some_and(|name| id == name) {
157-
self.seen = true;
158-
}
157+
// except Exception [as <name>]:
158+
// raise [<exc> [from <cause>]]
159+
let reraised = match (self.name, exc.as_deref(), cause.as_deref()) {
160+
// `raise`
161+
(_, None, None) => true,
162+
// `raise SomeExc from <name>`
163+
(Some(name), _, Some(Expr::Name(ast::ExprName { id, .. }))) if name == id => {
164+
true
159165
}
160-
} else {
161-
if let Some(exc) = exc {
162-
if let Expr::Name(ast::ExprName { id, .. }) = exc.as_ref() {
163-
if self.name.is_some_and(|name| id == name) {
164-
self.seen = true;
165-
}
166-
}
167-
} else {
168-
self.seen = true;
166+
// `raise <name>` and `raise <name> from SomeCause`
167+
(Some(name), Some(Expr::Name(ast::ExprName { id, .. })), _) if name == id => {
168+
true
169169
}
170+
_ => false,
171+
};
172+
if reraised {
173+
self.seen = true;
170174
}
171175
}
172176
Stmt::Try(_) | Stmt::FunctionDef(_) | Stmt::ClassDef(_) => {}
@@ -200,6 +204,9 @@ impl<'a> LogExceptionVisitor<'a> {
200204

201205
impl<'a> StatementVisitor<'a> for LogExceptionVisitor<'a> {
202206
fn visit_stmt(&mut self, stmt: &'a Stmt) {
207+
if self.seen {
208+
return;
209+
}
203210
match stmt {
204211
Stmt::Expr(ast::StmtExpr { value, .. }) => {
205212
if let Expr::Call(ast::ExprCall {

crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -164,33 +164,23 @@ BLE001 Do not catch blind exception: `Exception`
164164
132 | critical("...", exc_info=None)
165165
|
166166

167-
BLE001 Do not catch blind exception: `Exception`
168-
--> BLE.py:169:9
169-
|
170-
167 | try:
171-
168 | pass
172-
169 | except (Exception,):
173-
| ^^^^^^^^^
174-
170 | pass
175-
|
176-
177167
BLE001 Do not catch blind exception: `Exception`
178168
--> BLE.py:174:9
179169
|
180170
172 | try:
181171
173 | pass
182-
174 | except (Exception, ValueError):
172+
174 | except (Exception,):
183173
| ^^^^^^^^^
184174
175 | pass
185175
|
186176

187177
BLE001 Do not catch blind exception: `Exception`
188-
--> BLE.py:179:21
178+
--> BLE.py:179:9
189179
|
190180
177 | try:
191181
178 | pass
192-
179 | except (ValueError, Exception):
193-
| ^^^^^^^^^
182+
179 | except (Exception, ValueError):
183+
| ^^^^^^^^^
194184
180 | pass
195185
|
196186

@@ -199,67 +189,77 @@ BLE001 Do not catch blind exception: `Exception`
199189
|
200190
182 | try:
201191
183 | pass
202-
184 | except (ValueError, Exception) as e:
192+
184 | except (ValueError, Exception):
203193
| ^^^^^^^^^
204-
185 | print(e)
194+
185 | pass
205195
|
206196

207-
BLE001 Do not catch blind exception: `BaseException`
208-
--> BLE.py:189:9
197+
BLE001 Do not catch blind exception: `Exception`
198+
--> BLE.py:189:21
209199
|
210200
187 | try:
211201
188 | pass
212-
189 | except (BaseException, TypeError):
213-
| ^^^^^^^^^^^^^
214-
190 | pass
202+
189 | except (ValueError, Exception) as e:
203+
| ^^^^^^^^^
204+
190 | print(e)
215205
|
216206

217207
BLE001 Do not catch blind exception: `BaseException`
218-
--> BLE.py:194:20
208+
--> BLE.py:194:9
219209
|
220210
192 | try:
221211
193 | pass
222-
194 | except (TypeError, BaseException):
223-
| ^^^^^^^^^^^^^
212+
194 | except (BaseException, TypeError):
213+
| ^^^^^^^^^^^^^
224214
195 | pass
225215
|
226216

227-
BLE001 Do not catch blind exception: `Exception`
228-
--> BLE.py:199:9
217+
BLE001 Do not catch blind exception: `BaseException`
218+
--> BLE.py:199:20
229219
|
230220
197 | try:
231221
198 | pass
232-
199 | except (Exception, BaseException):
233-
| ^^^^^^^^^
222+
199 | except (TypeError, BaseException):
223+
| ^^^^^^^^^^^^^
234224
200 | pass
235225
|
236226

237-
BLE001 Do not catch blind exception: `BaseException`
227+
BLE001 Do not catch blind exception: `Exception`
238228
--> BLE.py:204:9
239229
|
240230
202 | try:
241231
203 | pass
242-
204 | except (BaseException, Exception):
243-
| ^^^^^^^^^^^^^
232+
204 | except (Exception, BaseException):
233+
| ^^^^^^^^^
244234
205 | pass
245235
|
246236

237+
BLE001 Do not catch blind exception: `BaseException`
238+
--> BLE.py:209:9
239+
|
240+
207 | try:
241+
208 | pass
242+
209 | except (BaseException, Exception):
243+
| ^^^^^^^^^^^^^
244+
210 | pass
245+
|
246+
247247
BLE001 Do not catch blind exception: `Exception`
248-
--> BLE.py:210:10
248+
--> BLE.py:215:10
249249
|
250-
208 | try:
251-
209 | pass
252-
210 | except ((Exception, ValueError), TypeError):
250+
213 | try:
251+
214 | pass
252+
215 | except ((Exception, ValueError), TypeError):
253253
| ^^^^^^^^^
254-
211 | pass
254+
216 | pass
255255
|
256256

257257
BLE001 Do not catch blind exception: `BaseException`
258-
--> BLE.py:215:22
258+
--> BLE.py:220:22
259259
|
260-
213 | try:
261-
214 | pass
262-
215 | except (ValueError, (BaseException, TypeError)):
260+
218 | try:
261+
219 | pass
262+
220 | except (ValueError, (BaseException, TypeError)):
263263
| ^^^^^^^^^^^^^
264-
216 | pass
264+
221 | pass
265265
|

0 commit comments

Comments
 (0)