1
1
use super :: { PyCode , PyStrRef , PyTypeRef } ;
2
2
use crate :: {
3
3
builtins:: PyBaseExceptionRef ,
4
- coroutine:: { Coro , Variant } ,
4
+ coroutine:: Coro ,
5
5
frame:: FrameRef ,
6
6
function:: OptionalArg ,
7
7
protocol:: PyIterReturn ,
@@ -34,7 +34,7 @@ impl PyAsyncGen {
34
34
35
35
pub fn new ( frame : FrameRef , name : PyStrRef ) -> Self {
36
36
PyAsyncGen {
37
- inner : Coro :: new ( frame, Variant :: AsyncGen , name) ,
37
+ inner : Coro :: new ( frame, name) ,
38
38
running_async : AtomicCell :: new ( false ) ,
39
39
}
40
40
}
@@ -50,8 +50,8 @@ impl PyAsyncGen {
50
50
}
51
51
52
52
#[ 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 )
55
55
}
56
56
57
57
#[ pymethod( magic) ]
@@ -138,24 +138,24 @@ impl PyValue for PyAsyncGenWrappedValue {
138
138
impl PyAsyncGenWrappedValue { }
139
139
140
140
impl 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 {
148
152
ag. running_async . store ( false ) ;
149
153
}
150
- let val = val?;
151
-
154
+ let val = val?. into_async_pyresult ( vm) ?;
152
155
match_class ! ( match val {
153
156
val @ Self => {
154
157
ag. running_async. store( false ) ;
155
- Err ( vm. new_exception(
156
- vm. ctx. exceptions. stop_iteration. clone( ) ,
157
- vec![ val. 0 . clone( ) ] ,
158
- ) )
158
+ Err ( vm. new_stop_iteration( Some ( val. 0 . clone( ) ) ) )
159
159
}
160
160
val => Ok ( val) ,
161
161
} )
@@ -214,7 +214,7 @@ impl PyAsyncGenASend {
214
214
}
215
215
}
216
216
} ;
217
- let res = self . ag . inner . send ( val, vm) ;
217
+ let res = self . ag . inner . send ( self . ag . as_object ( ) , val, vm) ;
218
218
let res = PyAsyncGenWrappedValue :: unbox ( & self . ag , res, vm) ;
219
219
if res. is_err ( ) {
220
220
self . close ( ) ;
@@ -237,6 +237,7 @@ impl PyAsyncGenASend {
237
237
}
238
238
239
239
let res = self . ag . inner . throw (
240
+ self . ag . as_object ( ) ,
240
241
exc_type,
241
242
exc_val. unwrap_or_none ( vm) ,
242
243
exc_tb. unwrap_or_none ( vm) ,
@@ -258,8 +259,7 @@ impl PyAsyncGenASend {
258
259
impl IteratorIterable for PyAsyncGenASend { }
259
260
impl SlotIterator for PyAsyncGenASend {
260
261
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)
262
+ PyIterReturn :: from_pyresult ( zelf. send ( vm. ctx . none ( ) , vm) , vm)
263
263
}
264
264
}
265
265
@@ -304,7 +304,7 @@ impl PyAsyncGenAThrow {
304
304
}
305
305
if self . ag . inner . closed ( ) {
306
306
self . state . store ( AwaitableState :: Closed ) ;
307
- return Err ( vm. new_exception_empty ( vm . ctx . exceptions . stop_iteration . clone ( ) ) ) ;
307
+ return Err ( vm. new_stop_iteration ( None ) ) ;
308
308
}
309
309
if !vm. is_none ( & val) {
310
310
return Err ( vm. new_runtime_error (
@@ -315,27 +315,28 @@ impl PyAsyncGenAThrow {
315
315
self . ag . running_async . store ( true ) ;
316
316
317
317
let ( ty, val, tb) = self . value . clone ( ) ;
318
- let ret = self . ag . inner . throw ( ty, val, tb, vm) ;
318
+ let ret = self . ag . inner . throw ( self . ag . as_object ( ) , ty, val, tb, vm) ;
319
319
let ret = if self . aclose {
320
320
if self . ignored_close ( & ret) {
321
321
Err ( self . yield_close ( vm) )
322
322
} else {
323
- ret
323
+ ret. and_then ( |o| o . into_async_pyresult ( vm ) )
324
324
}
325
325
} else {
326
326
PyAsyncGenWrappedValue :: unbox ( & self . ag , ret, vm)
327
327
} ;
328
328
ret. map_err ( |e| self . check_error ( e, vm) )
329
329
}
330
330
AwaitableState :: Iter => {
331
- let ret = self . ag . inner . send ( val, vm) ;
331
+ let ret = self . ag . inner . send ( self . ag . as_object ( ) , val, vm) ;
332
332
if self . aclose {
333
333
match ret {
334
- Ok ( v ) if v. payload_is :: < PyAsyncGenWrappedValue > ( ) => {
334
+ Ok ( PyIterReturn :: Return ( v ) ) if v. payload_is :: < PyAsyncGenWrappedValue > ( ) => {
335
335
Err ( self . yield_close ( vm) )
336
336
}
337
- Ok ( v) => Ok ( v) ,
338
- Err ( e) => Err ( self . check_error ( e, vm) ) ,
337
+ other => other
338
+ . and_then ( |o| o. into_async_pyresult ( vm) )
339
+ . map_err ( |e| self . check_error ( e, vm) ) ,
339
340
}
340
341
} else {
341
342
PyAsyncGenWrappedValue :: unbox ( & self . ag , ret, vm)
@@ -353,6 +354,7 @@ impl PyAsyncGenAThrow {
353
354
vm : & VirtualMachine ,
354
355
) -> PyResult {
355
356
let ret = self . ag . inner . throw (
357
+ self . ag . as_object ( ) ,
356
358
exc_type,
357
359
exc_val. unwrap_or_none ( vm) ,
358
360
exc_tb. unwrap_or_none ( vm) ,
@@ -362,7 +364,7 @@ impl PyAsyncGenAThrow {
362
364
if self . ignored_close ( & ret) {
363
365
Err ( self . yield_close ( vm) )
364
366
} else {
365
- ret
367
+ ret. and_then ( |o| o . into_async_pyresult ( vm ) )
366
368
}
367
369
} else {
368
370
PyAsyncGenWrappedValue :: unbox ( & self . ag , ret, vm)
@@ -375,9 +377,11 @@ impl PyAsyncGenAThrow {
375
377
self . state . store ( AwaitableState :: Closed ) ;
376
378
}
377
379
378
- fn ignored_close ( & self , res : & PyResult ) -> bool {
379
- res. as_ref ( )
380
- . map_or ( false , |v| v. payload_is :: < PyAsyncGenWrappedValue > ( ) )
380
+ fn ignored_close ( & self , res : & PyResult < PyIterReturn > ) -> bool {
381
+ res. as_ref ( ) . map_or ( false , |v| match v {
382
+ PyIterReturn :: Return ( obj) => obj. payload_is :: < PyAsyncGenWrappedValue > ( ) ,
383
+ PyIterReturn :: StopIteration ( _) => false ,
384
+ } )
381
385
}
382
386
fn yield_close ( & self , vm : & VirtualMachine ) -> PyBaseExceptionRef {
383
387
self . ag . running_async . store ( false ) ;
@@ -391,7 +395,7 @@ impl PyAsyncGenAThrow {
391
395
&& ( exc. isinstance ( & vm. ctx . exceptions . stop_async_iteration )
392
396
|| exc. isinstance ( & vm. ctx . exceptions . generator_exit ) )
393
397
{
394
- vm. new_exception_empty ( vm . ctx . exceptions . stop_iteration . clone ( ) )
398
+ vm. new_stop_iteration ( None )
395
399
} else {
396
400
exc
397
401
}
@@ -401,8 +405,7 @@ impl PyAsyncGenAThrow {
401
405
impl IteratorIterable for PyAsyncGenAThrow { }
402
406
impl SlotIterator for PyAsyncGenAThrow {
403
407
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)
408
+ PyIterReturn :: from_pyresult ( zelf. send ( vm. ctx . none ( ) , vm) , vm)
406
409
}
407
410
}
408
411
0 commit comments