Skip to content

Commit

Permalink
Modify parsing of raise with cause when exception is absent (#15049)
Browse files Browse the repository at this point in the history
When confronted with `raise from exc` the parser will now create a
`StmtRaise` that has `None` for the exception and `exc` for the cause.

Before, the parser created a `StmtRaise` with `from` for the exception,
no cause, and a spurious expression `exc` afterwards.
  • Loading branch information
dylwil3 authored Dec 19, 2024
1 parent 3bb0dac commit c1eaf6f
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
raise from exc
raise from None
55 changes: 34 additions & 21 deletions crates/ruff_python_parser/src/parser/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,31 +411,44 @@ impl<'src> Parser<'src> {
let start = self.node_start();
self.bump(TokenKind::Raise);

let exc = if self.at(TokenKind::Newline) {
None
} else {
// test_err raise_stmt_invalid_exc
// raise *x
// raise yield x
// raise x := 1
let exc = self.parse_expression_list(ExpressionContext::default());

if let Some(ast::ExprTuple {
parenthesized: false,
..
}) = exc.as_tuple_expr()
{
// test_err raise_stmt_unparenthesized_tuple_exc
// raise x,
// raise x, y
// raise x, y from z
self.add_error(ParseErrorType::UnparenthesizedTupleExpression, &exc);
let exc = match self.current_token_kind() {
TokenKind::Newline => None,
TokenKind::From => {
// test_err raise_stmt_from_without_exc
// raise from exc
// raise from None
self.add_error(
ParseErrorType::OtherError(
"Exception missing in `raise` statement with cause".to_string(),
),
self.current_token_range(),
);
None
}
_ => {
// test_err raise_stmt_invalid_exc
// raise *x
// raise yield x
// raise x := 1
let exc = self.parse_expression_list(ExpressionContext::default());

Some(Box::new(exc.expr))
if let Some(ast::ExprTuple {
parenthesized: false,
..
}) = exc.as_tuple_expr()
{
// test_err raise_stmt_unparenthesized_tuple_exc
// raise x,
// raise x, y
// raise x, y from z
self.add_error(ParseErrorType::UnparenthesizedTupleExpression, &exc);
}

Some(Box::new(exc.expr))
}
};

let cause = (exc.is_some() && self.eat(TokenKind::From)).then(|| {
let cause = self.eat(TokenKind::From).then(|| {
// test_err raise_stmt_invalid_cause
// raise x from *y
// raise x from yield y
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
source: crates/ruff_python_parser/tests/fixtures.rs
input_file: crates/ruff_python_parser/resources/inline/err/raise_stmt_from_without_exc.py
---
## AST

```
Module(
ModModule {
range: 0..31,
body: [
Raise(
StmtRaise {
range: 0..14,
exc: None,
cause: Some(
Name(
ExprName {
range: 11..14,
id: Name("exc"),
ctx: Load,
},
),
),
},
),
Raise(
StmtRaise {
range: 15..30,
exc: None,
cause: Some(
NoneLiteral(
ExprNoneLiteral {
range: 26..30,
},
),
),
},
),
],
},
)
```
## Errors

|
1 | raise from exc
| ^^^^ Syntax Error: Exception missing in `raise` statement with cause
2 | raise from None
|


|
1 | raise from exc
2 | raise from None
| ^^^^ Syntax Error: Exception missing in `raise` statement with cause
|

0 comments on commit c1eaf6f

Please sign in to comment.