From e0654bdbc0f7c39f4e6aa788b5974d78ee11b57d Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 15 Apr 2022 07:24:17 -0700 Subject: [PATCH] ExceptionGroup: make it generic (#7626) --- stdlib/builtins.pyi | 47 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index ce2042bca..9c5dfcfef 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -52,7 +52,6 @@ from typing import ( SupportsInt, SupportsRound, TypeVar, - Union, overload, ) from typing_extensions import Literal, SupportsIndex, TypeGuard, final @@ -1747,19 +1746,45 @@ if sys.version_info >= (3, 10): class EncodingWarning(Warning): ... if sys.version_info >= (3, 11): - _SplitCondition = Union[type[BaseException], tuple[type[BaseException], ...], Callable[[BaseException], bool]] + _BaseExceptionT_co = TypeVar("_BaseExceptionT_co", bound=BaseException, covariant=True) + _BaseExceptionT = TypeVar("_BaseExceptionT", bound=BaseException) + _ExceptionT_co = TypeVar("_ExceptionT_co", bound=Exception, covariant=True) + _ExceptionT = TypeVar("_ExceptionT", bound=Exception) - class BaseExceptionGroup(BaseException): - def __new__(cls: type[Self], __message: str, __exceptions: Sequence[BaseException]) -> Self: ... + class BaseExceptionGroup(BaseException, Generic[_BaseExceptionT_co]): + def __new__(cls: type[Self], __message: str, __exceptions: Sequence[_BaseExceptionT_co]) -> Self: ... @property def message(self) -> str: ... @property - def exceptions(self) -> tuple[BaseException, ...]: ... - def subgroup(self: Self, __condition: _SplitCondition) -> Self | None: ... - def split(self: Self, __condition: _SplitCondition) -> tuple[Self | None, Self | None]: ... - def derive(self: Self, __excs: Sequence[BaseException]) -> Self: ... + def exceptions(self) -> tuple[_BaseExceptionT_co | BaseExceptionGroup[_BaseExceptionT_co], ...]: ... + @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: ... + @overload + def split( + self: Self, __condition: type[_BaseExceptionT] | tuple[type[_BaseExceptionT], ...] + ) -> 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: ... - class ExceptionGroup(BaseExceptionGroup, Exception): - def __new__(cls: type[Self], __message: str, __exceptions: Sequence[Exception]) -> Self: ... + class ExceptionGroup(BaseExceptionGroup[_ExceptionT_co], Exception): + def __new__(cls: type[Self], __message: str, __exceptions: Sequence[_ExceptionT_co]) -> Self: ... @property - def exceptions(self) -> tuple[Exception, ...]: ... + def exceptions(self) -> tuple[_ExceptionT_co | ExceptionGroup[_ExceptionT_co], ...]: ... + # We accept a narrower type, but that's OK. + @overload # type: ignore[override] + def subgroup( + self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + ) -> ExceptionGroup[_ExceptionT] | None: ... + @overload + def subgroup(self: Self, __condition: Callable[[_ExceptionT_co], bool]) -> Self | None: ... + @overload # type: ignore[override] + def split( + self: Self, __condition: type[_ExceptionT] | tuple[type[_ExceptionT], ...] + ) -> tuple[ExceptionGroup[_ExceptionT] | None, Self | None]: ... + @overload + def split(self: Self, __condition: Callable[[_ExceptionT_co], bool]) -> tuple[Self | None, Self | None]: ...