Skip to content

Commit c7ed645

Browse files
charliermarshyouknowone
authored andcommitted
Implement except* syntax
1 parent 8caa28f commit c7ed645

4 files changed

Lines changed: 1428 additions & 0 deletions

File tree

‎parser/python.lalrpop‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,27 @@ TryStatement: ast::Stmt = {
451451
},
452452
}
453453
},
454+
<location:@L> "try" ":" <body:Suite> <handlers:ExceptStarClause+> <else_suite:("else" ":" Suite)?> <finally:("finally" ":" Suite)?> <end_location:@R> => {
455+
let orelse = else_suite.map(|s| s.2).unwrap_or_default();
456+
let finalbody = finally.map(|s| s.2).unwrap_or_default();
457+
let end_location = finalbody
458+
.last()
459+
.or_else(|| orelse.last())
460+
.map(|last| last.end_location)
461+
.or_else(|| handlers.last().map(|last| last.end_location))
462+
.unwrap();
463+
ast::Stmt {
464+
custom: (),
465+
location,
466+
end_location,
467+
node: ast::StmtKind::TryStar {
468+
body,
469+
handlers,
470+
orelse,
471+
finalbody,
472+
},
473+
}
474+
},
454475
<location:@L> "try" ":" <body:Suite> <finally:("finally" ":" Suite)> => {
455476
let handlers = vec![];
456477
let orelse = vec![];
@@ -470,6 +491,34 @@ TryStatement: ast::Stmt = {
470491
},
471492
};
472493

494+
ExceptStarClause: ast::Excepthandler = {
495+
<location:@L> "except" "*" <typ:Test<"all">> ":" <body:Suite> => {
496+
let end_location = body.last().unwrap().end_location.unwrap();
497+
ast::Excepthandler::new(
498+
location,
499+
end_location,
500+
ast::ExcepthandlerKind::ExceptHandler {
501+
type_: Some(Box::new(typ)),
502+
name: None,
503+
body,
504+
},
505+
)
506+
},
507+
<location:@L> "except" "*" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
508+
let end_location = body.last().unwrap().end_location.unwrap();
509+
ast::Excepthandler::new(
510+
location,
511+
end_location,
512+
ast::ExcepthandlerKind::ExceptHandler {
513+
type_: Some(Box::new(x.0)),
514+
name: Some(x.2),
515+
body,
516+
},
517+
)
518+
},
519+
};
520+
521+
473522
ExceptClause: ast::Excepthandler = {
474523
<location:@L> "except" <typ:Test<"all">?> ":" <body:Suite> => {
475524
let end_location = body.last().unwrap().end_location.unwrap();

‎parser/src/parser.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,37 @@ with (0 as a, 1 as b,): pass
405405
insta::assert_debug_snapshot!(parse_ast);
406406
}
407407

408+
#[test]
409+
fn test_try() {
410+
let parse_ast = parse_program(
411+
r#"try:
412+
raise ValueError(1)
413+
except TypeError as e:
414+
print(f'caught {type(e)}')
415+
except OSError as e:
416+
print(f'caught {type(e)}')"#,
417+
"<test>",
418+
)
419+
.unwrap();
420+
insta::assert_debug_snapshot!(parse_ast);
421+
}
422+
423+
#[test]
424+
fn test_try_star() {
425+
let parse_ast = parse_program(
426+
r#"try:
427+
raise ExceptionGroup("eg",
428+
[ValueError(1), TypeError(2), OSError(3), OSError(4)])
429+
except* TypeError as e:
430+
print(f'caught {type(e)} with nested {e.exceptions}')
431+
except* OSError as e:
432+
print(f'caught {type(e)} with nested {e.exceptions}')"#,
433+
"<test>",
434+
)
435+
.unwrap();
436+
insta::assert_debug_snapshot!(parse_ast);
437+
}
438+
408439
#[test]
409440
fn test_dict_unpacking() {
410441
let parse_ast = parse_expression(r#"{"a": "b", **c, "d": "e"}"#, "<test>").unwrap();

0 commit comments

Comments
 (0)