Modify parsing of raise with cause when exception is absent (#15049)

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.
This commit is contained in:
Dylan 2024-12-19 07:36:32 -06:00 committed by GitHub
parent 3bb0dac235
commit c1eaf6ff72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 93 additions and 21 deletions

View file

@ -0,0 +1,2 @@
raise from exc
raise from None

View file

@ -411,9 +411,21 @@ impl<'src> Parser<'src> {
let start = self.node_start(); let start = self.node_start();
self.bump(TokenKind::Raise); self.bump(TokenKind::Raise);
let exc = if self.at(TokenKind::Newline) { 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 None
} else { }
_ => {
// test_err raise_stmt_invalid_exc // test_err raise_stmt_invalid_exc
// raise *x // raise *x
// raise yield x // raise yield x
@ -433,9 +445,10 @@ impl<'src> Parser<'src> {
} }
Some(Box::new(exc.expr)) 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 // test_err raise_stmt_invalid_cause
// raise x from *y // raise x from *y
// raise x from yield y // raise x from yield y

View file

@ -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
|