I notice there are “two series” of IO stream-style interface provide by Python standard library, which are
typing.IO, including BinaryIO and TextIO
io.IOBase, including RawIOBase, TextIOBase etc.
IOBase is good at functionality due to default mixin methods. But IO[AnyStr] seems designed for typing.
My project require to design my own stream-like class. So, I wonder: Question 1: Which one would be better to work as a parent class? Is it common to use none of typing.IO[AnyStr] for typing hints?
Besides, I see typeshed/stdlib/builtins.pyi designs both override for these two base classes.
So, comes the … Question 2. What’s the role of IO[AnyStr]?Is it a redundant design? Is there any case where typing.IO[AnyStr] works well but io.IOBase not.
typing.IO is a pseudo-protocol. It provides no implementation and was introduced before protocols existed to provide a way to say “this is a file-like object” or “this argument requires a file-like object”. As such it is somewhat of a legacy feature, but still required for full compatibility with legacy annotations.
io.IOBase (and its sub-classes) on the other hand is a utility that allows you to implement a class for “file-like” object without implementing all functionality yourself.
In doubt, you can derive from both, but make sure (by using a type checker) that you implement the full protocol mandated by typing.IO if you do so.
The docs have some notes on this in the section ABCs and Protocols for working with I/O. In particular there is a io.Reader and io.Writer that often simpler and useful for a lot of cases.