diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2020-07-09 13:27:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-09 13:27:23 (GMT) |
commit | 8b33961e4bc4020d8b2d5b949ad9d5c669300e89 (patch) | |
tree | abed35abb8d1696af9e068b6eeb44193ac4ed00f /Objects | |
parent | 96a6a6d42be272a27562d98549bbffc0d1854669 (diff) | |
download | cpython-8b33961e4bc4020d8b2d5b949ad9d5c669300e89.zip cpython-8b33961e4bc4020d8b2d5b949ad9d5c669300e89.tar.gz cpython-8b33961e4bc4020d8b2d5b949ad9d5c669300e89.tar.bz2 |
bpo-29590: fix stack trace for gen.throw() with yield from (#19896)
* Add failing test.
* bpo-29590: fix stack trace for gen.throw() with yield from (GH-NNNN)
When gen.throw() is called on a generator after a "yield from", the
intermediate stack trace entries are lost. This commit fixes that.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/genobject.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/Objects/genobject.c b/Objects/genobject.c index 6a68c94..a379fa6 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -415,11 +415,21 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) { /* `yf` is a generator or a coroutine. */ + PyThreadState *tstate = _PyThreadState_GET(); + PyFrameObject *f = tstate->frame; + gen->gi_running = 1; + /* Since we are fast-tracking things by skipping the eval loop, + we need to update the current frame so the stack trace + will be reported correctly to the user. */ + /* XXX We should probably be updating the current frame + somewhere in ceval.c. */ + tstate->frame = gen->gi_frame; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); + tstate->frame = f; gen->gi_running = 0; } else { /* `yf` is an iterator or a coroutine-like object. */ |