On Fri, Apr 23, 2021 at 2:45 AM Chris Angelico <ros...@gmail.com> wrote:
>
> On Fri, Apr 23, 2021 at 6:25 PM Nathaniel Smith <n...@pobox.com> wrote:
> > The main possibility that I don't think we've examined fully is to
> > make 'except' blocks fire multiple times when there are multiple
> > exceptions.
>
> Vanilla except blocks? Not sure if I'm misunderstanding, but that
> could cause some problems. Consider:
>
> trn.begin()
> try:
>     ...
> except BaseException:
>     trn.rollback()
>     raise
> else:
>     trn.commit()
>
> What happens if multiple exceptions get raised? Will the transaction
> be rolled back more than once? What gets reraised?
>
> If I'm completely misunderstanding you here, my apologies.

Yeah, you've understood correctly, and you see why I wrote "both the
current proposal and the alternative have very complex implications
and downsides" :-)

A lot depends on the details, too. One possible design is "in general,
vanilla except blocks will trigger multiple times, but as a special
case, except: and except BaseException: will only fire once, receiving
the whole ExceptionGroup as a single exception". (Rationale for making
a special case: if you're saying "catch anything, I don't care what",
then you obviously didn't intend to do anything in particular with
those exceptions, plus this is the only case where the types work.) In
that design, your example becomes correct again.

Some other interesting cases:

# Filters out all OSError's that match the condition, while letting
all other OSError's continue
try:
    ...
except OSError as exc:
    if exc.errno != errno.EWHATEVER:
        raise

# If this gets an ExceptionGroup([ValueError, KeyboardInterrupt]),
then it logs the ValueError and
# then exits with the selected error code
try:
    ...
except Exception as exc:
    logger.log_exception(exc)
except KeyboardInterrupt:
    sys.exit(17)

OTOH you can still come up with cases that aren't handled correctly.
If you have old 'except' code mixed with new code raising
ExceptionGroup, then there's no way to make that do the right thing in
*all* cases. By definition, when the 'except' code was written, the
author wasn't thinking about ExceptionGroups! So the question is which
combination of semantics ends up doing the least harm on average
across all sorts of different real-world cases...

-n

--
Nathaniel J. Smith -- https://vorpus.org
_______________________________________________
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/3V6YEKHOD5MYLSCPVDB7IYGX4EOO4KWB/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to