File tree
Lib/test
Misc/NEWS.d/next/Core_and_Builtins
Objects
Python
Original file line numberDiff line numberDiff line change@@ -2265,6 +2265,20 @@ def c():
22652265# before fixing, visible stack from throw would be shorter than from send.
22662266self.assertEqual(len_send, len_throw)
226722672268+deftest_call_generator_in_frame_clear(self):
2269+# gh-143939: Running a generator while clearing the coroutine's frame
2270+# should not be misinterpreted as a yield.
2271+classCallGeneratorOnDealloc:
2272+def__del__(self):
2273+next(xforxin [1])
2274+2275+asyncdefcoro():
2276+obj=CallGeneratorOnDealloc()
2277+return42
2278+2279+yielded, result=run_async(coro())
2280+self.assertEqual(yielded, [])
2281+self.assertEqual(result, 42)
22702284support.is_emscriptenorsupport.is_wasi,
Original file line numberDiff line numberDiff line change@@ -0,0 +1,3 @@
1+Fix erroneous "cannot reuse already awaited coroutine" error that could
2+occur when a generator was run during the process of clearing a coroutine's
3+frame.
Original file line numberDiff line numberDiff line change@@ -280,6 +280,9 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, int exc)
280280281281if (return_kind==GENERATOR_YIELD) {
282282assert(result!=NULL&& !_PyErr_Occurred(tstate));
283+#ifndefPy_GIL_DISABLED
284+assert(FRAME_STATE_SUSPENDED(gen->gi_frame_state));
285+#endif
283286*presult=result;
284287returnPYGEN_NEXT;
285288 }
Original file line numberDiff line numberDiff line change@@ -1914,14 +1914,16 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
19141914assert(frame->owner==FRAME_OWNED_BY_GENERATOR);
19151915PyGenObject*gen=_PyGen_GetGeneratorFromFrame(frame);
19161916FT_ATOMIC_STORE_INT8_RELEASE(gen->gi_frame_state, FRAME_CLEARED);
1917- ((_PyThreadStateImpl*)tstate)->generator_return_kind=GENERATOR_RETURN;
19181917assert(tstate->exc_info==&gen->gi_exc_state);
19191918tstate->exc_info=gen->gi_exc_state.previous_item;
19201919gen->gi_exc_state.previous_item=NULL;
19211920assert(frame->frame_obj==NULL||frame->frame_obj->f_frame==frame);
19221921frame->previous=NULL;
19231922_PyFrame_ClearExceptCode(frame);
19241923_PyErr_ClearExcState(&gen->gi_exc_state);
1924+// gh-143939: There must not be any escaping calls between setting
1925+// the generator return kind and returning from _PyEval_EvalFrame.
1926+ ((_PyThreadStateImpl*)tstate)->generator_return_kind=GENERATOR_RETURN;
19251927}
1926192819271929void