@@ -462,11 +462,13 @@ and may be removed in a future version of Python.");
462462
463463static PyObject *
464464_gen_throw (PyGenObject * gen , int close_on_genexit ,
465- PyObject * typ , PyObject * val , PyObject * tb )
465+ PyObject * typ , PyObject * val , PyObject * tb ,
466+ PyObject * exc_context )
466467{
467468 PyObject * yf = _PyGen_yf (gen );
468469
469470 if (yf ) {
471+ assert (exc_context == NULL );
470472 _PyInterpreterFrame * frame = & gen -> gi_iframe ;
471473 PyObject * ret ;
472474 int err ;
@@ -502,7 +504,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
502504 PyFrameState state = gen -> gi_frame_state ;
503505 gen -> gi_frame_state = FRAME_EXECUTING ;
504506 ret = _gen_throw ((PyGenObject * )yf , close_on_genexit ,
505- typ , val , tb );
507+ typ , val , tb , NULL );
506508 gen -> gi_frame_state = state ;
507509 tstate -> current_frame = prev ;
508510 frame -> previous = NULL ;
@@ -581,8 +583,17 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
581583 goto failed_throw ;
582584 }
583585
586+ /* hide the current thread's exception context from the generator */
587+ PyThreadState * tstate = _PyThreadState_GET ();
588+ assert (tstate != NULL );
589+ PyObject * prev_exc = tstate -> exc_info -> exc_value ;
590+ tstate -> exc_info -> exc_value = (exc_context == NULL ? Py_None : exc_context );
591+
584592 PyErr_Restore (typ , val , tb );
585- return gen_send_ex (gen , Py_None , 1 , 0 );
593+ PyObject * ret = gen_send_ex (gen , Py_None , 1 , 0 );
594+
595+ tstate -> exc_info -> exc_value = prev_exc ;
596+ return ret ;
586597
587598failed_throw :
588599 /* Didn't use our arguments, so restore their original refcounts */
@@ -648,10 +659,7 @@ gen_throw(PyObject *op, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnam
648659 return NULL ;
649660 }
650661 }
651- // update the generator's current exception context before throwing the
652- // exception into it
653- PyErr_SetHandledException (exc_context == NULL ? Py_None : exc_context );
654- return _gen_throw (gen , 1 , typ , val , tb );
662+ return _gen_throw (gen , 1 , typ , val , tb , exc_context );
655663}
656664
657665
@@ -2182,7 +2190,7 @@ async_gen_athrow_send(PyObject *self, PyObject *arg)
21822190 retval = _gen_throw ((PyGenObject * )gen ,
21832191 0 , /* Do not close generator when
21842192 PyExc_GeneratorExit is passed */
2185- PyExc_GeneratorExit , NULL , NULL );
2193+ PyExc_GeneratorExit , NULL , NULL , NULL );
21862194
21872195 if (retval && _PyAsyncGenWrappedValue_CheckExact (retval )) {
21882196 Py_DECREF (retval );
@@ -2201,7 +2209,7 @@ async_gen_athrow_send(PyObject *self, PyObject *arg)
22012209 retval = _gen_throw ((PyGenObject * )gen ,
22022210 0 , /* Do not close generator when
22032211 PyExc_GeneratorExit is passed */
2204- typ , val , tb );
2212+ typ , val , tb , NULL );
22052213 retval = async_gen_unwrap_value (o -> agt_gen , retval );
22062214 }
22072215 if (retval == NULL ) {
0 commit comments