loop.subprocess_xxx() will give give your protocol a callback when the process exits (which may be earlier or later than when the pipes are closed). It also manages connecting the pipes for you. But you don't *have* to use it.
On Thu, Jan 23, 2014 at 8:40 AM, Gustavo Carneiro <[email protected]> wrote: > It's funny that I've been using subprocesses without even being aware of > loop.subprocess_exec(). I just followed the child_process.py example in > Tulip, and it works fine. Why should we use loop.subprocess_xxx instead of > plain old subprocess.Popen followed by connecting the pipes to asyncio > streams? > > > On 23 January 2014 16:17, Phil Schaf <[email protected]> wrote: >> >> Am Donnerstag, 23. Januar 2014 16:48:46 UTC+1 schrieb Guido van Rossum: >>> >>> Read the source code of asyncio/streams.py. There are helper classes >>> that should let you do it. Please post the solution here. >>> -- >>> --Guido van Rossum (python.org/~guido) >> >> i’m deep inside that source for some hours now, but since i never did >> multiple inheritance, only your comment convinced me that i can ideed marry >> SubprocessProtocol and a StreamReaderProtocol. >> >> import sys >> from functools import partial >> from asyncio.protocols import SubprocessProtocol >> from asyncio.streams import StreamReader, StreamReaderProtocol >> >> cmd = […] >> >> @coroutine >> def do_task(msg): >> loop = get_event_loop() >> reader = StreamReader(float('inf'), loop) >> >> transport, proto = yield from loop.subprocess_exec( >> partial(StdOutReaderProtocol, reader, loop=loop), *cmd) >> >> stdin = transport.get_pipe_transport(0) >> stdin.write(msg) >> stdin.write_eof() # which of those is actually necessary? only eof? >> only close? >> stdin.close() >> >> while True: # would be nice to do “for line in iter(reader.readline, >> b'')”, but not possible with coroutines >> line = yield from reader.readline() >> if not line: >> break >> do_something_with(line) >> >> class StdOutReaderProtocol(StreamReaderProtocol, SubprocessProtocol): >> def pipe_data_received(self, fd, data): >> if fd == 1: >> self.data_received(data) >> else: >> print('stderr from subprocess:', data.decode(), >> file=sys.stderr, end='') >> >> that was completely strange, though. imho there should be a easier way to >> do it instead of figuring this one out. >> >> thanks for your encouragement! >> >> – Phil > > > > > -- > Gustavo J. A. M. Carneiro > Gambit Research LLC > "The universe is always one step beyond logic." -- Frank Herbert -- --Guido van Rossum (python.org/~guido)
