forked from Rust-related/RustPython
Separate coro exception stack
This commit is contained in:
@@ -716,8 +716,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
print_error()
|
||||
# implicit "del e" here
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generator_leaking(self):
|
||||
# Test that generator exception state doesn't leak into the calling
|
||||
# frame
|
||||
@@ -748,8 +746,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
del g
|
||||
self.assertEqual(sys.exc_info()[0], TypeError)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generator_leaking2(self):
|
||||
# See issue 12475.
|
||||
def g():
|
||||
@@ -765,8 +761,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
pass
|
||||
self.assertEqual(sys.exc_info(), (None, None, None))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generator_leaking3(self):
|
||||
# See issue #23353. When gen.throw() is called, the caller's
|
||||
# exception state should be save and restored.
|
||||
@@ -786,7 +780,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
self.assertIs(gen_exc, e)
|
||||
self.assertEqual(sys.exc_info(), (None, None, None))
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON")
|
||||
def test_generator_leaking4(self):
|
||||
# See issue #23353. When an exception is raised by a generator,
|
||||
# the caller's exception state should still be restored.
|
||||
@@ -814,8 +807,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
# We used to find TypeError here.
|
||||
self.assertEqual(sys.exc_info(), (None, None, None))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generator_doesnt_retain_old_exc(self):
|
||||
def g():
|
||||
self.assertIsInstance(sys.exc_info()[1], RuntimeError)
|
||||
@@ -828,8 +819,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
next(it)
|
||||
self.assertRaises(StopIteration, next, it)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generator_finalizing_and_exc_info(self):
|
||||
# See #7173
|
||||
def simple_gen():
|
||||
@@ -881,8 +870,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
g.close()
|
||||
self._check_generator_cleanup_exc_state(do_close)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generator_del_cleanup_exc_state(self):
|
||||
def do_del(g):
|
||||
g = None
|
||||
@@ -1303,8 +1290,6 @@ class ExceptionTests(unittest.TestCase):
|
||||
with self.assertRaises(MainError):
|
||||
coro.throw(SubError())
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generator_doesnt_retain_old_exc2(self):
|
||||
#Issue 28884#msg282532
|
||||
def g():
|
||||
|
||||
@@ -4,13 +4,14 @@ use crate::frame::{ExecutionResult, FrameRef};
|
||||
use crate::pyobject::{PyObjectRef, PyResult};
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Coro {
|
||||
frame: FrameRef,
|
||||
closed: Cell<bool>,
|
||||
running: Cell<bool>,
|
||||
exceptions: RefCell<Vec<PyBaseExceptionRef>>,
|
||||
}
|
||||
|
||||
impl Coro {
|
||||
@@ -19,6 +20,7 @@ impl Coro {
|
||||
frame,
|
||||
closed: Cell::new(false),
|
||||
running: Cell::new(false),
|
||||
exceptions: RefCell::new(vec![]),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,15 +31,32 @@ impl Coro {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_with_context<F>(&self, func: F, vm: &VirtualMachine) -> PyResult<ExecutionResult>
|
||||
where
|
||||
F: FnOnce() -> PyResult<ExecutionResult>,
|
||||
{
|
||||
self.running.set(true);
|
||||
let curr_exception_stack_len = vm.exceptions.borrow().len();
|
||||
vm.exceptions
|
||||
.borrow_mut()
|
||||
.append(&mut self.exceptions.borrow_mut());
|
||||
let result = func();
|
||||
self.exceptions.replace(
|
||||
vm.exceptions
|
||||
.borrow_mut()
|
||||
.split_off(curr_exception_stack_len),
|
||||
);
|
||||
self.running.set(false);
|
||||
result
|
||||
}
|
||||
|
||||
pub fn send(&self, value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
if self.closed.get() {
|
||||
return Err(objiter::new_stop_iteration(vm));
|
||||
}
|
||||
|
||||
self.frame.push_value(value.clone());
|
||||
self.running.set(true);
|
||||
let result = vm.run_frame(self.frame.clone());
|
||||
self.running.set(false);
|
||||
let result = self.run_with_context(|| vm.run_frame(self.frame.clone()), vm);
|
||||
self.maybe_close(&result);
|
||||
result?.into_result(vm)
|
||||
}
|
||||
@@ -53,9 +72,9 @@ impl Coro {
|
||||
return Err(exceptions::normalize(exc_type, exc_val, exc_tb, vm)?);
|
||||
}
|
||||
vm.frames.borrow_mut().push(self.frame.clone());
|
||||
let result =
|
||||
self.run_with_context(|| self.frame.gen_throw(vm, exc_type, exc_val, exc_tb), vm);
|
||||
self.running.set(true);
|
||||
let result = self.frame.gen_throw(vm, exc_type, exc_val, exc_tb);
|
||||
self.running.set(false);
|
||||
self.maybe_close(&result);
|
||||
vm.frames.borrow_mut().pop();
|
||||
result?.into_result(vm)
|
||||
@@ -67,13 +86,17 @@ impl Coro {
|
||||
}
|
||||
vm.frames.borrow_mut().push(self.frame.clone());
|
||||
self.running.set(true);
|
||||
let result = self.frame.gen_throw(
|
||||
let result = self.run_with_context(
|
||||
|| {
|
||||
self.frame.gen_throw(
|
||||
vm,
|
||||
vm.ctx.exceptions.generator_exit.clone().into_object(),
|
||||
vm.get_none(),
|
||||
vm.get_none(),
|
||||
)
|
||||
},
|
||||
vm,
|
||||
vm.ctx.exceptions.generator_exit.clone().into_object(),
|
||||
vm.get_none(),
|
||||
vm.get_none(),
|
||||
);
|
||||
self.running.set(false);
|
||||
vm.frames.borrow_mut().pop();
|
||||
self.closed.set(true);
|
||||
match result {
|
||||
|
||||
Reference in New Issue
Block a user