@@ -721,16 +721,19 @@ def transform_try_finally_stmt_async(
721721 builder : IRBuilder , try_body : GenFunc , finally_body : GenFunc , line : int = - 1
722722) -> None :
723723 """Async-aware try/finally handling for when finally contains await.
724-
724+
725725 This version uses a modified approach that preserves exceptions across await."""
726-
726+
727727 # We need to handle returns properly, so we'll use TryFinallyNonlocalControl
728728 # to track return values, similar to the regular try/finally implementation
729-
729+
730730 err_handler , main_entry , return_entry , finally_entry = (
731- BasicBlock (), BasicBlock (), BasicBlock (), BasicBlock ()
731+ BasicBlock (),
732+ BasicBlock (),
733+ BasicBlock (),
734+ BasicBlock (),
732735 )
733-
736+
734737 # Track if we're returning from the try block
735738 control = TryFinallyNonlocalControl (return_entry )
736739 builder .builder .push_error_handler (err_handler )
@@ -741,76 +744,76 @@ def transform_try_finally_stmt_async(
741744 builder .nonlocal_control .pop ()
742745 builder .builder .pop_error_handler ()
743746 ret_reg = control .ret_reg
744-
747+
745748 # Normal case - no exception or return
746749 builder .activate_block (main_entry )
747750 builder .goto (finally_entry )
748-
751+
749752 # Return case
750753 builder .activate_block (return_entry )
751754 builder .goto (finally_entry )
752-
755+
753756 # Exception case - need to catch to clear the error indicator
754757 builder .activate_block (err_handler )
755758 # Catch the error to clear Python's error indicator
756759 old_exc = builder .call_c (error_catch_op , [], line )
757760 # We're not going to use old_exc since it won't survive await
758761 # The exception is now in sys.exc_info()
759762 builder .goto (finally_entry )
760-
763+
761764 # Finally block
762765 builder .activate_block (finally_entry )
763-
766+
764767 # Execute finally body
765768 finally_body ()
766-
769+
767770 # After finally, we need to handle exceptions carefully:
768771 # 1. If finally raised a new exception, it's in the error indicator - let it propagate
769772 # 2. If finally didn't raise, check if we need to reraise the original from sys.exc_info()
770773 # 3. If there was a return, return that value
771774 # 4. Otherwise, normal exit
772-
775+
773776 # First, check if there's a current exception in the error indicator
774777 # (this would be from the finally block)
775778 no_current_exc = builder .call_c (no_err_occurred_op , [], line )
776779 finally_raised = BasicBlock ()
777780 check_original = BasicBlock ()
778781 builder .add (Branch (no_current_exc , check_original , finally_raised , Branch .BOOL ))
779-
782+
780783 # Finally raised an exception - let it propagate naturally
781784 builder .activate_block (finally_raised )
782785 builder .call_c (keep_propagating_op , [], NO_TRACEBACK_LINE_NO )
783786 builder .add (Unreachable ())
784-
787+
785788 # No exception from finally, check if we need to handle return or original exception
786789 builder .activate_block (check_original )
787-
790+
788791 # Check if we have a return value
789792 if ret_reg :
790793 return_block , check_old_exc = BasicBlock (), BasicBlock ()
791794 builder .add (Branch (builder .read (ret_reg ), check_old_exc , return_block , Branch .IS_ERROR ))
792-
795+
793796 builder .activate_block (return_block )
794797 builder .nonlocal_control [- 1 ].gen_return (builder , builder .read (ret_reg ), - 1 )
795-
798+
796799 builder .activate_block (check_old_exc )
797-
800+
798801 # Check if we need to reraise the original exception from sys.exc_info
799802 exc_info = builder .call_c (get_exc_info_op , [], line )
800803 exc_type = builder .add (TupleGet (exc_info , 0 , line ))
801-
804+
802805 # Check if exc_type is None
803806 none_obj = builder .none_object ()
804807 has_exc = builder .binary_op (exc_type , none_obj , "is not" , line )
805-
808+
806809 reraise_block , exit_block = BasicBlock (), BasicBlock ()
807810 builder .add (Branch (has_exc , reraise_block , exit_block , Branch .BOOL ))
808-
811+
809812 # Reraise the original exception
810813 builder .activate_block (reraise_block )
811814 builder .call_c (reraise_exception_op , [], NO_TRACEBACK_LINE_NO )
812815 builder .add (Unreachable ())
813-
816+
814817 # Normal exit
815818 builder .activate_block (exit_block )
816819
@@ -856,9 +859,13 @@ def transform_try_body() -> None:
856859 body = t .finally_body
857860
858861 if use_async_version :
859- transform_try_finally_stmt_async (builder , transform_try_body , lambda : builder .accept (body ), t .line )
862+ transform_try_finally_stmt_async (
863+ builder , transform_try_body , lambda : builder .accept (body ), t .line
864+ )
860865 else :
861- transform_try_finally_stmt (builder , transform_try_body , lambda : builder .accept (body ), t .line )
866+ transform_try_finally_stmt (
867+ builder , transform_try_body , lambda : builder .accept (body ), t .line
868+ )
862869 else :
863870 transform_try_except_stmt (builder , t )
864871
@@ -949,7 +956,7 @@ def finally_body() -> None:
949956 builder ,
950957 lambda : transform_try_except (builder , try_body , [(None , None , except_body )], None , line ),
951958 finally_body ,
952- line
959+ line ,
953960 )
954961
955962
0 commit comments