New submission from Johannes Ebke: In a very specific case, asyncio.gather causes a cancel() call on the Task waiting on the _GatheringFuture to return a false positive. An example program demonstrating this is attached.
The context: asyncio.gather creates a _GatheringFuture with a list of child Futures. Each child Future carries a done callback that updates the _GatheringFuture, and once the last child done callback is executed, the _GatheringFuture sets its result. The specific situation: When the last child future changes state to done it schedules its done callbacks, but does not immediately execute them. If the Task waiting on the gather is then cancelled before the last child done callback has run, the cancel method in asyncio/tasks.py:578 determines that the _GatheringFuture inspects itself and sees that it is not done() yet, and proceeds to cancel all child futures - which has no effect, since all of them are already done(). It still returns True, so the Tasks thinks all is well, and proceeds with its execution. The behaviour I would expect is that if cancel() is called on the _GatheringFuture, and all children return False on cancel(), then _GatheringFuture.cancel() should also return False, i.e.: def cancel(self): if self.done(): return False at_least_one_child_cancelled = False for child in self._children: if child.cancel(): at_least_one_child_cancelled = True return at_least_one_child_cancelled If I replace _GatheringFuture.cancel with the above variant, the bug disappears for me. More context: We hit this bug sporadically in an integration test of aioredis, where some timings conspired to make it appear with a chance of about 1 in 10. The minimal example calls the cancellation in a done_callback, so that it always hits the window. This was not the way the bug was discovered. ---------- components: asyncio files: cancellation_test.py messages: 264719 nosy: JohannesEbke, gvanrossum, haypo, yselivanov priority: normal severity: normal status: open title: asyncio.gather drops cancellation type: behavior versions: Python 3.5 Added file: http://bugs.python.org/file42694/cancellation_test.py _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue26923> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com