On 2/23/21 1:24 AM, Irit Katriel via Python-Dev wrote:
We would like to request feedback on PEP 654 -- Exception Groups and except*.
Thank you for this PEP!
Also, thank you Nathaniel (and possibly other author(s) of Trio – sadly, I'm not following closely enough to track contributions) for doing things right even though it's hard (and slow), and documenting your work beautifully. I'm glad to see the ideas assimilated into Python & asyncio!
The PEP reminds me of PEP 380 (yield from): it looks like syntax sugar for code you could already write, but once you look closer, it turns out that there are so many details and corner cases to keep track of, getting it correct is very hard.
I kept notes as I read the PEP, then deleted most as I went through Rejected Ideas. These remained:
The `ExceptionGroup` class is final, i.e., it cannot be subclassed.
What's the rationale for this?
It is possible to catch the ExceptionGroup type with except, but not
with except* because the latter is ambiguous
What about `except *(TypeError, ExceptionGroup):`?
Motivation: Errors in wrapper code
This use case sticks out a bit: it's the only one where ExceptionGroup doesn't represent joining equivalent tasks. Consider code similar to bpo-40857:
try: with TemporaryDirectory() as tempdir: os.rmdir(tempdir) n = 1 / 0 except ArithmeticError: # that error can be safely ignored! pass
Instead of a FileNotFoundError with ArithmeticError for context you'd now get an ExceptionGroup. Neither is handled by `except ArithmeticError`. Where is the win?
Motivation: Multiple failures when retrying an operation
This is somewhat similar to the TemporaryDirectory, except there's no `with` block that feels like it should be "transparent" w.r.t. user errors. If I currently have:
try: create_connection(*addresses) except (Timeout, NetworkNotConnected): # that's OK, let's try later pass
what should happen after Python 3.10? Apart from adding a new function, I can see two possible changes: - create_connection() starts always raising ExceptionGroup on error, breaking backwards compatibility in the error case - create_connection() starts only raising ExceptionGroup only for 2+ errors, breaking backwards compatibility in the 2+ errors case
Both look like heisenbug magnets. IMO, the second one is worse; "code which is now *potentially* raising ExceptionGroup" (as mentioned in the Backwards Compatibility section; emphasis mine) should be discouraged.
Arguably, this here is a problem with the create_connection function: the PEP adds a better way how it could have been designed, and that is virtuous. Still, having it in Motivation might be misleading.
long term plan to replace `except` by `catch`
Whoa! Is that a real plan?