@@ -715,16 +715,19 @@ def transform_try_finally_stmt_async(
715715 builder : IRBuilder , try_body : GenFunc , finally_body : GenFunc , line : int = - 1
716716) -> None :
717717 """Async-aware try/finally handling for when finally contains await.
718-
718+
719719 This version uses a modified approach that preserves exceptions across await."""
720-
720+
721721 # We need to handle returns properly, so we'll use TryFinallyNonlocalControl
722722 # to track return values, similar to the regular try/finally implementation
723-
723+
724724 err_handler , main_entry , return_entry , finally_entry = (
725- BasicBlock (), BasicBlock (), BasicBlock (), BasicBlock ()
725+ BasicBlock (),
726+ BasicBlock (),
727+ BasicBlock (),
728+ BasicBlock (),
726729 )
727-
730+
728731 # Track if we're returning from the try block
729732 control = TryFinallyNonlocalControl (return_entry )
730733 builder .builder .push_error_handler (err_handler )
@@ -735,76 +738,76 @@ def transform_try_finally_stmt_async(
735738 builder .nonlocal_control .pop ()
736739 builder .builder .pop_error_handler ()
737740 ret_reg = control .ret_reg
738-
741+
739742 # Normal case - no exception or return
740743 builder .activate_block (main_entry )
741744 builder .goto (finally_entry )
742-
745+
743746 # Return case
744747 builder .activate_block (return_entry )
745748 builder .goto (finally_entry )
746-
749+
747750 # Exception case - need to catch to clear the error indicator
748751 builder .activate_block (err_handler )
749752 # Catch the error to clear Python's error indicator
750753 old_exc = builder .call_c (error_catch_op , [], line )
751754 # We're not going to use old_exc since it won't survive await
752755 # The exception is now in sys.exc_info()
753756 builder .goto (finally_entry )
754-
757+
755758 # Finally block
756759 builder .activate_block (finally_entry )
757-
760+
758761 # Execute finally body
759762 finally_body ()
760-
763+
761764 # After finally, we need to handle exceptions carefully:
762765 # 1. If finally raised a new exception, it's in the error indicator - let it propagate
763766 # 2. If finally didn't raise, check if we need to reraise the original from sys.exc_info()
764767 # 3. If there was a return, return that value
765768 # 4. Otherwise, normal exit
766-
769+
767770 # First, check if there's a current exception in the error indicator
768771 # (this would be from the finally block)
769772 no_current_exc = builder .call_c (no_err_occurred_op , [], line )
770773 finally_raised = BasicBlock ()
771774 check_original = BasicBlock ()
772775 builder .add (Branch (no_current_exc , check_original , finally_raised , Branch .BOOL ))
773-
776+
774777 # Finally raised an exception - let it propagate naturally
775778 builder .activate_block (finally_raised )
776779 builder .call_c (keep_propagating_op , [], NO_TRACEBACK_LINE_NO )
777780 builder .add (Unreachable ())
778-
781+
779782 # No exception from finally, check if we need to handle return or original exception
780783 builder .activate_block (check_original )
781-
784+
782785 # Check if we have a return value
783786 if ret_reg :
784787 return_block , check_old_exc = BasicBlock (), BasicBlock ()
785788 builder .add (Branch (builder .read (ret_reg ), check_old_exc , return_block , Branch .IS_ERROR ))
786-
789+
787790 builder .activate_block (return_block )
788791 builder .nonlocal_control [- 1 ].gen_return (builder , builder .read (ret_reg ), - 1 )
789-
792+
790793 builder .activate_block (check_old_exc )
791-
794+
792795 # Check if we need to reraise the original exception from sys.exc_info
793796 exc_info = builder .call_c (get_exc_info_op , [], line )
794797 exc_type = builder .add (TupleGet (exc_info , 0 , line ))
795-
798+
796799 # Check if exc_type is None
797800 none_obj = builder .none_object ()
798801 has_exc = builder .binary_op (exc_type , none_obj , "is not" , line )
799-
802+
800803 reraise_block , exit_block = BasicBlock (), BasicBlock ()
801804 builder .add (Branch (has_exc , reraise_block , exit_block , Branch .BOOL ))
802-
805+
803806 # Reraise the original exception
804807 builder .activate_block (reraise_block )
805808 builder .call_c (reraise_exception_op , [], NO_TRACEBACK_LINE_NO )
806809 builder .add (Unreachable ())
807-
810+
808811 # Normal exit
809812 builder .activate_block (exit_block )
810813
@@ -850,9 +853,13 @@ def transform_try_body() -> None:
850853 body = t .finally_body
851854
852855 if use_async_version :
853- transform_try_finally_stmt_async (builder , transform_try_body , lambda : builder .accept (body ), t .line )
856+ transform_try_finally_stmt_async (
857+ builder , transform_try_body , lambda : builder .accept (body ), t .line
858+ )
854859 else :
855- transform_try_finally_stmt (builder , transform_try_body , lambda : builder .accept (body ), t .line )
860+ transform_try_finally_stmt (
861+ builder , transform_try_body , lambda : builder .accept (body ), t .line
862+ )
856863 else :
857864 transform_try_except_stmt (builder , t )
858865
@@ -943,7 +950,7 @@ def finally_body() -> None:
943950 builder ,
944951 lambda : transform_try_except (builder , try_body , [(None , None , except_body )], None , line ),
945952 finally_body ,
946- line
953+ line ,
947954 )
948955
949956
0 commit comments