mirror of https://github.com/python/cpython
GH-100964: Break cycles involving exception state when returning from generator (GH-107563)
This commit is contained in:
parent
dd693d6320
commit
0d30a5a409
|
@ -0,0 +1,2 @@
|
||||||
|
Clear generators' exception state after ``return`` to break reference
|
||||||
|
cycles.
|
|
@ -149,14 +149,16 @@ gen_dealloc(PyGenObject *gen)
|
||||||
gen->gi_frame_state = FRAME_CLEARED;
|
gen->gi_frame_state = FRAME_CLEARED;
|
||||||
frame->previous = NULL;
|
frame->previous = NULL;
|
||||||
_PyFrame_ClearExceptCode(frame);
|
_PyFrame_ClearExceptCode(frame);
|
||||||
|
_PyErr_ClearExcState(&gen->gi_exc_state);
|
||||||
}
|
}
|
||||||
|
assert(gen->gi_exc_state.exc_value == NULL);
|
||||||
if (_PyGen_GetCode(gen)->co_flags & CO_COROUTINE) {
|
if (_PyGen_GetCode(gen)->co_flags & CO_COROUTINE) {
|
||||||
Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer);
|
Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer);
|
||||||
}
|
}
|
||||||
Py_DECREF(_PyGen_GetCode(gen));
|
Py_DECREF(_PyGen_GetCode(gen));
|
||||||
Py_CLEAR(gen->gi_name);
|
Py_CLEAR(gen->gi_name);
|
||||||
Py_CLEAR(gen->gi_qualname);
|
Py_CLEAR(gen->gi_qualname);
|
||||||
_PyErr_ClearExcState(&gen->gi_exc_state);
|
|
||||||
PyObject_GC_Del(gen);
|
PyObject_GC_Del(gen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,10 +254,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult,
|
||||||
!PyErr_ExceptionMatches(PyExc_StopAsyncIteration));
|
!PyErr_ExceptionMatches(PyExc_StopAsyncIteration));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generator can't be rerun, so release the frame */
|
assert(gen->gi_exc_state.exc_value == NULL);
|
||||||
/* first clean reference cycle through stored exception traceback */
|
|
||||||
_PyErr_ClearExcState(&gen->gi_exc_state);
|
|
||||||
|
|
||||||
assert(gen->gi_frame_state == FRAME_CLEARED);
|
assert(gen->gi_frame_state == FRAME_CLEARED);
|
||||||
*presult = result;
|
*presult = result;
|
||||||
return result ? PYGEN_RETURN : PYGEN_ERROR;
|
return result ? PYGEN_RETURN : PYGEN_ERROR;
|
||||||
|
|
|
@ -1466,6 +1466,7 @@ clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
|
||||||
tstate->c_recursion_remaining--;
|
tstate->c_recursion_remaining--;
|
||||||
assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame);
|
assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame);
|
||||||
_PyFrame_ClearExceptCode(frame);
|
_PyFrame_ClearExceptCode(frame);
|
||||||
|
_PyErr_ClearExcState(&gen->gi_exc_state);
|
||||||
tstate->c_recursion_remaining++;
|
tstate->c_recursion_remaining++;
|
||||||
frame->previous = NULL;
|
frame->previous = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue