For the whole set of functions I’d note in the current I/O stack you can’t do text mode without buffering / the buffering argument must be non-zero (Can either be line buffering or fixed size buffering at the moment).
I’d advocate either explicitly always doing Raw I/O / RawIOBase (direct byte stream access with POSIX read/write semantics “write some” + retry loop necessary) or explicitly always higher level I/O / BufferedIOBase (which generally gives “write all”). From my perspective the sort of exposed buffering at all the layers makes a lot more variants with some very specific behaviors that implementers would need to match. If can keep that out of public API will simplify implementations.
Re: BytesDuplex as a note the current Python I/O code calls this BufferedRandom rather than duplex.