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

Reply via email to