-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BaseExceptionGroup should return ExceptionGroup if initialized with non-base exceptions #12972
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] |
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: