HACKER Q&A
📣 m3047

Ways to deal with Python 3.11 breaking change to asyncio


AFAICT 3.11 requires your code to call asyncio.run(), whereas earlier versions (for some definition of "earlier") required you to inject your coroutines and then call loop.run_forever().

Basically it smells to me like this is going to require two distinct main()s. This is ugly. How do I make it not butt ugly and minimize the general odor?


  👤 seanhunter Accepted Answer ✓
You don’t need two different mains. My asyncio code runs just fine on both and didn’t require changes when moving from 3.10 to 3.11 possibly because the way I always do it is asyncio.run(main()) from the body of the code (“actual main”) to an

   async def main
async callable and the last real line of that is pretty much always just an asyncio.gather over a bunch of other stuff that I want to run. My understanding is that’s been the recommended method for a very long time rather than get_event_loop or run_forever or anything like that.

edit: that is to say, asyncio.run() may be required now but the method of injecting coroutines and then doing run_forever was definitely not required before. Asyncio.run was available before 3.11.


👤 gabrielsroka
get_event_loop was deprecated in Python 3.10

  loop = asyncio.get_event_loop()
  loop.run_until_complete(main())
https://docs.python.org/3.10/library/asyncio-eventloop.html

👤 m3047
Let me break it down for you:

Suppose I run asyncio.start_server() and I want it to run forever. What am I supposed to asyncio.gather()) on without making stuff up?

[Edit] Production code or it didn't happen.


👤 tony-allan
An example and references to the 3.11 changelog would be helpful...