Skip to content

readinto should accept any bytes-like object not just memoryview #15311

@hXtreme

Description

@hXtreme

typeshed/stdlib/_io.pyi

Lines 126 to 140 in a3568ac

@type_check_only
class _BufferedReaderStream(Protocol):
def read(self, n: int = ..., /) -> bytes: ...
# Optional: def readall(self) -> bytes: ...
def readinto(self, b: memoryview, /) -> int | None: ...
def seek(self, pos: int, whence: int, /) -> int: ...
def tell(self) -> int: ...
def truncate(self, size: int, /) -> int: ...
def flush(self) -> object: ...
def close(self) -> object: ...
@property
def closed(self) -> bool: ...
def readable(self) -> bool: ...
def seekable(self) -> bool: ...

From python docs:
https://docs.python.org/3/library/io.html#io.RawIOBase.readinto

Read bytes into a pre-allocated, writable bytes-like object b

Where bytes-like objects can be any of:

object that supports the Buffer Protocol and can export a C-contiguous buffer. This includes all bytes, bytearray, and array.array objects, as well as many common memoryview objects. ...

And more relevant to BufferReaderStream would be the read-write variant of bytes-like object https://docs.python.org/3/glossary.html#term-bytes-like-object

Some operations need the binary data to be mutable. The documentation often refers to these as “read-write bytes-like objects”. Example mutable buffer objects include bytearray and a memoryview of a bytearray.


Not having bytearray as a possible type for b makes it so that urllib3's BaseHTTPResponse.readinto fails typechecking when you do something like:

import io
import requests
from urllib3.response import HTTPResponse

with requests.get(url, stream=True) as response:
        data_stream = response.raw
        assert isinstance(data_stream, HTTPResponse)
        _ = io.BufferedReader(data_stream)
error: Argument 1 to "BufferedReader" has incompatible type "HTTPResponse"; expected "_BufferedReaderStream"  [arg-type]
note: Following member(s) of "HTTPResponse" have conflicts:
note:     Expected:
note:         def readinto(self, memoryview[int], /) -> int | None
note:     Got:
note:         def readinto(self, b: bytearray) -> int

Will also be filing a issue with the urllib3 repo, since I believe that they should also be accepting more types in their readinto method implementation
urllib3/urllib3#3764

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions