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/