Hi Paul,

IIUC, you are saying that exception group should not be a builtin type
because it is (1) complex (2) special-purposed.   Instead, you propose that
we make exception handling pluggable.

(1) I agree, it is somewhat complex - it took us several iterations to get
from the idea of "a container of exceptions" to something that works
correctly with split()/subgroup(), maintaining the integrity of
__traceback__/__cause__/__context__ information, allowing subclassing and
having a relatively simple API. To me this is a reason to provide it as a
builtin rather than a reason not to  (I think we should add this point to
the PEP- thanks).

You wrote:
> So yes, maybe being well aware that you're handling exactly Trio's (or
asyncio's, or context manager's) error isn't bad thing actually.

Maybe, in which case you can create a subclass of ExceptionGroup to mark
the groups coming from your library. But also maybe not, in which case you
don't have to.

(2) special-purposed? How so?   When I asked for a practical advantage of
your pluggable solution I meant an example of a use case that our proposal
doesn't accommodate well and where a pluggable one does better.
The only example you suggested so far was the TemporaryDirectory one, which
I don't find compelling:

  > > 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)

What if the user code raised an OSError too, so now that exception group
has more than one? Even without that problem, why should I prefer this to
our proposal?


I am interested to know (1) what limitations you see in the ExceptionGroup
type we are proposing (in what sense is it special-purposed? what purpose
is it unsuitable for?) and (2) an example where the pluggable solution
works better.

Irit

On Sat, Mar 27, 2021 at 12:42 PM Paul Sokolovsky <pmis...@gmail.com> wrote:

> Hello,
>
> On Sat, 27 Mar 2021 10:55:40 +0000
> Irit Katriel <iritkatr...@googlemail.com> wrote:
>
> > One of the motivations for introducing ExceptionGroup as a builtin is
> > so that we won't have a different custom version in each library that
> > needs it. So if you are writing a library the needs to raise multiple
> > exceptions, and then you decide to call Trio, you don't need to
> > translate Trio's MultiError into your own exception group type,
> > because everybody uses the builtin.
>
> Looking from a different angle shows a different perspective:
>
> 1. Trio devised an interesting concept of "nurseries" to deal with
> multiple tasks in asyncio-like programming.
>
> 2. It was all nice and beautiful until ... it came to error handling.
> Note that it's a rather typical situation - one can write nice, clean,
> beautiful code, which is not adequate in real-world scenarios,
> particularly because of error handling concerns. Oftentimes, such
> initial code/concepts are discarded, and more robust (though maybe not
> as beautiful) concepts/code is used.
>
> 3. But that's not what happened in the Trio case. The concept of
> nurseries got pushed forward, until it became clear that it requires
> changes on the programming language level.
>
> 4. That's how PEP654 was born, which, besides async scheduling of
> multiple tasks, bring *somewhat similar* usecases of e.g. raising
> exceptions thru context managers' own exceptions.
>
> Note that where errors and exceptions lead us is in questions on how to
> handle them. And beyond a couple of well known patterns ("dump and
> crash" or "dump and continue with next iteration"), error handling is
> very adhoc to a particular application and particular error(s). Seen
> from that angle, Trio wants to vendor-lock the entire language into its
> particular (experimental) way of handling multiple errors.
>
> So yes, maybe being well aware that you're handling exactly Trio's (or
> asyncio's, or context manager's) error isn't bad thing actually. And if
> it's clear that multiple asyncio frameworks are interested in sharing
> common exception base class for such usecases, then it could be
> introduced on the "asyncio" package level, or maybe even better, as a
> module similar to "concurrent.futures".
>
> > And your users don't need to
> > learn how your particular exception group works because they know
> > that you are using the builtin one.
> >
> > I see the aesthetic value of your suggestion, but does it have
> > practical advantages in light of the above?
>
> The concern is that it codifies pretty complex and special-purpose
> things on the language level. And it seems that the whole concept is
> rather experimental and "original design". We can compare that with
> another sufficiently complex feature which landed recently: pattern
> matching. At all phases of the design and discussion of that feature,
> one of the guiding principles was: "Many other languages implement it,
> so we know it's generally useful, and have design space more or less
> charted, and can vary things to find local optimum for Python".
>
> Contrary to that, the original PEP654 didn't refer to (cross-language,
> cross-framework) prior art in handling multiple errors, and I don't see
> that changed in the latest version. So I'm sorry, but it seems like NIH
> feature of a specific 3rd-party framework being promoted to a whole
> language's way of doing things.
>
> Under such circumstance, I guess it would be good idea to try to
> decouple behavior of that feature from the languages core, and make
> aspects of behavior more explicit (following "explicit is better than
> implicit" principle), and allow to vary/evolve it without changing the
> core language.
>
> I tried to draft a scheme aspiring to allow that. (Which would
> definitely need more work to achieve parity with functionality in
> PEP654, because again, it tries to codify rather complex and "magic"
> behavior. Where complex and magic behavior in exception handling is
> itself of concern, so making it more explicit may be a good idea. (A
> good "how other languages deal with it") review would mention that Go,
> Rust, Zig, etc. don't have and condemn exception handling at all (normal
> simple classy exceptions, not magic we discuss here!)).
>
>
> Thanks,
> Paul
>
>
>
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/OI56ISCKV7WKMLTX2QPZ44IPA4H7H2WG/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to