summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2020-05-13 23:18:27 (GMT)
committerGitHub <noreply@github.com>2020-05-13 23:18:27 (GMT)
commit75cd8e48c62c97fdb9d9a94fd2335be06084471d (patch)
treebcd719b2442c302d0fb5100fb57894b6517ce090 /Objects
parentd6fb53fe42d83a10f1372dd92ffaa6a01d2feffb (diff)
downloadcpython-75cd8e48c62c97fdb9d9a94fd2335be06084471d.zip
cpython-75cd8e48c62c97fdb9d9a94fd2335be06084471d.tar.gz
cpython-75cd8e48c62c97fdb9d9a94fd2335be06084471d.tar.bz2
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.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/genobject.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 5b253ed..fb01e58 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -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: