@@ -87,9 +87,14 @@ impl PyAsyncGen {
8787 if let Some ( finalizer) = finalizer
8888 && !zelf. inner . closed . load ( )
8989 {
90- // Ignore any errors (PyErr_WriteUnraisable)
90+ // Create a strong reference for the finalizer call.
91+ // This keeps the object alive during the finalizer execution.
9192 let obj: PyObjectRef = zelf. to_owned ( ) . into ( ) ;
92- let _ = finalizer. call ( ( obj, ) , vm) ;
93+
94+ // Call the finalizer. Any exceptions are handled as unraisable.
95+ if let Err ( e) = finalizer. call ( ( obj, ) , vm) {
96+ vm. run_unraisable ( e, Some ( "async generator finalizer" . to_owned ( ) ) , finalizer) ;
97+ }
9398 }
9499 }
95100
@@ -496,11 +501,13 @@ impl PyAsyncGenAThrow {
496501 }
497502 fn yield_close ( & self , vm : & VirtualMachine ) -> PyBaseExceptionRef {
498503 self . ag . running_async . store ( false ) ;
504+ self . ag . inner . closed . store ( true ) ;
499505 self . state . store ( AwaitableState :: Closed ) ;
500506 vm. new_runtime_error ( "async generator ignored GeneratorExit" )
501507 }
502508 fn check_error ( & self , exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyBaseExceptionRef {
503509 self . ag . running_async . store ( false ) ;
510+ self . ag . inner . closed . store ( true ) ;
504511 self . state . store ( AwaitableState :: Closed ) ;
505512 if self . aclose
506513 && ( exc. fast_isinstance ( vm. ctx . exceptions . stop_async_iteration )
@@ -687,12 +694,14 @@ impl IterNext for PyAnextAwaitable {
687694/// _PyGen_Finalize for async generators
688695impl Destructor for PyAsyncGen {
689696 fn del ( zelf : & Py < Self > , vm : & VirtualMachine ) -> PyResult < ( ) > {
690- // Generator isn't paused, so no need to close
697+ // Generator is already closed, nothing to do
691698 if zelf. inner . closed . load ( ) {
692699 return Ok ( ( ) ) ;
693700 }
694701
702+ // Call the async generator finalizer hook if set.
695703 Self :: call_finalizer ( zelf, vm) ;
704+
696705 Ok ( ( ) )
697706 }
698707}
0 commit comments