diff --git a/extmod/uasyncio/funcs.py b/extmod/uasyncio/funcs.py index 93f4fd256c..0ce48b015c 100644 --- a/extmod/uasyncio/funcs.py +++ b/extmod/uasyncio/funcs.py @@ -66,7 +66,7 @@ async def gather(*aws, return_exceptions=False): # # cancel all waiting tasks # raise er ts[i] = await ts[i] - except Exception as er: + except (core.CancelledError, Exception) as er: if return_exceptions: ts[i] = er else: diff --git a/tests/extmod/uasyncio_gather.py b/tests/extmod/uasyncio_gather.py index 0e2948b07c..6053873dbc 100644 --- a/tests/extmod/uasyncio_gather.py +++ b/tests/extmod/uasyncio_gather.py @@ -22,8 +22,9 @@ async def factorial(name, number): async def task(id): print("start", id) - await asyncio.sleep(0.2) + await asyncio.sleep(0.02) print("end", id) + return id async def gather_task(): @@ -36,12 +37,17 @@ async def main(): # Simple gather with return values print(await asyncio.gather(factorial("A", 2), factorial("B", 3), factorial("C", 4))) + # Test return_exceptions, where one task is cancelled and the other finishes normally + tasks = [asyncio.create_task(task(1)), asyncio.create_task(task(2))] + tasks[0].cancel() + print(await asyncio.gather(*tasks, return_exceptions=True)) + # Cancel a multi gather # TODO doesn't work, Task should not forward cancellation from gather to sub-task # but rather CancelledError should cancel the gather directly, which will then cancel # all sub-tasks explicitly # t = asyncio.create_task(gather_task()) - # await asyncio.sleep(0.1) + # await asyncio.sleep(0.01) # t.cancel() # await asyncio.sleep(0.01) diff --git a/tests/extmod/uasyncio_gather.py.exp b/tests/extmod/uasyncio_gather.py.exp index a37578d7eb..95310bbe1c 100644 --- a/tests/extmod/uasyncio_gather.py.exp +++ b/tests/extmod/uasyncio_gather.py.exp @@ -8,3 +8,6 @@ Task B: factorial(3) = 6 Task C: Compute factorial(4)... Task C: factorial(4) = 24 [2, 6, 24] +start 2 +end 2 +[CancelledError(), 2]