Introduce ReadableBuffer and WriteableBuffer Union aliases (#4232)

Since typing doesn't yet have a way to express buffer protocol objects
(python/typing#593), various interfaces have ended up with a mish-mash
of options: some list just bytes (or just bytearray, when writable),
some include mmap, some include memoryview, I think none of them include
array.array even though it's explicitly mentioned as bytes-like, etc. I
ran into problems because RawIOBase.readinto didn't allow for
memoryview.

To allow for some uniformity until the fundamental issue is resolved,
I've introduced _typeshed.ReadableBuffer and _typeshed.WriteableBuffer,
and applied them in stdlib/3/io.pyi as an example. If these get rolled
out in more places, it will mean that we have only one place where they
have to get tweaked in future, or swapped out for a public protocol.

This unfortunately does have the potential to break code that inherits
from RawIOBase/BufferedIOBase and overrides these methods, because the
base method is now more general and so the override now needs to accept
these types as well (which is why I've also updated gzip and lzma).
However, it should be a reasonably easy fix, and will make the
downstream annotations more correct.
This commit is contained in:
Bruce Merry
2020-06-19 12:45:12 +02:00
committed by GitHub
parent 1350e710cc
commit e05fbabdeb
4 changed files with 18 additions and 14 deletions

View File

@@ -6,8 +6,7 @@ import codecs
import sys
from mmap import mmap
from types import TracebackType
_bytearray_like = Union[bytearray, mmap]
from _typeshed import ReadableBuffer, WriteableBuffer
DEFAULT_BUFFER_SIZE: int
@@ -42,7 +41,7 @@ class IOBase:
def tell(self) -> int: ...
def truncate(self, __size: Optional[int] = ...) -> int: ...
def writable(self) -> bool: ...
def writelines(self, __lines: Iterable[Union[bytes, bytearray]]) -> None: ...
def writelines(self, __lines: Iterable[ReadableBuffer]) -> None: ...
def readline(self, __size: Optional[int] = ...) -> bytes: ...
def __del__(self) -> None: ...
@property
@@ -51,16 +50,16 @@ class IOBase:
class RawIOBase(IOBase):
def readall(self) -> bytes: ...
def readinto(self, __buffer: bytearray) -> Optional[int]: ...
def write(self, __b: Union[bytes, bytearray]) -> Optional[int]: ...
def readinto(self, __buffer: WriteableBuffer) -> Optional[int]: ...
def write(self, __b: ReadableBuffer) -> Optional[int]: ...
def read(self, __size: int = ...) -> Optional[bytes]: ...
class BufferedIOBase(IOBase):
raw: RawIOBase # This is not part of the BufferedIOBase API and may not exist on some implementations.
def detach(self) -> RawIOBase: ...
def readinto(self, __buffer: _bytearray_like) -> int: ...
def write(self, __buffer: Union[bytes, bytearray]) -> int: ...
def readinto1(self, __buffer: _bytearray_like) -> int: ...
def readinto(self, __buffer: WriteableBuffer) -> int: ...
def write(self, __buffer: ReadableBuffer) -> int: ...
def readinto1(self, __buffer: WriteableBuffer) -> int: ...
def read(self, __size: Optional[int] = ...) -> bytes: ...
def read1(self, __size: int = ...) -> bytes: ...
@@ -75,7 +74,7 @@ class FileIO(RawIOBase, BinaryIO):
closefd: bool = ...,
opener: Optional[Callable[[Union[int, str], str], int]] = ...
) -> None: ...
def write(self, __b: bytes) -> int: ...
def write(self, __b: ReadableBuffer) -> int: ...
def read(self, __size: int = ...) -> bytes: ...
def __enter__(self: _T) -> _T: ...
@@ -105,7 +104,7 @@ class BufferedReader(BufferedIOBase, BinaryIO):
class BufferedWriter(BufferedIOBase, BinaryIO):
def __enter__(self: _T) -> _T: ...
def __init__(self, raw: RawIOBase, buffer_size: int = ...) -> None: ...
def write(self, __buffer: Union[bytes, bytearray]) -> int: ...
def write(self, __buffer: ReadableBuffer) -> int: ...
class BufferedRandom(BufferedReader, BufferedWriter):
def __enter__(self: _T) -> _T: ...