Issue
I am using asyncio
for an application in a very basic way. Checking most tutorials around the internet (and even the official docs), I see that they use the get_event_loop()
and loop.run_until_complete()
:
import asyncio
async def say(what, when):
await asyncio.sleep(when)
print(what)
loop = asyncio.get_event_loop()
loop.run_until_complete(say('hello world', 1))
loop.close()
But in the Python 3.7 docs, we can read:
Application developers should typically use the high-level asyncio functions, such as asyncio.run(), and should rarely need to reference the loop object or call its methods. This section is intended mostly for authors of lower-level code, libraries, and frameworks, who need finer control over the event loop behavior.
I found it much cleaner and easier to use, but it only works for Python 3.7+. So here I would have to make a choice, whether to use Python 3.7+ and run()
or make it compatible with Python 3.6 and use the event loop. How would you manage this? Is there a simple way to make it backwards compatible with Python 3.6? Should I check Python version first and use either one way or another based on that, until Python 3.7 becomes a common version?
Solution
Is there a simple way to make [code making use of
asyncio.run
] backwards compatible with Python 3.6?
You can implement a simple substitute for asyncio.run
and call it on older Python versions:
import asyncio, sys, types
def run(coro):
if sys.version_info >= (3, 7):
return asyncio.run(coro)
# Emulate asyncio.run() on older versions
# asyncio.run() requires a coroutine, so require it here as well
if not isinstance(coro, types.CoroutineType):
raise TypeError("run() requires a coroutine object")
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
return loop.run_until_complete(coro)
finally:
loop.close()
asyncio.set_event_loop(None)
The advantage of this approach over just using loop.run_until_complete()
is that you're executing your code under the semantics close to those of the new asyncio.run
, even on older Python versions. (For example, you will always run on a freshly created event loop.) Dropping support for pre-3.7 Python will be as easy as removing the run
shim and calling asyncio.run
directly.
Answered By - user4815162342
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.