From bbd2af8e4f6f43661d2eb69c2b0e0e5dccf94dfc Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 18 Sep 2020 17:22:52 -0400 Subject: [PATCH 1/2] Add _TemporaryFileWrapper to tempfile.pyi --- stdlib/3/tempfile.pyi | 31 ++++++++++++++++++++++++ tests/stubtest_whitelists/py3_common.txt | 2 ++ 2 files changed, 33 insertions(+) diff --git a/stdlib/3/tempfile.pyi b/stdlib/3/tempfile.pyi index 3c46be28483a..12c30fdf40a1 100644 --- a/stdlib/3/tempfile.pyi +++ b/stdlib/3/tempfile.pyi @@ -164,6 +164,37 @@ else: dir: Optional[_DirT[AnyStr]] = ..., ) -> IO[Any]: ... +class _TemporaryFileWrapper(IO[str]): + file: IO[str] + name: Any + delete: bool + def __init__(self, file: IO[str], name: Any, delete: bool = ...) -> None: ... + def __enter__(self) -> _TemporaryFileWrapper: ... + def __exit__(self, exc: Optional[Type[BaseException]], value: Optional[BaseException], tb: Optional[TracebackType]) -> Optional[bool]: ... + def __getattr__(self, name: str) -> Any: ... + def close(self) -> None: ... + def unlink(self, path: str) -> None: ... + # These methods don't exist directly on this object, but + # are delegated to the underlying IO object through __getattr__. + # We need to add them here so that this class is concrete. + def __iter__(self) -> Iterator[str]: ... + def __next__(self) -> str: ... + def fileno(self) -> int: ... + def flush(self) -> None: ... + def isatty(self) -> bool: ... + def next(self) -> str: ... + def read(self, n: int = ...) -> str: ... + def readable(self) -> bool: ... + def readline(self, limit: int = ...) -> str: ... + def readlines(self, hint: int = ...) -> List[str]: ... + def seek(self, offset: int, whence: int = ...) -> int: ... + def seekable(self) -> bool: ... + def tell(self) -> int: ... + def truncate(self, size: Optional[int] = ...) -> int: ... + def writable(self) -> bool: ... + def write(self, s: str) -> int: ... + def writelines(self, lines: Iterable[str]) -> None: ... + # It does not actually derive from IO[AnyStr], but it does implement the # protocol. class SpooledTemporaryFile(IO[AnyStr]): diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index 375f9002cf32..564463b2a211 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -427,6 +427,8 @@ builtins.quit # Builtins that mypy pretends exist builtins.reveal_locals builtins.reveal_type +# Dynamically specified by __getattr__, and thus don't exist on the class +tempfile._TemporaryFileWrapper.[\w_]+ # Various classes in typing aren't types at runtime. In addition, mypy thinks some special forms are tautologically defined. typing.[A-Z]\w+ # We can't distinguish not having a default value from having a default value of inspect.Parameter.empty From bd3b1b8813ce71cf532ec45fe31a0dc25d723628 Mon Sep 17 00:00:00 2001 From: Rune Tynan Date: Fri, 18 Sep 2020 17:26:14 -0400 Subject: [PATCH 2/2] Black/Isort --- stdlib/3/tempfile.pyi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stdlib/3/tempfile.pyi b/stdlib/3/tempfile.pyi index 12c30fdf40a1..80040d940af4 100644 --- a/stdlib/3/tempfile.pyi +++ b/stdlib/3/tempfile.pyi @@ -170,7 +170,9 @@ class _TemporaryFileWrapper(IO[str]): delete: bool def __init__(self, file: IO[str], name: Any, delete: bool = ...) -> None: ... def __enter__(self) -> _TemporaryFileWrapper: ... - def __exit__(self, exc: Optional[Type[BaseException]], value: Optional[BaseException], tb: Optional[TracebackType]) -> Optional[bool]: ... + def __exit__( + self, exc: Optional[Type[BaseException]], value: Optional[BaseException], tb: Optional[TracebackType] + ) -> Optional[bool]: ... def __getattr__(self, name: str) -> Any: ... def close(self) -> None: ... def unlink(self, path: str) -> None: ...