[Python-Dev] Status of PEP 3145 - Asynchronous I/O for subprocess.popen
Guido van Rossum
guido at python.org
Fri Mar 28 22:09:19 CET 2014
To be clear, the proposal for Idle would be to still use the RPC protocol,
but run it over a pipe instead of a socket, right?
On Fri, Mar 28, 2014 at 1:58 PM, Terry Reedy <tjreedy at udel.edu> wrote:
> On 3/28/2014 6:20 AM, Victor Stinner wrote:
>
> Full example of asynchronous communication with a subprocess (the
>> python interactive interpreter) using asyncio high-level API:
>>
>
> Thank you for writing this. As I explained in response to Josiah, Idle
> communicates with a python interpreter subprocess through a socket. Since
> making the connection is not dependable, I would like to replace the socket
> with the pipes. http://bugs.python.org/issue18823
>
> However, the code below creates a subprocess for one command and one
> response, which can apparently be done now with subprocess.communicate.
> What I and others need is a continuing (non-blocking) conversion with 1 and
> only 1 subprocess (see my response to Josiah), and that is much more
> difficult. So this code does not do what he claims his will do.
>
> However it is done, I agree with the intent of the PEP to make it much
> easier to talk with a subprocess. Victor, if you can rewrite the below with
> a run_forever loop that can accept new write-read task pairs and also make
> each line read immediately accessible, that would be really helpful. Post
> it on the issue above if you prefer.
>
> Another difference from what you wrote below and what Idle does today is
> that the shell, defined in idlelib/PyShell.py, does not talk to the
> subprocess interpreter directly but to a run supervisor defined in
> idlelib/run.py through an rpc protocol ('cmd', 'arg string'). To use the
> pipes, the supervisor would grab all input from stdin (instead of the
> socket) and exec user code as it does today, or it could be replaced by a
> supervisor class with an instance with a name like _idle_supervisor_3_4_0_
> that would be extremely unlikely to clash with any name created by users.
>
>
> ---
>> import asyncio.subprocess
>> import time
>> import sys
>>
>> @asyncio.coroutine
>> def eval_python_async(command, encoding='ascii', loop=None):
>> proc = yield from asyncio.subprocess.create_subprocess_exec(
>> sys.executable, "-u", "-i",
>> stdin=asyncio.subprocess.PIPE,
>> stdout=asyncio.subprocess.PIPE,
>> stderr=asyncio.subprocess.STDOUT,
>> loop=loop)
>>
>> # wait for the prompt
>> buffer = bytearray()
>> while True:
>> data = yield from proc.stdout.read(100)
>> buffer.extend(data)
>> if buffer.endswith(b'>>> '):
>> break
>>
>> proc.stdin.write(command.encode(encoding) + b"\n")
>> yield from proc.stdin.drain()
>> proc.stdin.close()
>>
>> output = yield from proc.stdout.read()
>>
>> output = output.decode(encoding)
>> output = output.rstrip()
>> if output.endswith('>>>'):
>> output = output[:-3].rstrip()
>> return output
>>
>> def eval_python(command, timeout=None):
>> loop = asyncio.get_event_loop()
>> task = asyncio.Task(eval_python_async(command, loop=loop),
>> loop=loop)
>> return loop.run_until_complete(asyncio.wait_for(task, timeout))
>>
>> def test_sequential(nproc, command):
>> t0 = time.monotonic()
>> for index in range(nproc):
>> eval_python(command)
>> return time.monotonic() - t0
>>
>> def test_parallel(nproc, command):
>> loop = asyncio.get_event_loop()
>> tasks = [asyncio.Task(eval_python_async(command, loop=loop),
>> loop=loop)
>> for index in range(nproc)]
>> t0 = time.monotonic()
>> loop.run_until_complete(asyncio.wait(tasks))
>> return time.monotonic() - t0
>>
>> print("1+1 = %r" % eval_python("1+1", timeout=1.0))
>>
>> slow_code = "import math; print(str(math.factorial(20000)).count('7'))"
>>
>> dt = test_sequential(10, slow_code)
>> print("Run 10 tasks in sequence: %.1f sec" % dt)
>>
>> dt2 = test_parallel(10, slow_code)
>> print("Run 10 tasks in parallel: %.1f sec (speed=%.1f)" % (dt2, dt/dt2))
>>
>> # cleanup asyncio
>> asyncio.get_event_loop().close()
>>
>
>
> --
> Terry Jan Reedy
>
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe: https://mail.python.org/mailman/options/python-dev/
> guido%40python.org
>
--
--Guido van Rossum (python.org/~guido)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20140328/d31dc076/attachment.html>
More information about the Python-Dev
mailing list