Skip to content

Commit 82f53cc

Browse files
fix callbacks to copy it always
1 parent b0f96d7 commit 82f53cc

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

Lib/test/test_asyncio/test_futures.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,17 @@ def test_future_del_segfault(self):
697697
with self.assertRaises(AttributeError):
698698
del fut._log_traceback
699699

700+
def test_callbacks_copy(self):
701+
fut = self._new_future(loop=self.loop)
702+
f1 = lambda _: 1
703+
f2 = lambda _: 2
704+
fut.add_done_callback(f1)
705+
fut.add_done_callback(f2)
706+
callbacks = fut._callbacks
707+
self.assertIsNot(callbacks, fut._callbacks)
708+
fut.remove_done_callback(f1)
709+
self.assertIsNot(callbacks, fut._callbacks)
710+
700711

701712
@unittest.skipUnless(hasattr(futures, '_CFuture'),
702713
'requires the C _asyncio module')

Modules/_asynciomodule.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,10 +1267,6 @@ FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored))
12671267
asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut);
12681268
ENSURE_FUTURE_ALIVE(state, fut)
12691269

1270-
if (fut->fut_callback0 == NULL && fut->fut_callbacks == NULL) {
1271-
Py_RETURN_NONE;
1272-
}
1273-
12741270
Py_ssize_t len = 0;
12751271
if (fut->fut_callback0 != NULL) {
12761272
len++;
@@ -1279,6 +1275,10 @@ FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored))
12791275
len += PyList_GET_SIZE(fut->fut_callbacks);
12801276
}
12811277

1278+
if (len == 0) {
1279+
Py_RETURN_NONE;
1280+
}
1281+
12821282
PyObject *callbacks = PyList_New(len);
12831283
if (callbacks == NULL) {
12841284
return NULL;

0 commit comments

Comments
 (0)