-
-
Notifications
You must be signed in to change notification settings - Fork 367
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.