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

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