error: Argument 1 to "write" of "IO" has incompatible type "Union[bytes, bytearray, memoryview]"; expected "bytes" [arg-type]
Same using BinaryIO instead of IO[bytes].
As far as I can see, a binary file supports any object supporting the buffer protocol (or maybe less than that? However, the three types in the union tested are definitely supported).
Declaring f: IO[Buffer] almost works: write() doesn't complain anymore, but IO does: Invalid type argument value for "IO".
IO.write is declared as def write(self, __s: AnyStr) -> int: ..., so it only accepts exactly bytes if self is an IO[str]. Concrete binary IO classes do support any ReadableBuffer in their write methods, so it makes sense for IO[str] to do too. We can achieve that with overloads on self, similar to how we have handled re.Pattern.
The IO class is problematic because it doesn't exactly represent concrete IO classes well, and typeshed's recommendation is generally to use more specific protocols. However, IO is still widely used, so I think we should fix it. I'll submit a PR.
Activity
JelleZijlstra commented on Nov 4, 2022
IO.write is declared as def write(self, __s: AnyStr) -> int: ..., so it only accepts exactly bytes if self is an IO[str]. Concrete binary IO classes do support any ReadableBuffer in their write methods, so it makes sense for IO[str] to do too. We can achieve that with overloads on self, similar to how we have handled re.Pattern.
The IO class is problematic because it doesn't exactly represent concrete IO classes well, and typeshed's recommendation is generally to use more specific protocols. However, IO is still widely used, so I think we should fix it. I'll submit a PR.
typing: accept buffers in typing.IO.write