bpo-31787: Prevent refleaks when calling __init__() more than once (G… · python/cpython@d019bc8

@@ -458,13 +458,27 @@ future_schedule_callbacks(FutureObj *fut)

458458

return 0;

459459

}

460460461+461462

static int

462463

future_init(FutureObj *fut, PyObject *loop)

463464

{

464465

PyObject *res;

465466

int 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+468482

if (loop == Py_None) {

469483

loop = get_event_loop();

470484

if (loop == NULL) {

@@ -474,7 +488,7 @@ future_init(FutureObj *fut, PyObject *loop)

474488

else {

475489

Py_INCREF(loop);

476490

}

477-

Py_XSETREF(fut->fut_loop, loop);

491+

fut->fut_loop = loop;

478492479493

res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL);

480494

if (res == NULL) {

@@ -486,16 +500,12 @@ future_init(FutureObj *fut, PyObject *loop)

486500

return -1;

487501

}

488502

if (is_true) {

489-

Py_XSETREF(fut->fut_source_tb, _PyObject_CallNoArg(traceback_extract_stack));

503+

fut->fut_source_tb = _PyObject_CallNoArg(traceback_extract_stack);

490504

if (fut->fut_source_tb == NULL) {

491505

return -1;

492506

}

493507

}

494508495-

fut->fut_callback0 = NULL;

496-

fut->fut_context0 = NULL;

497-

fut->fut_callbacks = NULL;

498-499509

return 0;

500510

}

501511

@@ -1938,16 +1948,16 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop)

19381948

return -1;

19391949

}

194019501941-

self->task_context = PyContext_CopyCurrent();

1951+

Py_XSETREF(self->task_context, PyContext_CopyCurrent());

19421952

if (self->task_context == NULL) {

19431953

return -1;

19441954

}

194519551946-

self->task_fut_waiter = NULL;

1956+

Py_CLEAR(self->task_fut_waiter);

19471957

self->task_must_cancel = 0;

19481958

self->task_log_destroy_pending = 1;

19491959

Py_INCREF(coro);

1950-

self->task_coro = coro;

1960+

Py_XSETREF(self->task_coro, coro);

1951196119521962

if (task_call_step_soon(self, NULL)) {

19531963

return -1;