Repository navigation
ExceptionGroup: make it generic - #7626
Conversation
See motivation in #91549.
This comment has been minimized.
This comment has been minimized.
2 similar comments
This comment has been minimized.
This comment has been minimized.
|
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
AlexWaygood
left a comment
There was a problem hiding this comment.
I haven't studied the finer details of exception groups, but this seems reasonable, and mypy/pyright seem happy.
| @overload | ||
| def subgroup( | ||
| self, __condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...] | ||
| ) -> BaseExceptionGroup[_BaseExceptionT] | None: ... | ||
| @overload | ||
| def subgroup(self: Self, __condition: Callable[[_BaseExceptionT_co], bool]) -> Self | None: ... |
There was a problem hiding this comment.
One minor gripe I have is that _BaseExceptionT and _BaseExceptionT_co have a very similar name, which means that it's easy to miss the subtleties in cases like above. But I have no immediate idea for better names.
There was a problem hiding this comment.
I initially had them as _BaseExceptionT and _BaseExceptionU but that seemed worse.
| ) -> tuple[BaseExceptionGroup[_BaseExceptionT] | None, Self | None]: ... | ||
| @overload | ||
| def split(self: Self, __condition: Callable[[_BaseExceptionT_co], bool]) -> tuple[Self | None, Self | None]: ... | ||
| def derive(self: Self, __excs: Sequence[_BaseExceptionT_co]) -> Self: ... |
There was a problem hiding this comment.
This is a bit of a tricky one. If I read PEP 654 correctly, the __excs provided don't need to have anything in common with the exceptions of self. So a "correct" annotation would be:
def derive(self: Self, __excs: Sequence[_BaseExceptionT]) -> Self[_BaseExceptionT]: ...But I don't think that's possible. So I'm fine with this, until someone comes up with a better alternative.
|
why should this be the case? assert_type(beg.exceptions, tuple[SystemExit | BaseExceptionGroup[SystemExit], ...])shouldn't instead be like this? assert_type(beg.exceptions, tuple[SystemExit, ...])Asking because it causes unexpected typing when using |
|
nevermind, just tried https://mypy-play.net/?mypy=latest&python=3.12&gist=059952b22801648257f86bee1fbfd404 and indeed it can have a nested ExceptionGroup in it. Quite unexpected for me, but this is not the forum to raise the issue. |
See motivation in python/cpython#91549.
I used the following tests:
These all pass in pyright, but mypy for some reason fails on a lot of the
splitandsubgroupcalls, with errors likesamples/exceptiongroup.py:107: error: Expression is of type "Optional[BaseExceptionGroup[Any]]", not "Optional[BaseExceptionGroup[KeyboardInterrupt]]". Seems like a bug.The overloads I added trade precision in the generic argument against precision in the generic type itself. If you have a subclass
ChildExceptionGroup(ExceptionGroup)and call.split(SomeException)on it, you get anExceptionGroup[SomeException]from the type checker, though at runtime you'd get aChildExceptionGroup[SomeException]. I think that's the right tradeoff because subclassing ExceptionGroup is likely to be rare.