Skip to content

Commit c1bf512

Browse files
committed
RuntimeError on coro raising StopIteration
1 parent 9507a9f commit c1bf512

File tree

5 files changed

+46
-22
lines changed

5 files changed

+46
-22
lines changed

Lib/test/test_asyncgen.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,6 @@ async def gen():
219219
'async generator.*StopAsyncIteration'):
220220
to_list(gen())
221221

222-
@unittest.skip("TODO: RUSTPYTHON")
223222
def test_async_gen_exception_06(self):
224223
async def gen():
225224
yield 123

vm/src/obj/objasyncgenerator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::objcode::PyCodeRef;
2-
use super::objcoroinner::Coro;
2+
use super::objcoroinner::{Coro, Variant};
33
use super::objtype::{self, PyClassRef};
44
use crate::frame::FrameRef;
55
use crate::function::OptionalArg;
@@ -30,7 +30,7 @@ impl PyAsyncGen {
3030

3131
pub fn new(frame: FrameRef, vm: &VirtualMachine) -> PyAsyncGenRef {
3232
PyAsyncGen {
33-
inner: Coro::new_async(frame),
33+
inner: Coro::new(frame, Variant::AsyncGen),
3434
running_async: Cell::new(false),
3535
}
3636
.into_ref(vm)

vm/src/obj/objcoroinner.rs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,44 @@ use crate::vm::VirtualMachine;
66

77
use std::cell::{Cell, RefCell};
88

9+
#[derive(Debug, PartialEq, Clone, Copy)]
10+
pub enum Variant {
11+
Gen,
12+
Coroutine,
13+
AsyncGen,
14+
}
15+
impl Variant {
16+
fn exec_result(self, res: ExecutionResult, vm: &VirtualMachine) -> PyResult {
17+
res.into_result(self == Self::AsyncGen, vm)
18+
}
19+
fn name(self) -> &'static str {
20+
match self {
21+
Self::Gen => "generator",
22+
Self::Coroutine => "coroutine",
23+
Self::AsyncGen => "async generator",
24+
}
25+
}
26+
}
27+
928
#[derive(Debug)]
1029
pub struct Coro {
1130
frame: FrameRef,
1231
pub closed: Cell<bool>,
1332
running: Cell<bool>,
1433
exceptions: RefCell<Vec<PyBaseExceptionRef>>,
1534
started: Cell<bool>,
16-
async_iter: bool,
35+
variant: Variant,
1736
}
1837

1938
impl Coro {
20-
pub fn new(frame: FrameRef) -> Self {
39+
pub fn new(frame: FrameRef, variant: Variant) -> Self {
2140
Coro {
2241
frame,
2342
closed: Cell::new(false),
2443
running: Cell::new(false),
2544
exceptions: RefCell::new(vec![]),
2645
started: Cell::new(false),
27-
async_iter: false,
28-
}
29-
}
30-
pub fn new_async(frame: FrameRef) -> Self {
31-
Coro {
32-
frame,
33-
closed: Cell::new(false),
34-
running: Cell::new(false),
35-
exceptions: RefCell::new(vec![]),
36-
started: Cell::new(false),
37-
async_iter: true,
46+
variant,
3847
}
3948
}
4049

@@ -62,6 +71,22 @@ impl Coro {
6271
);
6372
self.running.set(false);
6473
self.started.set(true);
74+
if let Err(ref e) = result {
75+
if objtype::isinstance(e, &vm.ctx.exceptions.stop_iteration) {
76+
let err =
77+
vm.new_runtime_error(format!("{} raised StopIteration", self.variant.name()));
78+
err.set_cause(Some(e.clone()));
79+
return Err(err);
80+
}
81+
if self.variant == Variant::AsyncGen
82+
&& objtype::isinstance(e, &vm.ctx.exceptions.stop_async_iteration)
83+
{
84+
let err =
85+
vm.new_runtime_error("async generator raise StopAsyncIteration".to_owned());
86+
err.set_cause(Some(e.clone()));
87+
return Err(err);
88+
}
89+
}
6590
result
6691
}
6792

@@ -77,7 +102,7 @@ impl Coro {
77102
self.frame.push_value(value.clone());
78103
let result = self.run_with_context(|| vm.run_frame(self.frame.clone()), vm);
79104
self.maybe_close(&result);
80-
result?.into_result(self.async_iter, vm)
105+
self.variant.exec_result(result?, vm)
81106
}
82107
pub fn throw(
83108
&self,
@@ -94,7 +119,7 @@ impl Coro {
94119
self.run_with_context(|| self.frame.gen_throw(vm, exc_type, exc_val, exc_tb), vm);
95120
self.maybe_close(&result);
96121
vm.frames.borrow_mut().pop();
97-
result?.into_result(self.async_iter, vm)
122+
self.variant.exec_result(result?, vm)
98123
}
99124

100125
pub fn close(&self, vm: &VirtualMachine) -> PyResult<()> {

vm/src/obj/objcoroutine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use super::objcode::PyCodeRef;
2-
use super::objcoroinner::Coro;
2+
use super::objcoroinner::{Coro, Variant};
33
use super::objstr::PyStringRef;
44
use super::objtype::PyClassRef;
55
use crate::frame::FrameRef;
@@ -29,7 +29,7 @@ impl PyCoroutine {
2929

3030
pub fn new(frame: FrameRef, vm: &VirtualMachine) -> PyCoroutineRef {
3131
PyCoroutine {
32-
inner: Coro::new(frame),
32+
inner: Coro::new(frame, Variant::Coroutine),
3333
}
3434
.into_ref(vm)
3535
}

vm/src/obj/objgenerator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44

55
use super::objcode::PyCodeRef;
6-
use super::objcoroinner::Coro;
6+
use super::objcoroinner::{Coro, Variant};
77
use super::objtype::PyClassRef;
88
use crate::frame::FrameRef;
99
use crate::function::OptionalArg;
@@ -32,7 +32,7 @@ impl PyGenerator {
3232

3333
pub fn new(frame: FrameRef, vm: &VirtualMachine) -> PyGeneratorRef {
3434
PyGenerator {
35-
inner: Coro::new(frame),
35+
inner: Coro::new(frame, Variant::Gen),
3636
}
3737
.into_ref(vm)
3838
}

0 commit comments

Comments
 (0)