diff --git a/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py b/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py index 32c0dc87e2..f16c7f7e61 100644 --- a/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py +++ b/crates/ruff_linter/resources/test/fixtures/flake8_blind_except/BLE.py @@ -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 diff --git a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs index 6698873eb7..ac512dee04 100644 --- a/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs +++ b/crates/ruff_linter/src/rules/flake8_blind_except/rules/blind_except.rs @@ -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 ]: + // raise [ [from ]] + let reraised = match (self.name, exc.as_deref(), cause.as_deref()) { + // `raise` + (_, None, None) => true, + // `raise SomeExc from ` + (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 ` and `raise 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 { diff --git a/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap b/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap index 9c4b219a3b..1924cd03aa 100644 --- a/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap +++ b/crates/ruff_linter/src/rules/flake8_blind_except/snapshots/ruff_linter__rules__flake8_blind_except__tests__BLE001_BLE.py.snap @@ -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 + |