Hi,
I now understood that protocols should be avoided, they are low-level,
stream reader/writer should be preferred (high-level API). Ok, but
StreamReader and StreamWriter cannot be used with subprocess because
it's not possible to choose the protocols used for stdin, stdout and
stderr: WriteSubprocessPipeProto and ReadSubprocessPipeProto are used.
Moreover, StreamWriter is designed for socket: it requires to be a
pair with a StreamReader (stdin is not linked to stdout or stderr).
Well, a dedicated StreamWriter class can be written for stdin. But
StreamWriter also expects the transport to call resume_writing() and
pause_writing(), whereas _UnixWritePipeTransport doesn't.
The goal is to be able to just write "yield from read(...)" and
"write(...); yield from drain()". Example:
---
@asyncio.coroutine
def cat(loop):
transport, protocol = yield from
loop.subprocess_shell(SubprocessStreamReader, "cat")
print("pid: %s" % transport.get_pid())
stdin = protocol.stdin
stdout = protocol.stdout
message = "Hello World!"
print("write: %r" % message)
stdin.write(message.encode('ascii'))
yield from stdin.drain()
stdin.close()
read = yield from stdout.read()
print("read: %r" % read.decode('ascii'))
transport.close()
@asyncio.coroutine
def ls(loop):
transport, protocol = yield from
loop.subprocess_shell(SubprocessStreamReader, "ls", stdin=None)
while True:
line = yield from protocol.stdout.readline()
if not line:
break
print(">>", line.decode('ascii').rstrip())
transport.close()
---
I have a work-in-progress code which implements StreamReader for
stdout and stderr, but stdin is still a transport, not a stream
writer, and so stdin does not have a drain() method.
https://bitbucket.org/haypo/asyncio_staging/src/36fa55f6e030979469b8f0e002b5a8d6223753a7/subprocess_stream.py?at=default
I will try to hack asyncio to see how StreamWriter can be implemented for stdin.
Victor