Issue
I am trying to call an async function from exec, I would expect it to work like:
def test():
print("test")
exec('def test2():\n print("test")\ntest2()')
test()
Output:
test
test
So a function defined in exec is able to call itself, however we can't do such things in asyncio as:
async def test():
print("test")
exec('async def test2():\n print("test")\nawait test2()')
We cant use await outside function as well as we cant call another loop from a running loop:
async def test():
print("test")
exec('async def test2():\n print("test")\nasyncio.run(test2())')
Is there any solution to this problem?
Solution
You can put current running loop as exec()
global parameter:
import asyncio
async def test():
print("test")
loop = asyncio.get_running_loop()
exec('async def test2():\n print("test2")\nloop.create_task(test2())', {'loop': loop})
asyncio.run(test())
Prints:
test
test2
EDIT: To run asynchronously, you can return awaitable from the exec()
:
import asyncio
async def some_other_task():
await asyncio.sleep(1)
print('some_other_task')
async def test():
loop = asyncio.get_running_loop()
t = [None]
exec('async def test2():\n await asyncio.sleep(3);print("task in exec finished")\nt[0] = loop.create_task(test2())', {'asyncio': asyncio, 'loop': loop, 't': t})
await asyncio.gather(some_other_task(), t[0])
asyncio.run(test())
Prints:
some_other_task # <-- after 1 sec
task in exec finished # <-- after 3 sec
Answered By - Andrej Kesely
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.