Parses an `except` clause of a `try` statement. # Panics If the parser isn't positioned at an `except` token.
(&mut self)
| 1676 | /// |
| 1677 | /// If the parser isn't positioned at an `except` token. |
| 1678 | fn parse_except_clause(&mut self) -> (ExceptHandler, ExceptClauseKind) { |
| 1679 | let start = self.node_start(); |
| 1680 | self.bump(TokenKind::Except); |
| 1681 | |
| 1682 | let star_token_range = self.current_token_range(); |
| 1683 | let block_kind = if self.eat(TokenKind::Star) { |
| 1684 | ExceptClauseKind::Star(star_token_range) |
| 1685 | } else { |
| 1686 | ExceptClauseKind::Normal |
| 1687 | }; |
| 1688 | |
| 1689 | let type_ = if self.at_expr() { |
| 1690 | // test_err except_stmt_invalid_expression |
| 1691 | // try: |
| 1692 | // pass |
| 1693 | // except yield x: |
| 1694 | // pass |
| 1695 | // try: |
| 1696 | // pass |
| 1697 | // except* *x: |
| 1698 | // pass |
| 1699 | let parsed_expr = self.parse_expression_list(ExpressionContext::default()); |
| 1700 | if matches!( |
| 1701 | parsed_expr.expr, |
| 1702 | Expr::Tuple(ast::ExprTuple { |
| 1703 | parenthesized: false, |
| 1704 | .. |
| 1705 | }) |
| 1706 | ) { |
| 1707 | if self.at(TokenKind::As) { |
| 1708 | // test_err except_stmt_unparenthesized_tuple_as |
| 1709 | // try: |
| 1710 | // pass |
| 1711 | // except x, y as exc: |
| 1712 | // pass |
| 1713 | // try: |
| 1714 | // pass |
| 1715 | // except* x, y as eg: |
| 1716 | // pass |
| 1717 | self.add_error( |
| 1718 | ParseErrorType::OtherError( |
| 1719 | "Multiple exception types must be parenthesized when using `as`" |
| 1720 | .to_string(), |
| 1721 | ), |
| 1722 | &parsed_expr, |
| 1723 | ); |
| 1724 | } else { |
| 1725 | // test_err except_stmt_unparenthesized_tuple_no_as_py313 |
| 1726 | // # parse_options: {"target-version": "3.13"} |
| 1727 | // try: |
| 1728 | // pass |
| 1729 | // except x, y: |
| 1730 | // pass |
| 1731 | // try: |
| 1732 | // pass |
| 1733 | // except* x, y: |
| 1734 | // pass |
| 1735 |
no test coverage detected