I create a class inherited from io.RawIOBase and then manually define its write method with typing hints.
My trys
First, I casually annotatememoryview | bytearray | bytes. Of course, that’s incorrect.
import io
class VoidStream(io.RawIOBase):
# Argument 1 of "write" is incompatible with
# supertype "_RawIOBase"; supertype defines
# the argument type as "Buffer"
def write(self, b: memoryview | bytes | bytearray) -> int:
return len(b)
Then, I modify the annotation to collection.abc.Buffer, but:
from collections.abc import Buffer
import io
class VoidStream(io.RawIOBase):
def write(self, b: Buffer) -> int:
# Argument 1 to "len" has incompatible
# type "Buffer"; expected "Sized"
return len(b)
I learned mypy actually use the typeshed repository. The _io.pyi file also shows:
if sys.version_info >= (3, 12):
from collections.abc import Buffer as Buffer
ReadableBuffer: TypeAlias = Buffer
def write(self, b: ReadableBuffer, /)
Finally, I worked out two hacking ways for bypassing.
def write(self, b: Buffer):
b = memoryview(b)
return len(b)
def write(self, b: memoryview): # type: ignore
Question:
- (out of curiosity) Is there any use case where
writeaccepts a not-len-able argument? - How to construct the non-hacking code to simultaneously satisfy both
writeandlen?
Thanks.