Sorry, I keep thinking I've finished and you keep making interesting points :-)
On Wed, 3 Mar 2021 at 17:01, Irit Katriel firstname.lastname@example.org wrote:
Raising an ExceptionGroup is an API change. If you call APIs that say they will raise ExceptionGroups you need to update your code accordingly. If a library doesn't document that it raises ExceptionGroups and then one of those escapes, then that library has a bug. Just like with any other exception type.
In my experience, libraries don't document what exceptions they raise very well. You can call that a bug, but it's a fact of life, I'm afraid. The problem here isn't so much that the library code now raises an exception that it used not to raise, but rather that *the user hitting Ctrl-C* can now result in a different exception surfacing in my code than it used to. Libraries don't re-wrap KeyboardInterrupt, as you pointed out in a previous response, so I can currently write code that traps KeyboardInterrupt, safe in the knowledge that by doing so I'll handle that user action properly. But with PEP 654, libraries might well (indeed, some libraries almost certainly will) start wrapping KeyboardInterrupt in an exception group. That's a backward incompatible change from the perspective of my code's interaction with the user, and I need to re-code my application to deal with it (and worse still, writing that new code in a way that is portable between versions is not particularly straightforward).
For older Pythons you would have to do something like
except KeyboardInterrupt: ... except BaseExceptionGroup: # some stub type in old versions # inspect the contents # if there's a KeyboardInterrupt do what you need to do # reraise the rest
I'd be inclined to suggest that a complete version of this should be included in the "Backward compatibility" part of the PEP, as I honestly don't really know how I'd write that without doing more research. But such an example would make the KeyboardInterrupt case seem more important than it is. Maybe if it's framed as "how to write calling code that's compatible with older versions of Python but still able to handle called code potentially raising exceptions that you need to trap as part of a group", that would be a useful general example.
Or maybe it's not actually something that will be needed that often. I'm not sure - I'm trying to think in terms of pip, where we can't use new features in our own code until we drop support for older versions, but we might potentially rely on a library that uses exception grouping internally on versions where it's available (and that code lets those exception groups escape). It feels like a stretch to claim this is particularly likely, but conversely it's something I can easily imagine *could* happen...