Hello, On Fri, 26 Mar 2021 16:19:26 -0700 Guido van Rossum <guido@python.org> wrote:
Everyone,
Given the resounding silence I'm inclined to submit this to the Steering Council. While I'm technically a co-author, Irit has done almost all the work, and she's done a great job. If there are no further issues I'll send this SC-wards on Monday.
One issue with PEP654 is that it introduces pretty adhoc and complex-semantics concept (ExceptionGroup) on the language level. Here's an idea (maybe duplicate) on how to introduce a much simpler, and more generic concept on the language level, and let particular frameworks to introduce (and elaborate without further changing the language) adhoc concept they need. So, let's look how the usual "except MyExc as e" works: it performs "isinstance(e0, MyExc)" operation, where e0 is incoming exception (roughly, sys.exc_info[1]), and if it returns True, then assigns e0 to the "e" variable and executes handler body. "isinstance(e0, MyExc)" is formally known as an "exception filter". As we see, currently Python hardcodes isinstance() as exception filter. The idea is to allow to use an explicit exception filter. Let's reuse the same "except *" syntax to specify it. Also, it's more flexible instead of returning True/False from filter, to return either None (filter didn't match), or an exception object to make available to handler (which in general may be different than passed to the filter). With this, ExceptionGroup usecases should be covered. Examples: 1. Current implicit exception filter is equivalent to: def implicit(e0, excs): # one or tuple, as usual if isinstance(e0, excs): return e0 return None try: 1/0 except *implicit(ZeroDivisionError) as e: print(e) 2. Allow to catch main or chained exception (context manager example from PEP) def chained(e, excs): while e: if isinstance(e, excs): return e e = e.__cause__ # Simplified, should consider __context__ too try: tempfile.TemporaryDirectory(...) except *chained(OSError) as e: print(e) 3. Rough example of ExceptionGroup functionality (now not a language builtin, just implemented by framework(s) which need it, or as a separate module): class ExceptionGroup: ... @staticmethod def match(e0, excs): cur, rest = e0.split_by_types(excs) # That's how we allow an exception handler to re-raise either an # original group in full or just "unhandled" exception in the # group (or anything) - everything should be passed via # exception attributes (or computed by methods). cur.org = e0 cur.rest = rest return cur try: ... except *ExceptionGroup.match((TypeError, ValueError)) as e: # try to handle a subgroup with (TypeError, ValueError) here ... # now reraise a subgroup with unhandled exceptions from the # original group raise e.rest
--Guido
On Sat, Mar 20, 2021 at 10:05 AM Irit Katriel <iritkatriel@googlemail.com> wrote:
We would like to present for feedback a new version of PEP 654, which incorporates the feedback we received in the discussions so far: https://www.python.org/dev/peps/pep-0654/ The reference implementation has also been updated along with the PEP.
The changes we made since the first post are:
1. Instead of ExceptionGroup(BaseException), we will have two new builtin types: BaseExceptionGroup(BaseException) and ExceptionGroup(BaseExceptionGroup, Exception). This is so that "except Exception" catches ExceptionGroups (but not BaseExceptionGroups). BaseExceptionGroup.__new__ inspects the wrapped exceptions, and if they are all Exception subclasses, it creates an ExceptionGroup instead of a BaseExceptionGroup.
2. The exception group classes are not final - they can be subclassed and split()/subgroup() work correctly if the subclass overrides the derive() instance method as described here: https://www.python.org/dev/peps/pep-0654/#subclassing-exception-groups
3. We had some good suggestions on formatting exception groups, which we have implemented as you can see in the output shown for the examples in the PEP.
4. We expanded the section on handling Exception Groups, to show how subgroup can be used (with side effects) to do something for each leaf exception, and how to iterate correctly when the tracebacks of leaf exceptions are needed: https://www.python.org/dev/peps/pep-0654/#handling-exception-groups
5. We expanded the sections on rationale and backwards compatibility to explain our premise and expectations regarding how exception groups will be used and how the transition to using them will be managed.
6. We added several items to the rejected ideas section.
We did not receive any comments (or make any changes) to the proposed semantics of except*, hopefully this is because everyone thought they are sensible.
Irit, Yury and Guido
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
-- Best regards, Paul mailto:pmiscml@gmail.com