11use super :: { PyCode , PyStrRef , PyTypeRef } ;
22use crate :: {
33 builtins:: PyBaseExceptionRef ,
4- coroutine:: { Coro , Variant } ,
4+ coroutine:: Coro ,
55 frame:: FrameRef ,
66 function:: OptionalArg ,
77 protocol:: PyIterReturn ,
@@ -34,7 +34,7 @@ impl PyAsyncGen {
3434
3535 pub fn new ( frame : FrameRef , name : PyStrRef ) -> Self {
3636 PyAsyncGen {
37- inner : Coro :: new ( frame, Variant :: AsyncGen , name) ,
37+ inner : Coro :: new ( frame, name) ,
3838 running_async : AtomicCell :: new ( false ) ,
3939 }
4040 }
@@ -50,8 +50,8 @@ impl PyAsyncGen {
5050 }
5151
5252 #[ pymethod( magic) ]
53- fn repr ( zelf : PyRef < Self > ) -> String {
54- zelf. inner . repr ( zelf. get_id ( ) )
53+ fn repr ( zelf : PyRef < Self > , vm : & VirtualMachine ) -> String {
54+ zelf. inner . repr ( zelf. as_object ( ) , zelf . get_id ( ) , vm )
5555 }
5656
5757 #[ pymethod( magic) ]
@@ -138,17 +138,20 @@ impl PyValue for PyAsyncGenWrappedValue {
138138impl PyAsyncGenWrappedValue { }
139139
140140impl PyAsyncGenWrappedValue {
141- fn unbox ( ag : & PyAsyncGen , val : PyResult , vm : & VirtualMachine ) -> PyResult {
142- if let Err ( ref e) = val {
143- if e. isinstance ( & vm. ctx . exceptions . stop_async_iteration )
144- || e. isinstance ( & vm. ctx . exceptions . generator_exit )
145- {
146- ag. inner . closed . store ( true ) ;
147- }
141+ fn unbox ( ag : & PyAsyncGen , val : PyResult < PyIterReturn > , vm : & VirtualMachine ) -> PyResult {
142+ let ( closed, async_done) = match & val {
143+ Ok ( PyIterReturn :: StopIteration ( _) ) => ( true , true ) ,
144+ Err ( e) if e. isinstance ( & vm. ctx . exceptions . generator_exit ) => ( true , true ) ,
145+ Err ( _) => ( false , true ) ,
146+ _ => ( false , false ) ,
147+ } ;
148+ if closed {
149+ ag. inner . closed . store ( true ) ;
150+ }
151+ if async_done {
148152 ag. running_async . store ( false ) ;
149153 }
150- let val = val?;
151-
154+ let val = val?. into_async_pyresult ( vm) ?;
152155 match_class ! ( match val {
153156 val @ Self => {
154157 ag. running_async. store( false ) ;
@@ -214,7 +217,7 @@ impl PyAsyncGenASend {
214217 }
215218 }
216219 } ;
217- let res = self . ag . inner . send ( val, vm) ;
220+ let res = self . ag . inner . send ( self . ag . as_object ( ) , val, vm) ;
218221 let res = PyAsyncGenWrappedValue :: unbox ( & self . ag , res, vm) ;
219222 if res. is_err ( ) {
220223 self . close ( ) ;
@@ -237,6 +240,7 @@ impl PyAsyncGenASend {
237240 }
238241
239242 let res = self . ag . inner . throw (
243+ self . ag . as_object ( ) ,
240244 exc_type,
241245 exc_val. unwrap_or_none ( vm) ,
242246 exc_tb. unwrap_or_none ( vm) ,
@@ -258,8 +262,7 @@ impl PyAsyncGenASend {
258262impl IteratorIterable for PyAsyncGenASend { }
259263impl SlotIterator for PyAsyncGenASend {
260264 fn next ( zelf : & PyRef < Self > , vm : & VirtualMachine ) -> PyResult < PyIterReturn > {
261- // TODO: Fix zelf.send to return PyIterReturn
262- PyIterReturn :: from_result ( zelf. send ( vm. ctx . none ( ) , vm) , vm)
265+ PyIterReturn :: from_pyresult ( zelf. send ( vm. ctx . none ( ) , vm) , vm)
263266 }
264267}
265268
@@ -315,27 +318,28 @@ impl PyAsyncGenAThrow {
315318 self . ag . running_async . store ( true ) ;
316319
317320 let ( ty, val, tb) = self . value . clone ( ) ;
318- let ret = self . ag . inner . throw ( ty, val, tb, vm) ;
321+ let ret = self . ag . inner . throw ( self . ag . as_object ( ) , ty, val, tb, vm) ;
319322 let ret = if self . aclose {
320323 if self . ignored_close ( & ret) {
321324 Err ( self . yield_close ( vm) )
322325 } else {
323- ret
326+ ret. and_then ( |o| o . into_async_pyresult ( vm ) )
324327 }
325328 } else {
326329 PyAsyncGenWrappedValue :: unbox ( & self . ag , ret, vm)
327330 } ;
328331 ret. map_err ( |e| self . check_error ( e, vm) )
329332 }
330333 AwaitableState :: Iter => {
331- let ret = self . ag . inner . send ( val, vm) ;
334+ let ret = self . ag . inner . send ( self . ag . as_object ( ) , val, vm) ;
332335 if self . aclose {
333336 match ret {
334- Ok ( v ) if v. payload_is :: < PyAsyncGenWrappedValue > ( ) => {
337+ Ok ( PyIterReturn :: Return ( v ) ) if v. payload_is :: < PyAsyncGenWrappedValue > ( ) => {
335338 Err ( self . yield_close ( vm) )
336339 }
337- Ok ( v) => Ok ( v) ,
338- Err ( e) => Err ( self . check_error ( e, vm) ) ,
340+ other => other
341+ . and_then ( |o| o. into_async_pyresult ( vm) )
342+ . map_err ( |e| self . check_error ( e, vm) ) ,
339343 }
340344 } else {
341345 PyAsyncGenWrappedValue :: unbox ( & self . ag , ret, vm)
@@ -353,6 +357,7 @@ impl PyAsyncGenAThrow {
353357 vm : & VirtualMachine ,
354358 ) -> PyResult {
355359 let ret = self . ag . inner . throw (
360+ self . ag . as_object ( ) ,
356361 exc_type,
357362 exc_val. unwrap_or_none ( vm) ,
358363 exc_tb. unwrap_or_none ( vm) ,
@@ -362,7 +367,7 @@ impl PyAsyncGenAThrow {
362367 if self . ignored_close ( & ret) {
363368 Err ( self . yield_close ( vm) )
364369 } else {
365- ret
370+ ret. and_then ( |o| o . into_async_pyresult ( vm ) )
366371 }
367372 } else {
368373 PyAsyncGenWrappedValue :: unbox ( & self . ag , ret, vm)
@@ -375,9 +380,11 @@ impl PyAsyncGenAThrow {
375380 self . state . store ( AwaitableState :: Closed ) ;
376381 }
377382
378- fn ignored_close ( & self , res : & PyResult ) -> bool {
379- res. as_ref ( )
380- . map_or ( false , |v| v. payload_is :: < PyAsyncGenWrappedValue > ( ) )
383+ fn ignored_close ( & self , res : & PyResult < PyIterReturn > ) -> bool {
384+ res. as_ref ( ) . map_or ( false , |v| match v {
385+ PyIterReturn :: Return ( obj) => obj. payload_is :: < PyAsyncGenWrappedValue > ( ) ,
386+ PyIterReturn :: StopIteration ( _) => false ,
387+ } )
381388 }
382389 fn yield_close ( & self , vm : & VirtualMachine ) -> PyBaseExceptionRef {
383390 self . ag . running_async . store ( false ) ;
@@ -401,8 +408,7 @@ impl PyAsyncGenAThrow {
401408impl IteratorIterable for PyAsyncGenAThrow { }
402409impl SlotIterator for PyAsyncGenAThrow {
403410 fn next ( zelf : & PyRef < Self > , vm : & VirtualMachine ) -> PyResult < PyIterReturn > {
404- // TODO: Fix zelf.send to return PyIterReturn
405- PyIterReturn :: from_result ( zelf. send ( vm. ctx . none ( ) , vm) , vm)
411+ PyIterReturn :: from_pyresult ( zelf. send ( vm. ctx . none ( ) , vm) , vm)
406412 }
407413}
408414
0 commit comments