Catching StopIteration


I’m new to Trio and was looking for some help.

I have a generator that is ending via raising StopIteration and I want to catch the exception and shutdown elegantly, the following code works:

    async def func_called_by_run(self) -> None:
        # ... Startup code
        while True:
            gen = await ... # returns a generator
                consume(gen)  # Throws `StopIteration` when `gen` runs out.
            except RuntimeError as e:
                if e.args == ('generator raised StopIteration', ):
                raise e

Is there a better way?

The above is very fragile because the error message ('generator raised StopIteration', ) could change.

Thanks in advance for any help.


In general you can’t raise StopIteration from a generator, async function, or async generator (all three of which share substantial logic inside the Python interpreter). PEP 479 has the full rationale, but basically allowing StopIteration to escape was tending to suppress errors in unintended ways. The optimal approach would be to change the interface of gen so it uses a different exception to signal the thing you’re trying to notice. If that’s not possible, I don’t think you have any option except checking the message of the RuntimeError as you’re doing here.

Many thanks for that PEP reference, I didn’t know that! I thought it was trio doing the exception wrapping. Great help. Thanks again, Howard.