Raise syntax error for mixing except and except* (#14895)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions

This PR adds a syntax error if the parser encounters a `TryStmt` that
has except clauses both with and without a star.

The displayed error points to each except clause that contradicts the
original except clause kind. So, for example,

```python
try:
    ....
except:     #<-- we assume this is the desired except kind
    ....
except*:    #<---  error will point here
    ....
except*:    #<--- and here
    ....
```

Closes #14860
This commit is contained in:
Dylan 2024-12-10 17:50:55 -06:00 committed by GitHub
parent d4126f6049
commit a3bb0cd5ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 301 additions and 4 deletions

View file

@ -1332,14 +1332,12 @@ impl<'src> Parser<'src> {
self.bump(TokenKind::Try);
self.expect(TokenKind::Colon);
let mut is_star = false;
let mut is_star: Option<bool> = None;
let try_body = self.parse_body(Clause::Try);
let has_except = self.at(TokenKind::Except);
// TODO(dhruvmanila): Raise syntax error if there are both 'except' and 'except*'
// on the same 'try'
// test_err try_stmt_mixed_except_kind
// try:
// pass
@ -1353,11 +1351,36 @@ impl<'src> Parser<'src> {
// pass
// except:
// pass
// try:
// pass
// except:
// pass
// except:
// pass
// except* ExceptionGroup:
// pass
// except* ExceptionGroup:
// pass
let mut mixed_except_ranges = Vec::new();
let handlers = self.parse_clauses(Clause::Except, |p| {
let (handler, kind) = p.parse_except_clause();
is_star |= kind.is_star();
if is_star.is_none() {
is_star = Some(kind.is_star());
} else if is_star != Some(kind.is_star()) {
mixed_except_ranges.push(handler.range());
}
handler
});
// Empty handler has `is_star` false.
let is_star = is_star.unwrap_or_default();
for handler_err_range in mixed_except_ranges {
self.add_error(
ParseErrorType::OtherError(
"Cannot have both 'except' and 'except*' on the same 'try'".to_string(),
),
handler_err_range,
);
}
// test_err try_stmt_misspelled_except
// try: