Hello, On Sat, 27 Mar 2021 20:01:27 +0000 Irit Katriel <iritkatriel@googlemail.com> wrote: []
you gentlemen come up with the "ultimate" way to deal with multiple errors,
I've been mistaken for a man before, but no-one has ever confused me for gentle. I'll take that as a compliment.
Sorry, was just a figure of speech ;-). []
Pluggable is not without its problems. I'm all in favor of you developing this idea and proposing an alternative. As I said before, you just need to answer two questions: 1. show a limitation of our approach (the contrived flat-set is not one - see below) 2. describe how a pluggable approach works for that case
As I mentioned, I wanted to share concern about adding complex, arguably special-purpose semantics to the core language, and back that by an example on how to address some (not all) points of PEP 645 in a more lightweight (on the language more manner). It's hard to show a technical limitation of your approach - because again, it's already complex and special-purpose, and I can't say I've faced cases where regular application of it would be guaranteed and omissions would be visible. I vice versa can point to a limitation in "generic exception filters" approach - it handles "how to match exceptions more flexibly" issue, but doesn't cover "how to handle automagic reraising of multiple (unhandled) exceptions" part. In my list, that's good - in normal exception handling, exception are (re)raised explicitly. It's pretty big conceptual jump to make handling of that implicit (and exception handling in general is condemned as too-implicit control flow construct by some parties). Overall, my idea wasn't to come up with an alternative proposal so late in PEP654 lifecycle, nor even delay its submission to SC. I just decided to sounds these concern in the end (had them in my notes since initial posting), and ask for clarifications like if there's a cross-language prior art regarding it. []
def chained(e, excs): while e: if isinstance(e, excs): return e e = e.__cause__ # Simplified, should consider __context__
It's different because your "match" function returns a single exception (the first one that is of OSError type). Any further OSErrors will be reraised. The PEP's except* knows how to match multiple exceptions of the relevant type.
For this case, it was "chained" function (exception filter), which was concerned only with catching OSError anywhere in the exception chain. As mentioned in the other comment, if there's a need to reraise (parts) of original exception, in must be stored as an attribute of an exception returned from filter. All that's pretty clear and explicit, though I agree if it (reraising) needs to be done often, it may be cumbersome. If it needs to be done. We here touch the question of how exactly such (multiple) exceptions would be handled. And PEP654 is pretty bare on that too - it offers machinery to make that possible, but barely talks of actual usecases (where it starts talk about that is in "Rejected ideas" section, not in the main narrative).
My understanding is that ExceptionGroup is carefully designed to allow subclassing it and override behavior, and the above should be possible by subclassing.
Indeed:
class PaulsExceptionGroup(ExceptionGroup):
Thanks for confirming. []
So your concern with our design is that ExceptionGroup implements a generic split() that handles tracebacks and nested structure correctly, and you might not need that because maybe you don't nest or you don't care about tracebacks?
My concern is still that it adds quite a big chunk of complexity to the core semantics of language. PEP654's ExceptionGroup is clearly carefully designed to (try) to be general, there's no questions about that.
If that is the case then I think you are confusing "generic" with "special-purpose". ExceptionGroup is generic, it works for general nested groups with arbitrary tracebacks and cause/context. That's the opposite of special-purpose.
Sadly, to me it still looks that all its generic complexity is rooted in Trio and friends, and for other usecases simpler approach would suffice. Again, that's just personal opinion. I'm just worried to see "except*" in code where it's really needed (and be able to easily grasp what it does), and dread seeing it where it's not really needed (in that regard, PEP654 tries to delineate it clearly from the rest of Python, thanks).
Irit
-- Best regards, Paul mailto:pmiscml@gmail.com