bpo-31787: Prevent refleaks when calling __init__() more than once (G… · python/cpython@d019bc8
@@ -458,13 +458,27 @@ future_schedule_callbacks(FutureObj *fut)
458458return 0;
459459}
460460461+461462static int
462463future_init(FutureObj *fut, PyObject *loop)
463464{
464465PyObject *res;
465466int is_true;
466467_Py_IDENTIFIER(get_debug);
467468469+// Same to FutureObj_clear() but not clearing fut->dict
470+Py_CLEAR(fut->fut_loop);
471+Py_CLEAR(fut->fut_callback0);
472+Py_CLEAR(fut->fut_context0);
473+Py_CLEAR(fut->fut_callbacks);
474+Py_CLEAR(fut->fut_result);
475+Py_CLEAR(fut->fut_exception);
476+Py_CLEAR(fut->fut_source_tb);
477+478+fut->fut_state = STATE_PENDING;
479+fut->fut_log_tb = 0;
480+fut->fut_blocking = 0;
481+468482if (loop == Py_None) {
469483loop = get_event_loop();
470484if (loop == NULL) {
@@ -474,7 +488,7 @@ future_init(FutureObj *fut, PyObject *loop)
474488else {
475489Py_INCREF(loop);
476490 }
477-Py_XSETREF(fut->fut_loop, loop);
491+fut->fut_loop = loop;
478492479493res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL);
480494if (res == NULL) {
@@ -486,16 +500,12 @@ future_init(FutureObj *fut, PyObject *loop)
486500return -1;
487501 }
488502if (is_true) {
489-Py_XSETREF(fut->fut_source_tb, _PyObject_CallNoArg(traceback_extract_stack));
503+fut->fut_source_tb = _PyObject_CallNoArg(traceback_extract_stack);
490504if (fut->fut_source_tb == NULL) {
491505return -1;
492506 }
493507 }
494508495-fut->fut_callback0 = NULL;
496-fut->fut_context0 = NULL;
497-fut->fut_callbacks = NULL;
498-499509return 0;
500510}
501511@@ -1938,16 +1948,16 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)
19381948return -1;
19391949 }
194019501941-self->task_context = PyContext_CopyCurrent();
1951+Py_XSETREF(self->task_context, PyContext_CopyCurrent());
19421952if (self->task_context == NULL) {
19431953return -1;
19441954 }
194519551946-self->task_fut_waiter = NULL;
1956+Py_CLEAR(self->task_fut_waiter);
19471957self->task_must_cancel = 0;
19481958self->task_log_destroy_pending = 1;
19491959Py_INCREF(coro);
1950-self->task_coro = coro;
1960+Py_XSETREF(self->task_coro, coro);
1951196119521962if (task_call_step_soon(self, NULL)) {
19531963return -1;