From 25ac4d6af46104d0c7cb134ed09a61ca7092b62a Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Fri, 17 Aug 2018 17:36:00 +0200 Subject: [PATCH] Implement StartResponse using a protocol (#2392) * Add ExcInfo and OptExcInfo type aliases * Implement StartResponse using a protocol * Mark stub-only types with an underscore * Remove wrong TODO note python/mypy#1178 is about variable-length tuples, while exc_info() always returns a tuple with length 3. Ideally, exc_info() would return Union[Tuple[Type[_E], _E, TracebackType], Tuple[None, None, None]], but that is a different issue. --- stdlib/2/sys.pyi | 9 +++++---- stdlib/2and3/wsgiref/types.pyi | 8 +++++--- stdlib/3/sys.pyi | 8 +++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/stdlib/2/sys.pyi b/stdlib/2/sys.pyi index 48c3436d6..33fca3bea 100644 --- a/stdlib/2/sys.pyi +++ b/stdlib/2/sys.pyi @@ -6,6 +6,10 @@ from typing import ( ) from types import FrameType, ModuleType, TracebackType, ClassType +# The following type alias are stub-only and do not exist during runtime +_ExcInfo = Tuple[Type[BaseException], BaseException, TracebackType] +_OptExcInfo = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] + class _flags: bytes_warning = ... # type: int debug = ... # type: int @@ -112,10 +116,7 @@ def __displayhook__(value: int) -> None: ... def __excepthook__(type_: type, value: BaseException, traceback: TracebackType) -> None: ... def exc_clear() -> None: raise DeprecationWarning() -# TODO should be a union of tuple, see mypy#1178 -def exc_info() -> Tuple[Optional[Type[BaseException]], - Optional[BaseException], - Optional[TracebackType]]: ... +def exc_info() -> _OptExcInfo: ... # sys.exit() accepts an optional argument of anything printable def exit(arg: Any = ...) -> NoReturn: diff --git a/stdlib/2and3/wsgiref/types.pyi b/stdlib/2and3/wsgiref/types.pyi index 8f35cce51..808c68034 100644 --- a/stdlib/2and3/wsgiref/types.pyi +++ b/stdlib/2and3/wsgiref/types.pyi @@ -15,10 +15,12 @@ # you need to use 'WSGIApplication' and not simply WSGIApplication when type # hinting your code. Otherwise Python will raise NameErrors. -from typing import Callable, Dict, Iterable, List, Any, Text, Protocol +from sys import _OptExcInfo +from typing import Callable, Dict, Iterable, List, Any, Text, Protocol, Tuple, Optional + +class StartResponse(Protocol): + def __call__(self, status: str, headers: List[Tuple[str, str]], exc_info: Optional[_OptExcInfo] = ...) -> Callable[[bytes], Any]: ... -# (status: str, headers: List[Tuple[str, str]], exc_info = None) -StartResponse = Callable[..., Callable[[bytes], Any]] WSGIEnvironment = Dict[Text, Any] WSGIApplication = Callable[[WSGIEnvironment, StartResponse], Iterable[bytes]] diff --git a/stdlib/3/sys.pyi b/stdlib/3/sys.pyi index b35f6d7a9..0e7b47600 100644 --- a/stdlib/3/sys.pyi +++ b/stdlib/3/sys.pyi @@ -14,6 +14,10 @@ from importlib.abc import MetaPathFinder _T = TypeVar('_T') +# The following type alias are stub-only and do not exist during runtime +_ExcInfo = Tuple[Type[BaseException], BaseException, TracebackType] +_OptExcInfo = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] + # ----- sys variables ----- abiflags: str argv: List[str] @@ -128,9 +132,7 @@ def _current_frames() -> Dict[int, Any]: ... def displayhook(value: Optional[int]) -> None: ... def excepthook(type_: Type[BaseException], value: BaseException, traceback: TracebackType) -> None: ... -def exc_info() -> Tuple[Optional[Type[BaseException]], - Optional[BaseException], - Optional[TracebackType]]: ... +def exc_info() -> _OptExcInfo: ... # sys.exit() accepts an optional argument of anything printable def exit(arg: object = ...) -> NoReturn: raise SystemExit()