Unexpected asyncio code exec between exc in task and call of global asyncio crash handler
Port, board and/or hardware
unix and esp32
MicroPython version
MicroPython v1.23.0-preview.436.gc8021842c
Reproduction
import asyncio
class Loop():
async def run(self):
print("---", self.__class__.__name__, "---")
async def run_forever(self):
while True:
try:
await self.run()
await asyncio.sleep(0.1)
except Exception as exc:
print("EEE", exc)
raise
class Loop_1(Loop):
pass
class Loop_2(Loop):
async def run(self):
await super().run()
raise Exception("MOEP!")
class Loop_3(Loop):
pass
def async_crash_hdlr(loop, ctx):
# called when unhandled exceptions thrown in asyncio tasks.
# this function is called from within a task running in the mainloop.
print("Global asyncio exception handler called -> FREEZE")
while True:
pass
async def main():
asyncio.get_event_loop().set_exception_handler(async_crash_hdlr)
loop1 = Loop_1()
loop2 = Loop_2()
loop3 = Loop_3()
print("Starting loop1")
asyncio.create_task(loop1.run_forever())
print("Starting loop2")
asyncio.create_task(loop2.run_forever())
print("Starting loop3")
asyncio.create_task(loop3.run_forever())
while True:
print("--- MAINLOOP ---")
await asyncio.sleep(1)
print("Entering main program")
asyncio.run(main())
Expected behaviour
Expected the defined global asyncio exception handler (async_crash_hdlr) being called immediately.
Expected output from above code (as per CPython3):
Entering main program
Starting loop1
Starting loop2
Starting loop3
--- MAINLOOP ---
--- Loop_1 ---
--- Loop_2 ---
EEE MOEP!
Global asyncio exception handler called -> FREEZE
Observed behaviour
Unexpected to me, between the exception being raised in Loop2 and async_crash_hdlr() being called, there is still asyncio code being executed, despite no fruther await or alike in between.
In this very case (code from) Loop3 is being run:
Entering main program
Starting loop1
Starting loop2
Starting loop3
--- MAINLOOP ---
--- Loop_1 ---
--- Loop_2 ---
EEE MOEP!
--- Loop_3 --- # <<<<<-------------------------
Global asyncio exception handler called -> FREEZE
Additional Information
No, I've provided everything above.
Code of Conduct
Yes, I agree
uasyncio Event unexpected behaviour with only one task
[EDIT] Apologies, @kevinkk525 has pointed out that this is a duplcate of https://github.com/micropython/micropython/issues/5843
This prints "start" then runs to completion where I would expect it to wait indefinitely on the Event:
import uasyncio as asyncio
evt = asyncio.Event()
async def main_loop():
while True:
print("start")
await evt.wait()
await asyncio.sleep(1)
print("Got event")
asyncio.run(main_loop())
If an additional task is running the main_loop task behaves as expected, waiting forever:
import uasyncio as asyncio
evt = asyncio.Event()
async def main_loop():
while True:
print("start")
await evt.wait()
await asyncio.sleep(1)
print("Got event")
async def main():
asyncio.create_task(main_loop())
while True:
await asyncio.sleep(1)
asyncio.run(main())