Contra the rejected idea Not matching naked exceptions in except*, I think it's subtly dangerous to have except* FooError to match both FooError and ExceptionGroup[FooError]. In short, the current proposal treats unhandled operation errors as control flow exceptions, and IMO "the burden of having to explicitly handle both" is indeed a semantic benefit.
This is based on my - and others, though I don't have a written reference to hand - experience with Trio: when an error may or may not be an ExceptionGroup, users will tend to only handle the more common case. The common/naive misuse of "bare except:" is a good example here; IMO disallowing bare-except would be better than the status quo (though except: -> except Exception: would be better still).
I therefore propose that either:
except* can only catch ExceptionGroup and subclasses thereof, never naked exceptions, (my preferred option)
- or we require that
ExceptionGroup be named in the except* block:
try:
...
except* ExceptionGroup[FooError] as eg:
...
except* (TypeError, ExceptionGroup[TypeError]) as eg:
...
Taking the same principles too far, we would get:
try:
...
except FooError as err:
...
except ExceptionGroup[FooError] as eg:
...
except (TypeError, ExceptionGroup[TypeError]) as eg:
...
This would obviously require the except statement to grow magical awareness of ExceptionGroup, which I don't particularly like, but the only (substantial!) advantage of the except* statement is dedicated syntax for running all matching clauses. As a clean(ish) way to avoid new syntax I think this probably deserves a place under rejected ideas.