erdewit/nest_asyncio

Infinite recursion when cancelling a task

christian-oudard opened this issue · 3 comments

When cancelling a task, something about nest_asyncio is causing an infinite recursion:

      Traceback:
      File "/usr/local/lib/python3.8/dist-packages/nest_asyncio.py", line 190, in run
        ctx.run(self._callback, *self._args)
      File "/usr/local/lib/python3.8/dist-packages/nest_asyncio.py", line 148, in step
        step_orig(task, exc)
      File "/usr/lib/python3.8/asyncio/tasks.py", line 319, in __step
        if self._fut_waiter.cancel():
      File "/usr/lib/python3.8/asyncio/tasks.py", line 254, in cancel
        if self._fut_waiter.cancel():
      File "/usr/lib/python3.8/asyncio/tasks.py", line 707, in cancel
        if child.cancel():
      File "/usr/lib/python3.8/asyncio/tasks.py", line 254, in cancel
        if self._fut_waiter.cancel():
      File "/usr/lib/python3.8/asyncio/tasks.py", line 254, in cancel
        if self._fut_waiter.cancel():
      File "/usr/lib/python3.8/asyncio/tasks.py", line 707, in cancel
        if child.cancel():
      ...
      File "/usr/lib/python3.8/asyncio/tasks.py", line 254, in cancel
        if self._fut_waiter.cancel():
      File "/usr/lib/python3.8/asyncio/tasks.py", line 250, in cancel
        self._log_traceback = False
      File "/usr/lib/python3.8/asyncio/futures.py", line 112, in _log_traceback
        if bool(val):
    <class 'RecursionError'>
    maximum recursion depth exceeded while calling a Python object

Any idea what could be causing this?

Can you post a code example that triggers this?

I am actually unable to reproduce the issue, and I suspect it involves a rare race condition. I was hoping you could help me understand how this could happen even in principle. Honestly, I don't know whether it is even a bug in nest_asyncio or not. The problem was triggered by a task.cancel() call, followed by await task. There are several tasks running concurrently, alongside an ib_insync client.

I don't think it's a race condition. A race between what? From looking at the code that the stack trace touches it doesn't seem related to nest_asyncio. It looks like a cyclical dependency between a task and a asyncio.gather of that task, where the task depends on the result of the gathering.