Well, that's water under the bridge. I'm sure the current design is perfectly usable.
On Thu, Jan 23, 2014 at 9:46 AM, Gustavo Carneiro <[email protected]> wrote: > On 23 January 2014 17:12, Guido van Rossum <[email protected]> wrote: >> >> 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). > > > Sure. But my feeling is that waiting for the pipe to be closed is good > enough for most applications. You care more about stdin/stdout than you do > about the actual process, unless you are writing a daemon process supervisor > kind of thing (upstart/systemd). > >> It also manages connecting the pipes for you. > > > Well, it gives you one thing but expects another in return. It connects the > pipes, but expects a protocol factory. I don't want to write a protocol > factory just to be able to run a subprocess and capture its output, thank > you very much. > > Also, this confuses me: > > def subprocess_exec(self, protocol_factory, *args, > stdin=subprocess.PIPE, > stdout=subprocess.PIPE, stderr=subprocess.PIPE, > **kwargs): > > So you have a single protocol_factory, but potentially 3 pipes. Not only > you are forced to implement your own protocol, but you have to use the same > class to handle stdin, stdout, and stderr. I would expect to have 3 > different protocols, one for each pipe. > >> But you don't *have* to use it. > > > Sure. I think it's easier for me to write my own asyncio-friendly > subprocess.Popen wrapper instead. > > Sorry, I didn't mean to criticize these APIs this late in the release > process, but I hadn't noticed these methods and none of the tulip examples > use them, so they have stayed under my radar. > >> >> 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) > > > > > -- > Gustavo J. A. M. Carneiro > Gambit Research LLC > "The universe is always one step beyond logic." -- Frank Herbert -- --Guido van Rossum (python.org/~guido)
