summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2020-07-09 13:27:23 (GMT)
committerGitHub <noreply@github.com>2020-07-09 13:27:23 (GMT)
commit8b33961e4bc4020d8b2d5b949ad9d5c669300e89 (patch)
treeabed35abb8d1696af9e068b6eeb44193ac4ed00f /Objects
parent96a6a6d42be272a27562d98549bbffc0d1854669 (diff)
downloadcpython-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.c10
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. */