bpo-29590: fix stack trace for gen.throw() with yield from (GH-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.
(cherry picked from commit 8b33961e4bc4020d8b2d5b949ad9d5c669300e89)

Co-authored-by: Chris Jerdonek <chris.jerdonek@gmail.com>
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 09efbab..72c93f6 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -414,11 +414,21 @@
         }
         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. */