From b2947821832bb4d098985383c75c2d712b12f133 Mon Sep 17 00:00:00 2001 From: Michael Lee Date: Fri, 16 Aug 2019 16:13:33 -0700 Subject: [PATCH] Make most contextmanager `__exit__` signatures return Optional[bool] (#3179) This pull request is a follow-up to https://github.com/python/mypy/issues/7214. In short, within that mypy issue, we found it would be helpful to determine between contextmanagers that can "swallow" exceptions vs ones that can't. This helps prevent some false positive when using flags that analyze control flow such as `--warn-unreachable`. To do this, Jelle proposed assuming that only contextmanagers where the `__exit__` returns `bool` are assumed to swallow exceptions. This unfortunately required the following typeshed changes: 1. The typing.IO, threading.Lock, and concurrent.futures.Executor were all modified so `__exit__` returns `Optional[None]` instead of None -- along with all of their subclasses. I believe these three types are meant to be subclassed, so I felt picking the more general type was correct. 2. There were also a few concrete types (e.g. see socketserver, subprocess, ftplib...) that I modified to return `None` -- I checked the source code, and these all seem to return None (and don't appear to be meant to be subclassable). 3. contextlib.suppress was changed to return bool. I also double-checked the unittest modules and modified a subset of those contextmanagers, leaving ones like `_AssertRaisesContext` alone. --- CONTRIBUTING.md | 9 +++++++++ stdlib/2/SocketServer.pyi | 2 +- stdlib/2/__builtin__.pyi | 4 ++-- stdlib/2/_io.pyi | 4 ++-- stdlib/2/subprocess.pyi | 2 +- stdlib/2/tempfile.pyi | 4 ++-- stdlib/2/typing.pyi | 2 +- stdlib/2and3/builtins.pyi | 4 ++-- stdlib/2and3/codecs.pyi | 4 ++-- stdlib/2and3/contextlib.pyi | 9 +++++++++ stdlib/2and3/ftplib.pyi | 2 +- stdlib/2and3/tarfile.pyi | 2 +- stdlib/2and3/threading.pyi | 10 +++++----- stdlib/2and3/warnings.pyi | 2 +- stdlib/2and3/zipfile.pyi | 2 +- stdlib/3/concurrent/futures/_base.pyi | 2 +- stdlib/3/http/client.pyi | 5 ++--- stdlib/3/io.pyi | 6 +++--- stdlib/3/socketserver.pyi | 2 +- stdlib/3/subprocess.pyi | 2 +- stdlib/3/tempfile.pyi | 4 ++-- stdlib/3/typing.pyi | 2 +- stdlib/3/unittest/case.pyi | 4 ++-- stdlib/3/urllib/response.pyi | 2 +- third_party/2/concurrent/futures/_base.pyi | 2 +- 25 files changed, 55 insertions(+), 38 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4c871672360b..bdab962fe86d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -292,6 +292,15 @@ Type variables and aliases you introduce purely for legibility reasons should be prefixed with an underscore to make it obvious to the reader they are not part of the stubbed API. +When adding type annotations for context manager classes, annotate +the return type of `__exit__` as bool only if the context manager +sometimes suppresses annotations -- if it sometimes returns `True` +at runtime. If the context manager never suppresses exceptions, +have the return type be either `None` or `Optional[bool]`. If you +are not sure whether exceptions are suppressed or not or if the +context manager is meant to be subclassed, pick `Optional[bool]`. +See https://github.com/python/mypy/issues/7214 for more details. + NOTE: there are stubs in this repository that don't conform to the style described above. Fixing them is a great starting point for new contributors. diff --git a/stdlib/2/SocketServer.pyi b/stdlib/2/SocketServer.pyi index 22dda28b4f1d..2403614b4709 100644 --- a/stdlib/2/SocketServer.pyi +++ b/stdlib/2/SocketServer.pyi @@ -38,7 +38,7 @@ class BaseServer: def __enter__(self) -> BaseServer: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[types.TracebackType]) -> bool: ... + exc_tb: Optional[types.TracebackType]) -> None: ... if sys.version_info >= (3, 3): def service_actions(self) -> None: ... diff --git a/stdlib/2/__builtin__.pyi b/stdlib/2/__builtin__.pyi index 37d72736e67f..daadf8fb040c 100644 --- a/stdlib/2/__builtin__.pyi +++ b/stdlib/2/__builtin__.pyi @@ -787,7 +787,7 @@ class memoryview(Sized, Container[_mv_container_type]): nbytes: int def __init__(self, obj: Union[bytes, bytearray, memoryview]) -> None: ... def __enter__(self) -> memoryview: ... - def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> bool: ... + def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> None: ... else: def __init__(self, obj: Union[bytes, bytearray, buffer, memoryview]) -> None: ... @@ -1615,7 +1615,7 @@ if sys.version_info < (3,): def next(self) -> str: ... def read(self, n: int = ...) -> str: ... def __enter__(self) -> BinaryIO: ... - def __exit__(self, t: Optional[type] = ..., exc: Optional[BaseException] = ..., tb: Optional[Any] = ...) -> bool: ... + def __exit__(self, t: Optional[type] = ..., exc: Optional[BaseException] = ..., tb: Optional[Any] = ...) -> Optional[bool]: ... def flush(self) -> None: ... def fileno(self) -> int: ... def isatty(self) -> bool: ... diff --git a/stdlib/2/_io.pyi b/stdlib/2/_io.pyi index e4e15cbfd90f..dd4d1440dd13 100644 --- a/stdlib/2/_io.pyi +++ b/stdlib/2/_io.pyi @@ -32,7 +32,7 @@ class _IOBase(BinaryIO): def truncate(self, size: Optional[int] = ...) -> int: ... def writable(self) -> bool: ... def __enter__(self: _T) -> _T: ... - def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[Any]) -> bool: ... + def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[Any]) -> Optional[bool]: ... def __iter__(self: _T) -> _T: ... # The parameter type of writelines[s]() is determined by that of write(): def writelines(self, lines: Iterable[bytes]) -> None: ... @@ -146,7 +146,7 @@ class _TextIOBase(TextIO): def write(self, pbuf: unicode) -> int: ... def writelines(self, lines: Iterable[unicode]) -> None: ... def __enter__(self: _T) -> _T: ... - def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[Any]) -> bool: ... + def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[Any]) -> Optional[bool]: ... def __iter__(self: _T) -> _T: ... class StringIO(_TextIOBase): diff --git a/stdlib/2/subprocess.pyi b/stdlib/2/subprocess.pyi index e4ffc3db3320..672efbf8c71e 100644 --- a/stdlib/2/subprocess.pyi +++ b/stdlib/2/subprocess.pyi @@ -106,7 +106,7 @@ class Popen(Generic[_T]): def terminate(self) -> None: ... def kill(self) -> None: ... def __enter__(self) -> Popen: ... - def __exit__(self, type, value, traceback) -> bool: ... + def __exit__(self, type, value, traceback) -> None: ... def list2cmdline(seq: Sequence[str]) -> str: ... # undocumented diff --git a/stdlib/2/tempfile.pyi b/stdlib/2/tempfile.pyi index 2dcc1a924beb..4233cf72f179 100644 --- a/stdlib/2/tempfile.pyi +++ b/stdlib/2/tempfile.pyi @@ -24,7 +24,7 @@ class _TemporaryFileWrapper(IO[str]): def __init__(self, file: IO, name: Any, delete: bool = ...) -> None: ... def __del__(self) -> None: ... def __enter__(self) -> _TemporaryFileWrapper: ... - def __exit__(self, exc, value, tb) -> bool: ... + def __exit__(self, exc, value, tb) -> Optional[bool]: ... def __getattr__(self, name: unicode) -> Any: ... def close(self) -> None: ... def unlink(self, path: unicode) -> None: ... @@ -88,7 +88,7 @@ class TemporaryDirectory: dir: Union[bytes, unicode] = ...) -> None: ... def cleanup(self) -> None: ... def __enter__(self) -> Any: ... # Can be str or unicode - def __exit__(self, type, value, traceback) -> bool: ... + def __exit__(self, type, value, traceback) -> None: ... @overload def mkstemp() -> Tuple[int, str]: ... diff --git a/stdlib/2/typing.pyi b/stdlib/2/typing.pyi index 52042ff2be6c..0d10952b5ae6 100644 --- a/stdlib/2/typing.pyi +++ b/stdlib/2/typing.pyi @@ -343,7 +343,7 @@ class IO(Iterator[AnyStr], Generic[AnyStr]): def __enter__(self) -> IO[AnyStr]: ... @abstractmethod def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], - traceback: Optional[TracebackType]) -> bool: ... + traceback: Optional[TracebackType]) -> Optional[bool]: ... class BinaryIO(IO[str]): # TODO readinto diff --git a/stdlib/2and3/builtins.pyi b/stdlib/2and3/builtins.pyi index 37d72736e67f..daadf8fb040c 100644 --- a/stdlib/2and3/builtins.pyi +++ b/stdlib/2and3/builtins.pyi @@ -787,7 +787,7 @@ class memoryview(Sized, Container[_mv_container_type]): nbytes: int def __init__(self, obj: Union[bytes, bytearray, memoryview]) -> None: ... def __enter__(self) -> memoryview: ... - def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> bool: ... + def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], exc_tb: Optional[TracebackType]) -> None: ... else: def __init__(self, obj: Union[bytes, bytearray, buffer, memoryview]) -> None: ... @@ -1615,7 +1615,7 @@ if sys.version_info < (3,): def next(self) -> str: ... def read(self, n: int = ...) -> str: ... def __enter__(self) -> BinaryIO: ... - def __exit__(self, t: Optional[type] = ..., exc: Optional[BaseException] = ..., tb: Optional[Any] = ...) -> bool: ... + def __exit__(self, t: Optional[type] = ..., exc: Optional[BaseException] = ..., tb: Optional[Any] = ...) -> Optional[bool]: ... def flush(self) -> None: ... def fileno(self) -> int: ... def isatty(self) -> bool: ... diff --git a/stdlib/2and3/codecs.pyi b/stdlib/2and3/codecs.pyi index 47ea963c6920..fe734511be21 100644 --- a/stdlib/2and3/codecs.pyi +++ b/stdlib/2and3/codecs.pyi @@ -188,7 +188,7 @@ class StreamReaderWriter(TextIO): def __enter__(self: _T) -> _T: ... def __exit__( self, typ: Optional[Type[BaseException]], exc: Optional[BaseException], tb: Optional[types.TracebackType] - ) -> bool: ... + ) -> None: ... def __getattr__(self, name: str) -> Any: ... # These methods don't actually exist directly, but they are needed to satisfy the TextIO # interface. At runtime, they are delegated through __getattr__. @@ -229,7 +229,7 @@ class StreamRecoder(BinaryIO): def __enter__(self: _SRT) -> _SRT: ... def __exit__( self, type: Optional[Type[BaseException]], value: Optional[BaseException], tb: Optional[types.TracebackType] - ) -> bool: ... + ) -> None: ... # These methods don't actually exist directly, but they are needed to satisfy the BinaryIO # interface. At runtime, they are delegated through __getattr__. def seek(self, offset: int, whence: int = ...) -> int: ... diff --git a/stdlib/2and3/contextlib.pyi b/stdlib/2and3/contextlib.pyi index 4aa07471f842..a2b161ce85dc 100644 --- a/stdlib/2and3/contextlib.pyi +++ b/stdlib/2and3/contextlib.pyi @@ -46,6 +46,9 @@ class closing(ContextManager[_T], Generic[_T]): if sys.version_info >= (3, 4): class suppress(ContextManager[None]): def __init__(self, *exceptions: Type[BaseException]) -> None: ... + def __exit__(self, exctype: Optional[Type[BaseException]], + excinst: Optional[BaseException], + exctb: Optional[TracebackType]) -> bool: ... class redirect_stdout(ContextManager[None]): def __init__(self, new_target: IO[str]) -> None: ... @@ -69,6 +72,9 @@ if sys.version_info >= (3,): def pop_all(self: _U) -> _U: ... def close(self) -> None: ... def __enter__(self: _U) -> _U: ... + def __exit__(self, __exc_type: Optional[Type[BaseException]], + __exc_value: Optional[BaseException], + __traceback: Optional[TracebackType]) -> bool: ... if sys.version_info >= (3, 7): from typing import Awaitable @@ -94,6 +100,9 @@ if sys.version_info >= (3, 7): def pop_all(self: _S) -> _S: ... def aclose(self) -> Awaitable[None]: ... def __aenter__(self: _S) -> Awaitable[_S]: ... + def __aexit__(self, __exc_type: Optional[Type[BaseException]], + __exc_value: Optional[BaseException], + __traceback: Optional[TracebackType]) -> Awaitable[bool]: ... if sys.version_info >= (3, 7): @overload diff --git a/stdlib/2and3/ftplib.pyi b/stdlib/2and3/ftplib.pyi index dff8c4788bc2..9222ff6556d3 100644 --- a/stdlib/2and3/ftplib.pyi +++ b/stdlib/2and3/ftplib.pyi @@ -44,7 +44,7 @@ class FTP: encoding: str def __enter__(self: _T) -> _T: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> None: ... else: file: Optional[BinaryIO] diff --git a/stdlib/2and3/tarfile.pyi b/stdlib/2and3/tarfile.pyi index 07f78aeeb7d9..98523fc44f64 100644 --- a/stdlib/2and3/tarfile.pyi +++ b/stdlib/2and3/tarfile.pyi @@ -77,7 +77,7 @@ class TarFile(Iterable[TarInfo]): def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> None: ... def __iter__(self) -> Iterator[TarInfo]: ... @classmethod def open(cls, name: Optional[_Path] = ..., mode: str = ..., diff --git a/stdlib/2and3/threading.pyi b/stdlib/2and3/threading.pyi index 190f93407001..63f838f3df4d 100644 --- a/stdlib/2and3/threading.pyi +++ b/stdlib/2and3/threading.pyi @@ -81,7 +81,7 @@ class Lock: def __enter__(self) -> bool: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... if sys.version_info >= (3,): def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... else: @@ -95,7 +95,7 @@ class _RLock: def __enter__(self) -> bool: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... if sys.version_info >= (3,): def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... else: @@ -111,7 +111,7 @@ class Condition: def __enter__(self) -> bool: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... if sys.version_info >= (3,): def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... else: @@ -131,7 +131,7 @@ class Semaphore: def __enter__(self) -> bool: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... if sys.version_info >= (3,): def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... else: @@ -143,7 +143,7 @@ class BoundedSemaphore: def __enter__(self) -> bool: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... if sys.version_info >= (3,): def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... else: diff --git a/stdlib/2and3/warnings.pyi b/stdlib/2and3/warnings.pyi index 4d7419edbf90..d9ecec74f71e 100644 --- a/stdlib/2and3/warnings.pyi +++ b/stdlib/2and3/warnings.pyi @@ -43,4 +43,4 @@ class catch_warnings: def __enter__(self) -> Optional[List[_Record]]: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> None: ... diff --git a/stdlib/2and3/zipfile.pyi b/stdlib/2and3/zipfile.pyi index a1ae7f3d2f14..f5b8fab0edff 100644 --- a/stdlib/2and3/zipfile.pyi +++ b/stdlib/2and3/zipfile.pyi @@ -55,7 +55,7 @@ class ZipFile: def __enter__(self) -> ZipFile: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> None: ... def close(self) -> None: ... def getinfo(self, name: Text) -> ZipInfo: ... def infolist(self) -> List[ZipInfo]: ... diff --git a/stdlib/3/concurrent/futures/_base.pyi b/stdlib/3/concurrent/futures/_base.pyi index fd04210936dc..6d454fbe8388 100644 --- a/stdlib/3/concurrent/futures/_base.pyi +++ b/stdlib/3/concurrent/futures/_base.pyi @@ -53,7 +53,7 @@ class Executor: def map(self, func: Callable[..., _T], *iterables: Iterable[Any], timeout: Optional[float] = ...,) -> Iterator[_T]: ... def shutdown(self, wait: bool = ...) -> None: ... def __enter__(self: _T) -> _T: ... - def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> bool: ... + def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Optional[bool]: ... def as_completed(fs: Iterable[Future[_T]], timeout: Optional[float] = ...) -> Iterator[Future[_T]]: ... diff --git a/stdlib/3/http/client.pyi b/stdlib/3/http/client.pyi index f4b5189d94d8..ee57f16a8f29 100644 --- a/stdlib/3/http/client.pyi +++ b/stdlib/3/http/client.pyi @@ -80,8 +80,7 @@ responses: Dict[int, str] class HTTPMessage(email.message.Message): ... -# Ignore errors to work around python/mypy#5027 -class HTTPResponse(io.BufferedIOBase, BinaryIO): # type: ignore +class HTTPResponse(io.BufferedIOBase, BinaryIO): msg: HTTPMessage headers: HTTPMessage version: int @@ -103,7 +102,7 @@ class HTTPResponse(io.BufferedIOBase, BinaryIO): # type: ignore def __enter__(self) -> HTTPResponse: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[types.TracebackType]) -> bool: ... + exc_tb: Optional[types.TracebackType]) -> Optional[bool]: ... def info(self) -> email.message.Message: ... def geturl(self) -> str: ... def getcode(self) -> int: ... diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index 5afbbcbf386e..900b77cc9831 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -28,7 +28,7 @@ class IOBase: def __next__(self) -> bytes: ... def __enter__(self: _T) -> _T: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... def close(self) -> None: ... def fileno(self) -> int: ... def flush(self) -> None: ... @@ -86,7 +86,7 @@ class BytesIO(BinaryIO): def __next__(self) -> bytes: ... def __enter__(self) -> BytesIO: ... def __exit__(self, t: Optional[Type[BaseException]] = ..., value: Optional[BaseException] = ..., - traceback: Optional[TracebackType] = ...) -> bool: ... + traceback: Optional[TracebackType] = ...) -> Optional[bool]: ... def close(self) -> None: ... def fileno(self) -> int: ... def flush(self) -> None: ... @@ -165,7 +165,7 @@ class TextIOWrapper(TextIO): ) -> None: ... # copied from IOBase def __exit__(self, t: Optional[Type[BaseException]] = ..., value: Optional[BaseException] = ..., - traceback: Optional[TracebackType] = ...) -> bool: ... + traceback: Optional[TracebackType] = ...) -> Optional[bool]: ... def close(self) -> None: ... def fileno(self) -> int: ... def flush(self) -> None: ... diff --git a/stdlib/3/socketserver.pyi b/stdlib/3/socketserver.pyi index 22dda28b4f1d..2403614b4709 100644 --- a/stdlib/3/socketserver.pyi +++ b/stdlib/3/socketserver.pyi @@ -38,7 +38,7 @@ class BaseServer: def __enter__(self) -> BaseServer: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[types.TracebackType]) -> bool: ... + exc_tb: Optional[types.TracebackType]) -> None: ... if sys.version_info >= (3, 3): def service_actions(self) -> None: ... diff --git a/stdlib/3/subprocess.pyi b/stdlib/3/subprocess.pyi index 0e5df2c5094c..ef2aae4cbff5 100644 --- a/stdlib/3/subprocess.pyi +++ b/stdlib/3/subprocess.pyi @@ -1170,7 +1170,7 @@ class Popen(Generic[AnyStr]): def terminate(self) -> None: ... def kill(self) -> None: ... def __enter__(self) -> Popen: ... - def __exit__(self, type: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> bool: ... + def __exit__(self, type: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> None: ... # The result really is always a str. def getstatusoutput(cmd: _TXT) -> Tuple[int, str]: ... diff --git a/stdlib/3/tempfile.pyi b/stdlib/3/tempfile.pyi index e4aad54b4a03..c81187631b87 100644 --- a/stdlib/3/tempfile.pyi +++ b/stdlib/3/tempfile.pyi @@ -38,7 +38,7 @@ class SpooledTemporaryFile(IO[AnyStr]): def __enter__(self) -> SpooledTemporaryFile: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... # These methods are copied from the abstract methods of IO, because # SpooledTemporaryFile implements IO. @@ -69,7 +69,7 @@ class TemporaryDirectory(Generic[AnyStr]): def __enter__(self) -> AnyStr: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> None: ... def mkstemp(suffix: Optional[AnyStr] = ..., prefix: Optional[AnyStr] = ..., dir: Optional[AnyStr] = ..., text: bool = ...) -> Tuple[int, AnyStr]: ... diff --git a/stdlib/3/typing.pyi b/stdlib/3/typing.pyi index 893dbffef624..42ebbf964284 100644 --- a/stdlib/3/typing.pyi +++ b/stdlib/3/typing.pyi @@ -479,7 +479,7 @@ class IO(Iterator[AnyStr], Generic[AnyStr]): def __enter__(self) -> IO[AnyStr]: ... @abstractmethod def __exit__(self, t: Optional[Type[BaseException]], value: Optional[BaseException], - traceback: Optional[TracebackType]) -> bool: ... + traceback: Optional[TracebackType]) -> Optional[bool]: ... class BinaryIO(IO[bytes]): # TODO readinto diff --git a/stdlib/3/unittest/case.pyi b/stdlib/3/unittest/case.pyi index f71e5e4e8b7f..2e9e523c3ae1 100644 --- a/stdlib/3/unittest/case.pyi +++ b/stdlib/3/unittest/case.pyi @@ -214,11 +214,11 @@ class _AssertWarnsContext: lineno: int def __enter__(self) -> _AssertWarnsContext: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> None: ... class _AssertLogsContext: records: List[logging.LogRecord] output: List[str] def __enter__(self) -> _AssertLogsContext: ... def __exit__(self, exc_type: Optional[Type[BaseException]], exc_val: Optional[BaseException], - exc_tb: Optional[TracebackType]) -> bool: ... + exc_tb: Optional[TracebackType]) -> Optional[bool]: ... diff --git a/stdlib/3/urllib/response.pyi b/stdlib/3/urllib/response.pyi index ef3507d7ddc7..7cbc045a3f76 100644 --- a/stdlib/3/urllib/response.pyi +++ b/stdlib/3/urllib/response.pyi @@ -7,7 +7,7 @@ _AIUT = TypeVar("_AIUT", bound=addbase) class addbase(BinaryIO): def __enter__(self: _AIUT) -> _AIUT: ... - def __exit__(self, type: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> bool: ... + def __exit__(self, type: Optional[Type[BaseException]], value: Optional[BaseException], traceback: Optional[TracebackType]) -> None: ... def __iter__(self: _AIUT) -> _AIUT: ... def __next__(self) -> bytes: ... def close(self) -> None: ... diff --git a/third_party/2/concurrent/futures/_base.pyi b/third_party/2/concurrent/futures/_base.pyi index fd04210936dc..6d454fbe8388 100644 --- a/third_party/2/concurrent/futures/_base.pyi +++ b/third_party/2/concurrent/futures/_base.pyi @@ -53,7 +53,7 @@ class Executor: def map(self, func: Callable[..., _T], *iterables: Iterable[Any], timeout: Optional[float] = ...,) -> Iterator[_T]: ... def shutdown(self, wait: bool = ...) -> None: ... def __enter__(self: _T) -> _T: ... - def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> bool: ... + def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> Optional[bool]: ... def as_completed(fs: Iterable[Future[_T]], timeout: Optional[float] = ...) -> Iterator[Future[_T]]: ...