From 4694594e37c1f0c03d5c9ac20b358131148293f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Mon, 25 May 2020 22:41:25 -0300 Subject: [PATCH 01/12] Make BytesIO inherit from BufferedIOBase. --- stdlib/3/io.pyi | 36 +----------------------------------- 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index 47fb0d2b6849..944bfd185cc7 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -77,8 +77,7 @@ class FileIO(RawIOBase): opener: Optional[Callable[[Union[int, str], str], int]] = ... ) -> None: ... -# TODO should extend from BufferedIOBase -class BytesIO(BinaryIO): +class BytesIO(BufferedIOBase, BinaryIO): def __init__(self, initial_bytes: bytes = ...) -> None: ... # BytesIO does not contain a "name" field. This workaround is necessary # to allow BytesIO sub-classes to add this field, as it is defined @@ -86,39 +85,6 @@ class BytesIO(BinaryIO): name: Any def getvalue(self) -> bytes: ... def getbuffer(self) -> memoryview: ... - # copied from IOBase - def __iter__(self) -> Iterator[bytes]: ... - def __next__(self) -> bytes: ... - def __enter__(self) -> BytesIO: ... - def __exit__(self, t: Optional[Type[BaseException]] = ..., value: Optional[BaseException] = ..., - traceback: Optional[TracebackType] = ...) -> Optional[bool]: ... - def close(self) -> None: ... - def fileno(self) -> int: ... - def flush(self) -> None: ... - def isatty(self) -> bool: ... - def readable(self) -> bool: ... - def readlines(self, __size: int = ...) -> List[bytes]: ... - def seek(self, __pos: int, __whence: int = ...) -> int: ... - def seekable(self) -> bool: ... - def tell(self) -> int: ... - def truncate(self, __size: Optional[int] = ...) -> int: ... - def writable(self) -> bool: ... - # TODO should be the next line instead - # def writelines(self, lines: List[Union[bytes, bytearray]]) -> None: ... - def writelines(self, __lines: Any) -> None: ... - def readline(self, __size: Optional[int] = ...) -> bytes: ... - def __del__(self) -> None: ... - closed: bool - # copied from BufferedIOBase - def detach(self) -> RawIOBase: ... - def readinto(self, __buffer: _bytearray_like) -> int: ... - def write(self, __b: Union[bytes, bytearray]) -> int: ... - def readinto1(self, __buffer: _bytearray_like) -> int: ... - def read(self, __size: Optional[int] = ...) -> bytes: ... - if sys.version_info >= (3, 7): - def read1(self, __size: Optional[int] = ...) -> bytes: ... - else: - def read1(self, __size: Optional[int]) -> bytes: ... class BufferedReader(BufferedIOBase): def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... From 51e9829f61af050ee0a588840f12e9570c756ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Mon, 25 May 2020 22:47:36 -0300 Subject: [PATCH 02/12] Remove BinaryIO from explicit inheritance. --- stdlib/3/io.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index 944bfd185cc7..17c06255ab26 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -77,7 +77,7 @@ class FileIO(RawIOBase): opener: Optional[Callable[[Union[int, str], str], int]] = ... ) -> None: ... -class BytesIO(BufferedIOBase, BinaryIO): +class BytesIO(BufferedIOBase): def __init__(self, initial_bytes: bytes = ...) -> None: ... # BytesIO does not contain a "name" field. This workaround is necessary # to allow BytesIO sub-classes to add this field, as it is defined From fd70d01cc11d2ce38cc0d14145a6286b5d1292ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Tue, 26 May 2020 11:38:08 -0300 Subject: [PATCH 03/12] Add explicit inheritance to IO[bytes]. --- stdlib/3/io.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index 17c06255ab26..70e2ebbda3f9 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -77,7 +77,7 @@ class FileIO(RawIOBase): opener: Optional[Callable[[Union[int, str], str], int]] = ... ) -> None: ... -class BytesIO(BufferedIOBase): +class BytesIO(BufferedIOBase, IO[bytes]): def __init__(self, initial_bytes: bytes = ...) -> None: ... # BytesIO does not contain a "name" field. This workaround is necessary # to allow BytesIO sub-classes to add this field, as it is defined From 7572f9bf2cdd2f120e4769de6a42165def12175b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Tue, 26 May 2020 12:29:49 -0300 Subject: [PATCH 04/12] Declare __enter__ in BytesIO as well. --- stdlib/3/io.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index 70e2ebbda3f9..b8d70ebd7697 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -83,6 +83,7 @@ class BytesIO(BufferedIOBase, IO[bytes]): # to allow BytesIO sub-classes to add this field, as it is defined # as a read-only property on IO[]. name: Any + def __enter__(self: _T) -> _T: ... def getvalue(self) -> bytes: ... def getbuffer(self) -> memoryview: ... From faa5b041b53e15bfda9fa3d20ce284476c2d4bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Wed, 27 May 2020 21:23:24 -0300 Subject: [PATCH 05/12] Apply suggestions by @hauntsaninja. --- stdlib/3/io.pyi | 8 +++++--- tests/stubtest_whitelists/py3_common.txt | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index b8d70ebd7697..4c23b750a539 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -44,7 +44,7 @@ class IOBase: def truncate(self, __size: Optional[int] = ...) -> int: ... def writable(self) -> bool: ... def writelines(self, __lines: Iterable[Union[bytes, bytearray]]) -> None: ... - def readline(self, __size: int = ...) -> bytes: ... + def readline(self, __size: Optional[int] = ...) -> bytes: ... def __del__(self) -> None: ... @property def closed(self) -> bool: ... @@ -63,8 +63,10 @@ class BufferedIOBase(IOBase): def write(self, __buffer: Union[bytes, bytearray]) -> int: ... def readinto1(self, __buffer: _bytearray_like) -> int: ... def read(self, __size: Optional[int] = ...) -> bytes: ... - def read1(self, __size: int = ...) -> bytes: ... - + if sys.version_info >= (3, 7): + def read1(self, __size: int = ...) -> bytes: ... + else: + def read1(self, __size: int) -> bytes: ... class FileIO(RawIOBase): mode: str diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index d58ac3cfcb0b..b513da4d74c0 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -247,6 +247,7 @@ io.BufferedReader.truncate io.BufferedWriter.seek io.BufferedWriter.truncate io.BytesIO.readlines +io.BytesIO.seek io.FileIO.seek io.StringIO.seek io.StringIO.truncate From fba1d2818f9a23e638281fd62e03d1f8d973c11d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Wed, 27 May 2020 21:36:23 -0300 Subject: [PATCH 06/12] Change argument type on gzip and lzma's readline. --- stdlib/3/gzip.pyi | 2 +- stdlib/3/lzma.pyi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/3/gzip.pyi b/stdlib/3/gzip.pyi index ce8152c34f09..b7876e4c4b37 100644 --- a/stdlib/3/gzip.pyi +++ b/stdlib/3/gzip.pyi @@ -40,7 +40,7 @@ class GzipFile(_compression.BaseStream): def writable(self) -> bool: ... def seekable(self) -> bool: ... def seek(self, offset: int, whence: int = ...) -> int: ... - def readline(self, size: int = ...) -> bytes: ... + def readline(self, size: Optional[int] = ...) -> bytes: ... class _GzipReader(_compression.DecompressReader): def __init__(self, fp: IO[bytes]) -> None: ... diff --git a/stdlib/3/lzma.pyi b/stdlib/3/lzma.pyi index 37009c813cee..08dba8076327 100644 --- a/stdlib/3/lzma.pyi +++ b/stdlib/3/lzma.pyi @@ -85,7 +85,7 @@ class LZMAFile(io.BufferedIOBase, IO[bytes]): # type: ignore # python/mypy#502 def peek(self, size: int = ...) -> bytes: ... def read(self, size: Optional[int] = ...) -> bytes: ... def read1(self, size: int = ...) -> bytes: ... - def readline(self, size: int = ...) -> bytes: ... + def readline(self, size: Optional[int] = ...) -> bytes: ... def write(self, data: bytes) -> int: ... def seek(self, offset: int, whence: int = ...) -> int: ... def tell(self) -> int: ... From 842bee7df492cfaea62e354ce9ef8d887475d334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Wed, 27 May 2020 21:50:11 -0300 Subject: [PATCH 07/12] Add bz2.BZ2File.read1 to whitelists. --- tests/stubtest_whitelists/py35.txt | 1 + tests/stubtest_whitelists/py36.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/stubtest_whitelists/py35.txt b/tests/stubtest_whitelists/py35.txt index e2d141036b92..ff7d3799faac 100644 --- a/tests/stubtest_whitelists/py35.txt +++ b/tests/stubtest_whitelists/py35.txt @@ -17,6 +17,7 @@ asyncio.tasks.Task._wakeup asyncio.unix_events._UnixSelectorEventLoop.create_unix_server bdb.GENERATOR_AND_COROUTINE_FLAGS builtins.str.maketrans +bz2.BZ2File.read1 cmath.log codecs.StreamRecoder.seek collections.Reversible diff --git a/tests/stubtest_whitelists/py36.txt b/tests/stubtest_whitelists/py36.txt index 7a5d18c2ea92..5629f3c08ab1 100644 --- a/tests/stubtest_whitelists/py36.txt +++ b/tests/stubtest_whitelists/py36.txt @@ -6,6 +6,7 @@ asyncio.protocols.BufferedProtocol asyncio.runners asyncio.unix_events._UnixSelectorEventLoop.create_unix_server builtins.str.maketrans +bz2.BZ2File.read1 cmath.log codecs.StreamRecoder.seek collections.AsyncGenerator.ag_await From d7178fc981d3b7030d0c9d67cc5eee1f3511f6b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Wed, 27 May 2020 22:02:17 -0300 Subject: [PATCH 08/12] Remove unused whitelist entries. --- tests/stubtest_whitelists/py35.txt | 2 -- tests/stubtest_whitelists/py36.txt | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/stubtest_whitelists/py35.txt b/tests/stubtest_whitelists/py35.txt index ff7d3799faac..4878dbac7154 100644 --- a/tests/stubtest_whitelists/py35.txt +++ b/tests/stubtest_whitelists/py35.txt @@ -33,8 +33,6 @@ gettext.npgettext gettext.pgettext importlib.metadata importlib.resources -io.BufferedRandom.read1 -io.BufferedReader.read1 io.StringIO.readline ipaddress._BaseNetwork.__init__ json.dump diff --git a/tests/stubtest_whitelists/py36.txt b/tests/stubtest_whitelists/py36.txt index 5629f3c08ab1..c174c81beced 100644 --- a/tests/stubtest_whitelists/py36.txt +++ b/tests/stubtest_whitelists/py36.txt @@ -30,8 +30,6 @@ gettext.npgettext gettext.pgettext importlib.metadata importlib.resources -io.BufferedRandom.read1 -io.BufferedReader.read1 io.StringIO.readline ipaddress._BaseNetwork.__init__ json.loads From 8409b91af85c53b1d2be4f0b467f8289cd13001c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Thu, 28 May 2020 13:10:52 -0300 Subject: [PATCH 09/12] Apply suggested changes. --- stdlib/3/io.pyi | 19 ++++++++++++++----- tests/stubtest_whitelists/py35.txt | 1 - tests/stubtest_whitelists/py36.txt | 1 - 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index 4c23b750a539..e73f9e994798 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -63,10 +63,7 @@ class BufferedIOBase(IOBase): def write(self, __buffer: Union[bytes, bytearray]) -> int: ... def readinto1(self, __buffer: _bytearray_like) -> int: ... def read(self, __size: Optional[int] = ...) -> bytes: ... - if sys.version_info >= (3, 7): - def read1(self, __size: int = ...) -> bytes: ... - else: - def read1(self, __size: int) -> bytes: ... + def read1(self, __size: int = ...) -> bytes: ... class FileIO(RawIOBase): mode: str @@ -79,7 +76,7 @@ class FileIO(RawIOBase): opener: Optional[Callable[[Union[int, str], str], int]] = ... ) -> None: ... -class BytesIO(BufferedIOBase, IO[bytes]): +class BytesIO(BufferedIOBase, BinaryIO): def __init__(self, initial_bytes: bytes = ...) -> None: ... # BytesIO does not contain a "name" field. This workaround is necessary # to allow BytesIO sub-classes to add this field, as it is defined @@ -88,10 +85,18 @@ class BytesIO(BufferedIOBase, IO[bytes]): def __enter__(self: _T) -> _T: ... def getvalue(self) -> bytes: ... def getbuffer(self) -> memoryview: ... + if sys.version_info >= (3, 7): + def read1(self, __size: int = ...) -> bytes: ... + else: + def read1(self, __size: int) -> bytes: ... class BufferedReader(BufferedIOBase): def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... def peek(self, __size: int = ...) -> bytes: ... + if sys.version_info >= (3, 7): + def read1(self, __size: int = ...) -> bytes: ... + else: + def read1(self, __size: int) -> bytes: ... class BufferedWriter(BufferedIOBase): def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... @@ -102,6 +107,10 @@ class BufferedRandom(BufferedReader, BufferedWriter): def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... def seek(self, __target: int, __whence: int = ...) -> int: ... def tell(self) -> int: ... + if sys.version_info >= (3, 7): + def read1(self, __size: int = ...) -> bytes: ... + else: + def read1(self, __size: int) -> bytes: ... class BufferedRWPair(BufferedIOBase): def __init__(self, reader: RawIOBase, writer: RawIOBase, diff --git a/tests/stubtest_whitelists/py35.txt b/tests/stubtest_whitelists/py35.txt index 4878dbac7154..855fc9dfa5bb 100644 --- a/tests/stubtest_whitelists/py35.txt +++ b/tests/stubtest_whitelists/py35.txt @@ -17,7 +17,6 @@ asyncio.tasks.Task._wakeup asyncio.unix_events._UnixSelectorEventLoop.create_unix_server bdb.GENERATOR_AND_COROUTINE_FLAGS builtins.str.maketrans -bz2.BZ2File.read1 cmath.log codecs.StreamRecoder.seek collections.Reversible diff --git a/tests/stubtest_whitelists/py36.txt b/tests/stubtest_whitelists/py36.txt index c174c81beced..d072377cd4d9 100644 --- a/tests/stubtest_whitelists/py36.txt +++ b/tests/stubtest_whitelists/py36.txt @@ -6,7 +6,6 @@ asyncio.protocols.BufferedProtocol asyncio.runners asyncio.unix_events._UnixSelectorEventLoop.create_unix_server builtins.str.maketrans -bz2.BZ2File.read1 cmath.log codecs.StreamRecoder.seek collections.AsyncGenerator.ag_await From d60731d478ff3dba2a002267e37dc5aede9be3e9 Mon Sep 17 00:00:00 2001 From: Tarcisio Date: Thu, 28 May 2020 09:11:25 -0700 Subject: [PATCH 10/12] Update tests/stubtest_whitelists/py3_common.txt Co-authored-by: Shantanu --- tests/stubtest_whitelists/py3_common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/stubtest_whitelists/py3_common.txt b/tests/stubtest_whitelists/py3_common.txt index b513da4d74c0..1a3c4171e120 100644 --- a/tests/stubtest_whitelists/py3_common.txt +++ b/tests/stubtest_whitelists/py3_common.txt @@ -247,7 +247,7 @@ io.BufferedReader.truncate io.BufferedWriter.seek io.BufferedWriter.truncate io.BytesIO.readlines -io.BytesIO.seek +io.BytesIO.seek # Parameter name for a positional-only param differs from its name in the inherited method io.FileIO.seek io.StringIO.seek io.StringIO.truncate From 35c1e4d1cfd4e690b934b6761cc759d70ace7136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarc=C3=ADsio=20Eduardo=20Moreira=20Crocomo?= Date: Thu, 28 May 2020 13:35:42 -0300 Subject: [PATCH 11/12] Add type: ignore for LSP-breaks on Python <= 3.6. --- stdlib/3/io.pyi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index e73f9e994798..22c655d0255f 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -88,7 +88,7 @@ class BytesIO(BufferedIOBase, BinaryIO): if sys.version_info >= (3, 7): def read1(self, __size: int = ...) -> bytes: ... else: - def read1(self, __size: int) -> bytes: ... + def read1(self, __size: int) -> bytes: ... # type: ignore class BufferedReader(BufferedIOBase): def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... @@ -96,7 +96,7 @@ class BufferedReader(BufferedIOBase): if sys.version_info >= (3, 7): def read1(self, __size: int = ...) -> bytes: ... else: - def read1(self, __size: int) -> bytes: ... + def read1(self, __size: int) -> bytes: ... # type: ignore class BufferedWriter(BufferedIOBase): def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ... @@ -110,7 +110,7 @@ class BufferedRandom(BufferedReader, BufferedWriter): if sys.version_info >= (3, 7): def read1(self, __size: int = ...) -> bytes: ... else: - def read1(self, __size: int) -> bytes: ... + def read1(self, __size: int) -> bytes: ... # type: ignore class BufferedRWPair(BufferedIOBase): def __init__(self, reader: RawIOBase, writer: RawIOBase, From ccf3d8b583d1aaa19500e747800364d997841910 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 28 May 2020 16:42:00 -0700 Subject: [PATCH 12/12] read1 size argument is Optional --- stdlib/3/io.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stdlib/3/io.pyi b/stdlib/3/io.pyi index 22c655d0255f..84cc44860bed 100644 --- a/stdlib/3/io.pyi +++ b/stdlib/3/io.pyi @@ -86,9 +86,9 @@ class BytesIO(BufferedIOBase, BinaryIO): def getvalue(self) -> bytes: ... def getbuffer(self) -> memoryview: ... if sys.version_info >= (3, 7): - def read1(self, __size: int = ...) -> bytes: ... + def read1(self, __size: Optional[int] = ...) -> bytes: ... else: - def read1(self, __size: int) -> bytes: ... # type: ignore + def read1(self, __size: Optional[int]) -> bytes: ... # type: ignore class BufferedReader(BufferedIOBase): def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ...