Skip to content

Commit

Permalink
Backport gh-126091: Always link generator frames when propagating a t…
Browse files Browse the repository at this point in the history
…hrown-in exception through a yield-from chain

Reviewed By: alexmalyshev

Differential Revision: D66556446

fbshipit-source-id: 022f87d78d439efb1595e2c638cf91b976ab9ab1
  • Loading branch information
jbower-fb authored and facebook-github-bot committed Dec 7, 2024
1 parent 8a348b3 commit dcba50f
Showing 1 changed file with 15 additions and 10 deletions.
25 changes: 15 additions & 10 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -641,18 +641,15 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
return gen_send_ex(gen, Py_None, 1, 0);
goto throw_here;
}

PyThreadState *tstate = _PyThreadState_GET();
PyFrameObject *f = tstate->frame;
_PyShadowFrame *sf = tstate->shadow_frame;
_PyShadowFrame_PtrKind old_ptr_kind = _PyShadowFrame_GetPtrKind(sf);
if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) {
/* `yf` is a generator or a coroutine. */
PyThreadState *tstate = _PyThreadState_GET();
PyFrameObject *f = tstate->frame;
_PyShadowFrame *sf = tstate->shadow_frame;
_PyShadowFrame_PtrKind old_ptr_kind = _PyShadowFrame_GetPtrKind(sf);

/* 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. */

/* Link frame into the stack to enable complete backtraces. */
tstate->frame = gen->gi_frame;
tstate->shadow_frame = &gen->gi_shadow_frame;
/* Close the generator that we are currently iterating with
Expand All @@ -678,9 +675,17 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
Py_DECREF(yf);
goto throw_here;
}
tstate->frame = gen->gi_frame;
tstate->shadow_frame = &gen->gi_shadow_frame;
CI_WITH_GEN_MARKED_AS_THROWING(gen, {
ret = PyObject_CallFunctionObjArgs(meth, typ, val, tb, NULL);
});
if (old_ptr_kind != PYSF_PYFRAME && _PyShadowFrame_GetPtrKind(sf) == PYSF_PYFRAME) {
/* Frame was materialized while throwing into yf */
f = _PyShadowFrame_GetPyFrame(sf);
}
tstate->frame = f;
tstate->shadow_frame = sf;
Py_DECREF(meth);
}
Py_DECREF(yf);
Expand Down

0 comments on commit dcba50f

Please sign in to comment.