diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2020-05-13 23:18:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-13 23:18:27 (GMT) |
commit | 75cd8e48c62c97fdb9d9a94fd2335be06084471d (patch) | |
tree | bcd719b2442c302d0fb5100fb57894b6517ce090 /Objects | |
parent | d6fb53fe42d83a10f1372dd92ffaa6a01d2feffb (diff) | |
download | cpython-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.c | 22 |
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: |