← index #6174Issue #5882
Off-topic · high · value 2.264
QUERY · ISSUE

uasyncio: Code throws exception under CPython

openby peterhinchopened 2020-06-19updated 2020-06-21
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 gather return_exceptions=True does not return exceptions

closedby peterhinchopened 2020-04-08updated 2021-11-17
extmod

This script works as expected under CPython but not under MicroPython:

try:
    import uasyncio as asyncio
except ImportError:
    import asyncio

async def barking(n):
    print('Start barking')
    for _ in range(6):
        await asyncio.sleep(1)
    print('Done barking.')
    return 2 * n

async def foo(n):
    print('Start timeout coro foo()')
    while True:
        await asyncio.sleep(1)
        n += 1
    return n

async def bar(n):
    print('Start cancellable bar()')
    while True:
        await asyncio.sleep(1)
        n += 1
    return n

async def do_cancel(task):
    await asyncio.sleep(5)
    print('About to cancel bar')
    task.cancel()

async def main():
    tasks = [asyncio.create_task(bar(70))]
    tasks.append(barking(21))
    tasks.append(asyncio.wait_for(foo(10), 7))
    asyncio.create_task(do_cancel(tasks[0]))
    res = None
    try:
        res = await asyncio.gather(*tasks, return_exceptions=True)
    except asyncio.TimeoutError:
        print('Timeout')
    except asyncio.CancelledError:
        print('Cancelled')
    print('Result: ', res)

asyncio.run(main())

Under CPython:

Start cancellable bar()
Start barking
Start timeout coro foo()
About to cancel bar
Done barking.
Result:  [CancelledError(), 42, TimeoutError()]

MicroPython:

Start cancellable bar()
Start barking
Start timeout coro foo()
About to cancel bar
Cancelled
Result:  None

The cancelled exception has propagated to the caller and the timeout exception has apparently vanished.

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied