@@ -2597,66 +2597,78 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body)
25972597static stmt_ty
25982598ast_for_try_stmt (struct compiling * c , const node * n )
25992599{
2600+ const int nch = NCH (n );
2601+ int n_except = (nch - 3 )/3 ;
2602+ asdl_seq * body , * orelse = NULL , * finally = NULL ;
2603+
26002604 REQ (n , try_stmt );
26012605
2602- if (TYPE (CHILD (n , 3 )) == NAME ) {/* must be 'finally' */
2603- /* try_stmt: 'try' ':' suite 'finally' ':' suite) */
2604- asdl_seq * s1 , * s2 ;
2605- s1 = ast_for_suite (c , CHILD (n , 2 ));
2606- if (!s1 )
2607- return NULL ;
2608- s2 = ast_for_suite (c , CHILD (n , 5 ));
2609- if (!s2 ) {
2610- return NULL ;
2611- }
2612-
2613- return TryFinally (s1 , s2 , LINENO (n ), c -> c_arena );
2614- }
2615- else if (TYPE (CHILD (n , 3 )) == except_clause ) {
2616- /* try_stmt: ('try' ':' suite (except_clause ':' suite)+
2617- ['else' ':' suite]
2618- */
2619- asdl_seq * suite_seq1 , * suite_seq2 ;
2620- asdl_seq * handlers ;
2621- int i , has_else = 0 , n_except = NCH (n ) - 3 ;
2622- if (TYPE (CHILD (n , NCH (n ) - 3 )) == NAME ) {
2623- has_else = 1 ;
2624- n_except -= 3 ;
2625- }
2626- n_except /= 3 ;
2627- handlers = asdl_seq_new (n_except , c -> c_arena );
2628- if (!handlers )
2629- return NULL ;
2630- for (i = 0 ; i < n_except ; i ++ ) {
2631- excepthandler_ty e = ast_for_except_clause (c ,
2632- CHILD (n , 3 + i * 3 ),
2633- CHILD (n , 5 + i * 3 ));
2634- if (!e ) {
2606+ body = ast_for_suite (c , CHILD (n , 2 ));
2607+ if (body == NULL )
2608+ return NULL ;
2609+
2610+ if (TYPE (CHILD (n , nch - 3 )) == NAME ) {
2611+ if (strcmp (STR (CHILD (n , nch - 3 )), "finally" ) == 0 ) {
2612+ if (nch >= 9 && TYPE (CHILD (n , nch - 6 )) == NAME ) {
2613+ /* we can assume it's an "else",
2614+ because nch >= 9 for try-else-finally and
2615+ it would otherwise have a type of except_clause */
2616+ orelse = ast_for_suite (c , CHILD (n , nch - 4 ));
2617+ if (orelse == NULL )
2618+ return NULL ;
2619+ n_except -- ;
2620+ }
2621+
2622+ finally = ast_for_suite (c , CHILD (n , nch - 1 ));
2623+ if (finally == NULL )
26352624 return NULL ;
2636- }
2637- asdl_seq_SET (handlers , i , e );
2625+ n_except -- ;
26382626 }
2639-
2640- suite_seq1 = ast_for_suite (c , CHILD (n , 2 ));
2641- if (!suite_seq1 ) {
2642- return NULL ;
2643- }
2644- if (has_else ) {
2645- suite_seq2 = ast_for_suite (c , CHILD (n , NCH (n ) - 1 ));
2646- if (!suite_seq2 ) {
2627+ else {
2628+ /* we can assume it's an "else",
2629+ otherwise it would have a type of except_clause */
2630+ orelse = ast_for_suite (c , CHILD (n , nch - 1 ));
2631+ if (orelse == NULL )
26472632 return NULL ;
2648- }
2633+ n_except -- ;
26492634 }
2650- else
2651- suite_seq2 = NULL ;
2652-
2653- return TryExcept (suite_seq1 , handlers , suite_seq2 , LINENO (n ),
2654- c -> c_arena );
26552635 }
2656- else {
2636+ else if ( TYPE ( CHILD ( n , nch - 3 )) != except_clause ) {
26572637 ast_error (n , "malformed 'try' statement" );
26582638 return NULL ;
26592639 }
2640+
2641+ if (n_except > 0 ) {
2642+ int i ;
2643+ stmt_ty except_st ;
2644+ /* process except statements to create a try ... except */
2645+ asdl_seq * handlers = asdl_seq_new (n_except , c -> c_arena );
2646+ if (handlers == NULL )
2647+ return NULL ;
2648+
2649+ for (i = 0 ; i < n_except ; i ++ ) {
2650+ excepthandler_ty e = ast_for_except_clause (c , CHILD (n , 3 + i * 3 ),
2651+ CHILD (n , 5 + i * 3 ));
2652+ if (!e )
2653+ return NULL ;
2654+ asdl_seq_SET (handlers , i , e );
2655+ }
2656+
2657+ except_st = TryExcept (body , handlers , orelse , LINENO (n ), c -> c_arena );
2658+ if (!finally )
2659+ return except_st ;
2660+
2661+ /* if a 'finally' is present too, we nest the TryExcept within a
2662+ TryFinally to emulate try ... except ... finally */
2663+ body = asdl_seq_new (1 , c -> c_arena );
2664+ if (body == NULL )
2665+ return NULL ;
2666+ asdl_seq_SET (body , 0 , except_st );
2667+ }
2668+
2669+ /* must be a try ... finally (except clauses are in body, if any exist) */
2670+ assert (finally != NULL );
2671+ return TryFinally (body , finally , LINENO (n ), c -> c_arena );
26602672}
26612673
26622674static stmt_ty
0 commit comments