Just wanted to elaborate a little bit on StopIteration to add to Irit's reply: On Mon, Apr 5, 2021 at 9:52 AM Irit Katriel via Python-Dev <python-dev@python.org> wrote:
On Mon, Apr 5, 2021 at 11:01 AM Nathaniel Smith <njs@pobox.com> wrote:
- There are a number of places where the Python VM itself catches exceptions and has hard-coded handling for certain exception types. For example:
- Unhandled exceptions that reach the top of the main thread generally cause a traceback to be printed, but if the exception is SystemExit then the interpreter instead exits silently with status exc.args[0].
- 'for' loops call iter.__next__, and catch StopIteration while allowing other exceptions to escape.
- Generators catch StopIteration from their bodies and replace it with RuntimeError (PEP 479)
With this PEP, it's now possible for the main thread to terminate with ExceptionGroup(SystemExit), __next__ to raise ExceptionGroup(StopIteration), a generator to raise ExceptionGroup(StopIteration), either alone or mixed with other exceptions. How should the VM handle these new cases? Should they be using except* or except?
I don't think there's an obvious answer here, and possibly the answer is just "don't do that". But I feel like the PEP should say what the language semantics are in these cases, one way or another.
There's no need to do anything about ExceptionGroups potentially wrapping StopIteration or StopAsyncIteration exceptions. The point of PEP 479 was to solve a problem of one of nested frames raising a StopIteration (often by mistake) and the outer generator being stopped. That lead to some really tricky situations to debug. In our case, a rogue StopIteration wrapped in an EG would not stop a generator silently, it would do that loud and clear. As for SystemExit, we'll change "asyncio.run()" to unpack SystemExit and propagate them unwrapped, potentially allowing to dump the exception tree into a log file for later debug, if configured. Trio should do the same. Problem solved. It's important to understand that the PEP doesn't propose a magical mechanism to turn all exceptions into EGs automatically, it's up to the framework/user code how to build them and what to propagate out. In Python 3.9 you can just as well write `except BaseException: pass` and silence a SystemExit (and people do that from time to time!) Yury