@@ -79,9 +79,14 @@ impl PyAsyncGen {
7979 if let Some ( finalizer) = finalizer
8080 && !zelf. inner . closed . load ( )
8181 {
82- // Ignore any errors (PyErr_WriteUnraisable)
82+ // Create a strong reference for the finalizer call.
83+ // This keeps the object alive during the finalizer execution.
8384 let obj: PyObjectRef = zelf. to_owned ( ) . into ( ) ;
84- let _ = finalizer. call ( ( obj, ) , vm) ;
85+
86+ // Call the finalizer. Any exceptions are handled as unraisable.
87+ if let Err ( e) = finalizer. call ( ( obj, ) , vm) {
88+ vm. run_unraisable ( e, Some ( "async generator finalizer" . to_owned ( ) ) , finalizer) ;
89+ }
8590 }
8691 }
8792
@@ -463,11 +468,13 @@ impl PyAsyncGenAThrow {
463468 }
464469 fn yield_close ( & self , vm : & VirtualMachine ) -> PyBaseExceptionRef {
465470 self . ag . running_async . store ( false ) ;
471+ self . ag . inner . closed . store ( true ) ;
466472 self . state . store ( AwaitableState :: Closed ) ;
467473 vm. new_runtime_error ( "async generator ignored GeneratorExit" )
468474 }
469475 fn check_error ( & self , exc : PyBaseExceptionRef , vm : & VirtualMachine ) -> PyBaseExceptionRef {
470476 self . ag . running_async . store ( false ) ;
477+ self . ag . inner . closed . store ( true ) ;
471478 self . state . store ( AwaitableState :: Closed ) ;
472479 if self . aclose
473480 && ( exc. fast_isinstance ( vm. ctx . exceptions . stop_async_iteration )
@@ -647,12 +654,14 @@ impl IterNext for PyAnextAwaitable {
647654/// _PyGen_Finalize for async generators
648655impl Destructor for PyAsyncGen {
649656 fn del ( zelf : & Py < Self > , vm : & VirtualMachine ) -> PyResult < ( ) > {
650- // Generator isn't paused, so no need to close
657+ // Generator is already closed, nothing to do
651658 if zelf. inner . closed . load ( ) {
652659 return Ok ( ( ) ) ;
653660 }
654661
662+ // Call the async generator finalizer hook if set.
655663 Self :: call_finalizer ( zelf, vm) ;
664+
656665 Ok ( ( ) )
657666 }
658667}
0 commit comments