mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-29587: Make gen.throw() chain exceptions with yield from (GH-19858)
The previous commits on bpo-29587 got exception chaining working with gen.throw() in the `yield` case. This patch also gets the `yield from` case working. As a consequence, implicit exception chaining now also works in the asyncio scenario of awaiting on a task when an exception is already active. Tests are included for both the asyncio case and the pure generator-only case.
This commit is contained in:
parent
d6fb53fe42
commit
75cd8e48c6
3 changed files with 57 additions and 11 deletions
|
@ -217,6 +217,18 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
|
|||
assert(f->f_back == NULL);
|
||||
f->f_back = tstate->frame;
|
||||
|
||||
_PyErr_StackItem *gi_exc_state = &gen->gi_exc_state;
|
||||
if (exc && gi_exc_state->exc_type != NULL &&
|
||||
gi_exc_state->exc_type != Py_None)
|
||||
{
|
||||
Py_INCREF(gi_exc_state->exc_type);
|
||||
Py_XINCREF(gi_exc_state->exc_value);
|
||||
Py_XINCREF(gi_exc_state->exc_traceback);
|
||||
_PyErr_ChainExceptions(gi_exc_state->exc_type,
|
||||
gi_exc_state->exc_value,
|
||||
gi_exc_state->exc_traceback);
|
||||
}
|
||||
|
||||
gen->gi_running = 1;
|
||||
gen->gi_exc_state.previous_item = tstate->exc_info;
|
||||
tstate->exc_info = &gen->gi_exc_state;
|
||||
|
@ -512,16 +524,6 @@ throw_here:
|
|||
}
|
||||
|
||||
PyErr_Restore(typ, val, tb);
|
||||
|
||||
_PyErr_StackItem *gi_exc_state = &gen->gi_exc_state;
|
||||
if (gi_exc_state->exc_type != NULL && gi_exc_state->exc_type != Py_None) {
|
||||
Py_INCREF(gi_exc_state->exc_type);
|
||||
Py_XINCREF(gi_exc_state->exc_value);
|
||||
Py_XINCREF(gi_exc_state->exc_traceback);
|
||||
_PyErr_ChainExceptions(gi_exc_state->exc_type,
|
||||
gi_exc_state->exc_value,
|
||||
gi_exc_state->exc_traceback);
|
||||
}
|
||||
return gen_send_ex(gen, Py_None, 1, 0);
|
||||
|
||||
failed_throw:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue