mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-03 18:28:56 +00:00
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:
parent
3bb0dac235
commit
c1eaf6ff72
3 changed files with 93 additions and 21 deletions
|
@ -0,0 +1,2 @@
|
|||
raise from exc
|
||||
raise from None
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue