Skip to content

Python type hint for Reader/Writer should probably be IO[bytes] #241

@naegelejd

Description

@naegelejd

Currently, the Python BinaryProtocolReader accepts a binary input stream or a string filename:

class BinaryProtocolReader(ABC):
    def __init__(
        self,
        stream: Union[BufferedReader, BytesIO, BinaryIO, str],
        expected_schema: Optional[str],
    ) -> None:
    ....

However, Pyright 1.1.405 (2025-09-03) complains when the stream is of type IO[bytes], e.g.:

# Run mrd_phantom as subprocess and capture stdout
proc = subprocess.Popen(["mrd_phantom"], stdout=subprocess.PIPE)

if proc.stdout is None:
    raise RuntimeError("Failed to capture stdout")

with mrd.BinaryMrdReader(proc.stdout) as reader:    # <-- Pyright error
    ...

Pyright complains that

Argument of type "IO[bytes] | None" cannot be assigned to parameter "stream" of type "BufferedReader[_BufferedReaderStream] | BytesIO | BinaryIO | str" in function "__init__"
  Type "IO[bytes] | None" is not assignable to type "BufferedReader[_BufferedReaderStream] | BytesIO | BinaryIO | str"
    Type "IO[bytes]" is not assignable to type "BufferedReader[_BufferedReaderStream] | BytesIO | BinaryIO | str"
      "IO[bytes]" is not assignable to "BufferedReader[_BufferedReaderStream]"
      "IO[bytes]" is not assignable to "BytesIO"
      "IO[bytes]" is not assignable to "BinaryIO"
      "IO[bytes]" is not assignable to "str"Pylance[reportArgumentType](https://github.com/microsoft/pylance-release/blob/main/docs/diagnostics/reportArgumentType.md)

As I understand it, IO[bytes] is the generic ABC for all binary IO streams (source):

class typing.IO
class typing.TextIO
class typing.BinaryIO
Generic type IO[AnyStr] and its subclasses TextIO(IO[str]) and BinaryIO(IO[bytes]) represent the types of I/O streams such as returned by [open()](https://docs.python.org/3.8/library/functions.html#open).

This change appears to be recommended by type checkers like Ruff: astral-sh/ruff#15532

Similar changes may be needed for BinaryProtocolWriter, NDJsonProtocolReader, and NDJsonProtocolReader and they can also be tested using subprocess.PIPE.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions