Hi Paul, 

I agree that your condition (1) is essential, while condition (2) is desirable.   (I explained in the email you replied to why I think 2 is less critical than 1).

The current state of the PEP is that ExceptionGroup does not wrap BaseExceptions and is caught by "except Exception", while BaseExceptionGroup wraps BaseException and is only caught by "except BaseException" but not "except Exception". 

This is covered the PEP, but TL;DR:
If we could make "except KeyboardInterrupt" catch BaseExceptionGroup([KeyboardInterrupt]) in a reasonably backwards compatible way then we wouldn't need except*. 

For example, suppose that this:

try:
    raise BaseExceptionGroup([KeyboardInterrupt()])
except  KeyboardInterrupt:
   email_the_boss()

worked as you suggest. Then what should this do?  Send two emails to the boss?

try:
    raise BaseExceptionGroup([KeyboardInterrupt(), KeyboardInterrupt() ])
except  KeyboardInterrupt:
   email_the_boss()


As you noted, no library is under any obligation to wrap KeyboardInterrupts into the exception groups it raises. You may decide it's a bad idea and not do it.  What we are discussing here is what the language should make possible. We agree that wrapping a BaseException by an Exception is something we should definitely block. When it's wrapping a BaseException by another, new BaseException type, in my view that's ok. You may have a bug where you don't catch an exception you want to catch, because you are using a new API incorrectly. But you won't have bugs where you swallow an exception that you didn't swallow before.

Irit


On Wed, Mar 3, 2021 at 8:30 AM Paul Moore <p.f.moore@gmail.com> wrote:
On Tue, 2 Mar 2021 at 21:46, Irit Katriel via Python-Dev
<python-dev@python.org> wrote:
> As an aside - I found it interesting that the option to wrap BaseException instances by an Exception, which came up a couple of times in this thread, didn't generate any anxiety.

Probably because it wasn't clear that was ever being proposed... (or
at least the implication wasn't obvious - presumably this is somehow
related to BaseExceptions being accumulated in ExceptionGroups?) :-(

I would consider it essential that if someone hits Ctrl-C and that
generates a KeyboardInterrupt, then:

1. That KeyboardInterrupt will *not* get caught by exception handlers
only interested in Exception instances
2. That KeyboardInterrupt *will* get caught by any handler that does
an explicit `except KeyboardInterrupt` or an `except BaseException`.

To me, that's pretty much essential to correct Ctrl-C handling in any
app (never ignore a user's Ctrl-C and always exit cleanly if one is
raised).

That might mean that BaseException instances shouldn't be "groupable",
but I don't want to comment on that until I've properly read the PEP
(I've skimmed it now, but only superficially). At a minimum, I'd
consider it a bug for library code to manually wrap a
KeyboardInterrupt in an exception group (just like code that catches
KeyboardInterrupt and re-raises it as a ValueError would be today).

Paul