-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
BaseExceptionGroup should return ExceptionGroup if initialized with non-base exceptions #12972
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Somewhat related: #9922 At a glance it seems like an overloaded (cc @sobolevn as the author of the current |
Oh, found a comment in the test file noticing it as a limitation
and found the accompanying discussion #9230 (comment) where @sobolevn lays out the tradeoffs I tried it out myself, and managed to repro the limitations*. Though I personally feel like getting Though I also hit python/mypy#17251 so we'd need to remove the * It's only a limitation for mypy, pyright handles this (somewhat minified) repro perfectly. Mypy falls back to defaults and raises some errors on the stub itself. from __future__ import annotations
from typing import Generic, TypeVar, overload, Self
from typing_extensions import reveal_type
_BaseExceptionT_co = TypeVar("_BaseExceptionT_co", bound=BaseException, covariant=True, default=BaseException)
_ExceptionT_co = TypeVar("_ExceptionT_co", bound=Exception, covariant=True, default=Exception)
class BaseExceptionGroup(Generic[_BaseExceptionT_co]):
@overload
# mypy: Self argument missing for a non-static method (or an invalid type for self)
def __new__( # type: ignore[misc]
cls: ExceptionGroup[_ExceptionT_co], _exception: _ExceptionT_co, /
) -> ExceptionGroup[_ExceptionT_co]: ...
@overload
def __new__(cls, _exception: _BaseExceptionT_co, /) -> Self: ...
# mypy: "__new__" must return a class instance
def __new__( # type: ignore[misc]
cls, _exception: _ExceptionT_co | _BaseExceptionT_co
) -> Self | ExceptionGroup[_ExceptionT_co]:
return object.__new__(cls)
class ExceptionGroup(BaseExceptionGroup[_ExceptionT_co]):
def __new__(cls, _exception: _ExceptionT_co, /) -> Self:
return object.__new__(cls)
class MyBaseExcGroup(BaseExceptionGroup[_BaseExceptionT_co]): ...
class MyExcGroup(ExceptionGroup[_ExceptionT_co]): ...
reveal_type(BaseExceptionGroup(ValueError()))
reveal_type(BaseExceptionGroup(SystemExit()))
reveal_type(MyBaseExcGroup(ValueError())) # mypy reverts to BaseException default
reveal_type(MyBaseExcGroup(SystemExit()))
reveal_type(ExceptionGroup(ValueError()))
reveal_type(MyExcGroup(ValueError()))
# expected errors
ExceptionGroup(SystemExit()) # type: ignore[type-var] # pyright: ignore[reportArgumentType]
MyExcGroup(SystemExit()) # type: ignore[type-var] # pyright: ignore[reportArgumentType] |
If someone could provide an exploratory PR, we could see the impact of such a change. |
When initializing a
BaseExceptionGroup
with non-base exceptions the stdlib (and the backport) will in fact return anExceptionGroup
. The typing in neither of typeshed nor the backport currently supports this.I have vague recollections that trying to do this was hard-to-impossible, but I currently cannot find any related issues.
The text was updated successfully, but these errors were encountered: