-
-
Notifications
You must be signed in to change notification settings - Fork 371
Closed
Labels
Description
If we break out of a loop over some receive-channel created with @trio.as_safe_channel, the async generator will be cleaned up in the background, and indeed this works:
import trio
async def main():
async with inner_generator() as recv_chan:
async for _ in recv_chan:
break # Early exit
@trio.as_safe_channel
async def inner_generator():
try:
for x in range(10):
await trio.lowlevel.checkpoint()
yield x
except BaseException: # breaks if `except*`!
raise
await trio.lowlevel.checkpoint()
trio.run(main)...unless you use except*.
Add one little * to the program above, and we instead crash with a BaseExceptionGroup(..., [GeneratorExit()]) - and if you have an outer generator wrapping around the inner one, you'll instead see our BaseExceptionGroup: Encountered exception during cleanup of generator object, as well as exception in the contextmanager body - unable to unwrap error.
Inserting if eg.subgroup(GeneratorExit): raise GeneratorExit from eg before the inner try: block here fixes this issue and I think is the right approach, but I'd love to hear your takes.