QUERY · ISSUE
uasyncio: Code throws exception under CPython
extmod
MicroPython allows a task to be created before issuing .run() but CPython throws an exception.
try:
import uasyncio as asyncio
except ImportError:
import asyncio
async def foo():
await asyncio.sleep(3)
async def bar():
await foo_task
foo_task = asyncio.create_task(foo()) # Naughty code here...
asyncio.run(bar())
Outcome under CPython 3.8.0:
adminpete@debian8:/mnt/qnap2/temp$ python3 -m rats_x
Traceback (most recent call last):
File "/usr/local/lib/python3.8/runpy.py", line 192, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/local/lib/python3.8/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/mnt/qnap2/temp/rats_x.py", line 12, in <module>
foo_task = asyncio.create_task(foo())
File "/usr/local/lib/python3.8/asyncio/tasks.py", line 381, in create_task
loop = events.get_running_loop()
RuntimeError: no running event loop
sys:1: RuntimeWarning: coroutine 'foo' was never awaited
My view is that this doesn't matter, but I thought it worth reporting.
CANDIDATE · ISSUE
extmod/uasyncio Discrepancy between behaviour and docs
The doc for the class Task states:
Task.cancel()
Cancel the task by injecting a CancelledError into it. The task may or may not ignore this exception.
The following script produces identical results in CPython 3.8 and MicroPython, with no exception occurring in bar(). The script runs correctly apart from this.
Is there in fact a way to detect cancellation within a task, or are the docs wrong?
try:
import uasyncio as asyncio
except ImportError:
import asyncio
async def bar():
try:
while True:
print('Bar running')
await asyncio.sleep(1)
except Exception as e:
print('bar stopped.', e) # Never happens (CPython or mp)
async def main():
t = asyncio.create_task(bar())
await asyncio.sleep(2)
t.cancel()
await asyncio.sleep(1)
asyncio.run(main())
Detecting cancellation or timeouts within a task is actually very useful e.g. for cleanup, if there is a way to achieve it.