I am using Python 3.13.2.
I am going through the Python asyncio tutorial here. At around 10:20 timestamp, the instructor shows an example of asyncio.gather with a coroutine accepting a Future.
Here is a sample code that is not working for me using asyncio.gather. How to gather the results of multiple get_result calls?
In [162]: import asyncio
In [163]: from typing import Awaitable
In [164]: async def get_result(awaitable: Awaitable) -> str:
...: try:
...: result = await awaitable
...: except Exception as e:
...: print("oops!", e)
...: return "no result"
...: else:
...: return result
...:
In [165]: loop = asyncio.new_event_loop()
In [166]: f = asyncio.Future(loop=loop)
In [167]: loop.call_later(20, f.set_result, "final result")
...:
...: loop.run_until_complete(asyncio.gather(get_result(f), get_result(f), get_result(f)))
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
Cell In[167], line 3
1 loop.call_later(20, f.set_result, "final result")
----> 3 loop.run_until_complete(asyncio.gather(get_result(f), get_result(f), get_result(f)))
File /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/tasks.py:884, in gather(return_exceptions, *coros_or_futures)
882 for arg in coros_or_futures:
883 if arg not in arg_to_fut:
--> 884 fut = ensure_future(arg, loop=loop)
885 if loop is None:
886 loop = futures._get_loop(fut)
File /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/tasks.py:746, in ensure_future(coro_or_future, loop)
742 raise TypeError('An asyncio.Future, a coroutine or an awaitable '
743 'is required')
745 if loop is None:
--> 746 loop = events.get_event_loop()
747 try:
748 return loop.create_task(coro_or_future)
File /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/events.py:716, in BaseDefaultEventLoopPolicy.get_event_loop(self)
713 self.set_event_loop(self.new_event_loop())
715 if self._local._loop is None:
--> 716 raise RuntimeError('There is no current event loop in thread %r.'
717 % threading.current_thread().name)
719 return self._local._loop
RuntimeError: There is no current event loop in thread 'MainThread'.
I also tried using await asyncio.gather but got another error like below,
In [168]: loop = asyncio.new_event_loop()
In [169]: f = asyncio.Future(loop=loop)
In [170]: loop.call_later(10, f.set_result, "final result")
...:
...: await asyncio.gather(get_result(f))
oops! Task <Task pending name='Task-28075' coro=<get_result() running at <ipython-input-164-a1176dbd480d>:3> cb=[gather.<locals>._done_callback() at /Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/asyncio/tasks.py:820]> got Future <Future pending> attached to a different loop
Out[170]: ['no result']
It looks like asyncio.gather() is creating a task attached to a new loop instead of my created loop. Is it possible to use gather using my created loop?
The instructor's video is 5 years old and I assume asyncio have changed until now.