@@ -27,23 +27,34 @@ Example to use it on Windows::
2727Create a subprocess: high-level API using Process
2828-------------------------------------------------
2929
30- .. function :: create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds)
30+ .. function :: create_subprocess_exec(\*args, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds)
31+
32+ Create a subprocess.
3133
32- Run the shell command *cmd *. See :meth: `BaseEventLoop.subprocess_shell ` for
33- parameters. Return a :class: `~asyncio.subprocess.Process ` instance.
34+ The *limit * parameter sets the buffer limit passed to the
35+ :class: `StreamReader `. See :meth: `BaseEventLoop.subprocess_exec ` for other
36+ parameters.
3437
35- The optional *limit * parameter sets the buffer limit passed to the
36- :class: `StreamReader `.
38+ Return a :class: `~asyncio.subprocess.Process ` instance.
3739
3840 This function is a :ref: `coroutine <coroutine >`.
3941
40- .. function :: create_subprocess_exec(\*args, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds)
42+ .. function :: create_subprocess_shell(cmd, stdin=None, stdout=None, stderr=None, loop=None, limit=None, \*\*kwds)
43+
44+ Run the shell command *cmd *.
4145
42- Create a subprocess. See :meth: `BaseEventLoop.subprocess_exec ` for
43- parameters. Return a :class: `~asyncio.subprocess.Process ` instance.
46+ The *limit * parameter sets the buffer limit passed to the
47+ :class: `StreamReader `. See :meth: `BaseEventLoop.subprocess_shell ` for other
48+ parameters.
4449
45- The optional *limit * parameter sets the buffer limit passed to the
46- :class: `StreamReader `.
50+ Return a :class: `~asyncio.subprocess.Process ` instance.
51+
52+ It is the application's responsibility to ensure that all whitespace and
53+ metacharacters are quoted appropriately to avoid `shell injection
54+ <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection> `_
55+ vulnerabilities. The :func: `shlex.quote ` function can be used to properly
56+ escape whitespace and shell metacharacters in strings that are going to be
57+ used to construct shell commands.
4758
4859 This function is a :ref: `coroutine <coroutine >`.
4960
@@ -69,6 +80,9 @@ Run subprocesses asynchronously using the :mod:`subprocess` module.
6980 however, where :class: `~subprocess.Popen ` takes a single argument which is
7081 list of strings, :func: `subprocess_exec ` takes multiple string arguments.
7182
83+ The *protocol_factory * must instanciate a subclass of the
84+ :class: `asyncio.SubprocessProtocol ` class.
85+
7286 Other parameters:
7387
7488 * *stdin *: Either a file-like object representing the pipe to be connected
@@ -109,15 +123,23 @@ Run subprocesses asynchronously using the :mod:`subprocess` module.
109123 using the platform's "shell" syntax. This is similar to the standard library
110124 :class: `subprocess.Popen ` class called with ``shell=True ``.
111125
126+ The *protocol_factory * must instanciate a subclass of the
127+ :class: `asyncio.SubprocessProtocol ` class.
128+
112129 See :meth: `~BaseEventLoop.subprocess_exec ` for more details about
113130 the remaining arguments.
114131
115132 Returns a pair of ``(transport, protocol) ``, where *transport * is an
116133 instance of :class: `BaseSubprocessTransport `.
117134
118- This method is a :ref: `coroutine <coroutine >`.
135+ It is the application's responsibility to ensure that all whitespace and
136+ metacharacters are quoted appropriately to avoid `shell injection
137+ <http://en.wikipedia.org/wiki/Shell_injection#Shell_injection> `_
138+ vulnerabilities. The :func: `shlex.quote ` function can be used to properly
139+ escape whitespace and shell metacharacters in strings that are going to be
140+ used to construct shell commands.
119141
120- See the constructor of the :class: ` subprocess.Popen ` class for parameters .
142+ This method is a :ref: ` coroutine < coroutine >` .
121143
122144.. seealso ::
123145
@@ -153,35 +175,37 @@ Process
153175
154176.. class :: asyncio.subprocess.Process
155177
156- .. attribute :: pid
157-
158- The identifier of the process.
159-
160- Note that if you set the *shell * argument to ``True ``, this is the
161- process identifier of the spawned shell.
162-
163- .. attribute :: returncode
178+ A subprocess created by the :func: `create_subprocess_exec ` or the
179+ :func: `create_subprocess_shell ` function.
164180
165- Return code of the process when it exited. A ``None `` value indicates
166- that the process has not terminated yet.
167-
168- A negative value ``-N `` indicates that the child was terminated by signal
169- ``N `` (Unix only).
181+ The API of the :class: `~asyncio.subprocess.Process ` class was designed to be
182+ closed the API of the :class: `subprocess.Popen ` class, but they are some
183+ differences:
170184
171- .. attribute :: stdin
185+ * There is no explicit :meth: `~subprocess.Popen.poll ` method
186+ * The :meth: `~subprocess.Popen.communicate ` and
187+ :meth: `~subprocess.Popen.wait ` methods don't take a *timeout * parameter:
188+ use the :func: `wait_for ` function
189+ * The *universal_newlines * parameter is not supported (only bytes strings
190+ are supported)
191+ * The :meth: `~asyncio.subprocess.Process.wait ` method of
192+ the :class: `~asyncio.subprocess.Process ` class is asynchronous whereas the
193+ :meth: `~subprocess.Popen.wait ` method of the :class: `~subprocess.Popen `
194+ class is implemented as a busy loop.
172195
173- Standard input stream (write), ``None `` if the process was created with
174- ``stdin=None ``.
196+ .. method :: wait()
175197
176- .. attribute :: stdout
198+ Wait for child process to terminate. Set and return :attr: `returncode `
199+ attribute.
177200
178- Standard output stream (read), ``None `` if the process was created with
179- ``stdout=None ``.
201+ This method is a :ref: `coroutine <coroutine >`.
180202
181- .. attribute :: stderr
203+ .. note ::
182204
183- Standard error stream (read), ``None `` if the process was created with
184- ``stderr=None ``.
205+ This will deadlock when using ``stdout=PIPE `` or ``stderr=PIPE `` and
206+ the child process generates enough output to a pipe such that it
207+ blocks waiting for the OS pipe buffer to accept more data. Use the
208+ :meth: `communicate ` method when using pipes to avoid that.
185209
186210 .. method :: communicate(input=None)
187211
@@ -191,33 +215,28 @@ Process
191215 process, or ``None ``, if no data should be sent to the child. The type
192216 of *input * must be bytes.
193217
218+ :meth: `communicate ` returns a tuple ``(stdout_data, stderr_data) ``.
219+
194220 If a :exc: `BrokenPipeError ` or :exc: `ConnectionResetError ` exception is
195221 raised when writing *input * into stdin, the exception is ignored. It
196222 occurs when the process exits before all data are written into stdin.
197223
198- :meth: `communicate ` returns a tuple ``(stdoutdata, stderrdata) ``.
199-
200224 Note that if you want to send data to the process's stdin, you need to
201225 create the Process object with ``stdin=PIPE ``. Similarly, to get anything
202226 other than ``None `` in the result tuple, you need to give ``stdout=PIPE ``
203227 and/or ``stderr=PIPE `` too.
204228
229+ This method is a :ref: `coroutine <coroutine >`.
230+
205231 .. note ::
206232
207233 The data read is buffered in memory, so do not use this method if the
208234 data size is large or unlimited.
209235
210- This method is a :ref: `coroutine <coroutine >`.
211-
212236 .. versionchanged :: 3.4.2
213237 The method now ignores :exc: `BrokenPipeError ` and
214238 :exc: `ConnectionResetError `.
215239
216- .. method :: kill()
217-
218- Kills the child. On Posix OSs the function sends :py:data: `SIGKILL ` to
219- the child. On Windows :meth: `kill ` is an alias for :meth: `terminate `.
220-
221240 .. method :: send_signal(signal)
222241
223242 Sends the signal *signal * to the child process.
@@ -235,53 +254,142 @@ Process
235254 to the child. On Windows the Win32 API function
236255 :c:func: `TerminateProcess ` is called to stop the child.
237256
238- .. method :: wait():
257+ .. method :: kill()
239258
240- Wait for child process to terminate. Set and return :attr: ` returncode `
241- attribute .
259+ Kills the child. On Posix OSs the function sends :py:data: ` SIGKILL ` to
260+ the child. On Windows :meth: ` kill ` is an alias for :meth: ` terminate ` .
242261
243- This method is a :ref: ` coroutine < coroutine >`.
262+ .. attribute :: stdin
244263
264+ Standard input stream (:class: `StreamWriter `), ``None `` if the process
265+ was created with ``stdin=None ``.
245266
246- Example
247- -------
267+ .. attribute :: stdout
268+
269+ Standard output stream (:class: `StreamReader `), ``None `` if the process
270+ was created with ``stdout=None ``.
271+
272+ .. attribute :: stderr
273+
274+ Standard error stream (:class: `StreamReader `), ``None `` if the process
275+ was created with ``stderr=None ``.
276+
277+ .. warning ::
278+
279+ Use the :meth: `communicate ` method rather than :attr: `.stdin.write
280+ <stdin> `, :attr: `.stdout.read <stdout> ` or :attr: `.stderr.read <stderr> `
281+ to avoid deadlocks due to streams pausing reading or writing and blocking
282+ the child process.
283+
284+ .. attribute :: pid
285+
286+ The identifier of the process.
287+
288+ Note that for processes created by the :func: `create_subprocess_shell `
289+ function, this attribute is the process identifier of the spawned shell.
290+
291+ .. attribute :: returncode
292+
293+ Return code of the process when it exited. A ``None `` value indicates
294+ that the process has not terminated yet.
295+
296+ A negative value ``-N `` indicates that the child was terminated by signal
297+ ``N `` (Unix only).
298+
299+
300+ Subprocess examples
301+ ===================
248302
249- Implement a function similar to :func: `subprocess.getstatusoutput `, except that
250- it does not use a shell. Get the output of the "python -m platform" command and
251- display the output::
303+ Subprocess using transport and protocol
304+ ---------------------------------------
305+
306+ Example of a subprocess protocol using to get the output of a subprocess and to
307+ wait for the subprocess exit. The subprocess is created by the
308+ :meth: `BaseEventLoop.subprocess_exec ` method::
252309
253310 import asyncio
254- import os
255311 import sys
256- from asyncio import subprocess
257312
258- @asyncio.coroutine
259- def getstatusoutput(*args):
260- proc = yield from asyncio.create_subprocess_exec(
261- *args,
262- stdout=subprocess.PIPE,
263- stderr=subprocess.STDOUT)
264- try:
265- stdout, _ = yield from proc.communicate()
266- except:
267- proc.kill()
268- yield from proc.wait()
269- raise
270- exitcode = yield from proc.wait()
271- return (exitcode, stdout)
313+ class DateProtocol(asyncio.SubprocessProtocol):
314+ def __init__(self, exit_future):
315+ self.exit_future = exit_future
316+ self.output = bytearray()
272317
273- if os.name == 'nt':
318+ def pipe_data_received(self, fd, data):
319+ self.output.extend(data)
320+
321+ def process_exited(self):
322+ self.exit_future.set_result(True)
323+
324+ @asyncio.coroutine
325+ def get_date(loop):
326+ code = 'import datetime; print(datetime.datetime.now())'
327+ exit_future = asyncio.Future(loop=loop)
328+
329+ # Create the subprocess controlled by the protocol DateProtocol,
330+ # redirect the standard output into a pipe
331+ create = loop.subprocess_exec(lambda: DateProtocol(exit_future),
332+ sys.executable, '-c', code,
333+ stdin=None, stderr=None)
334+ transport, protocol = yield from create
335+
336+ # Wait for the subprocess exit using the process_exited() method
337+ # of the protocol
338+ yield from exit_future
339+
340+ # Close the stdout pipe
341+ transport.close()
342+
343+ # Read the output which was collected by the pipe_data_received()
344+ # method of the protocol
345+ data = bytes(protocol.output)
346+ return data.decode('ascii').rstrip()
347+
348+ if sys.platform == "win32":
274349 loop = asyncio.ProactorEventLoop()
275350 asyncio.set_event_loop(loop)
276351 else:
277352 loop = asyncio.get_event_loop()
278- coro = getstatusoutput(sys.executable, '-m', 'platform')
279- exitcode, stdout = loop.run_until_complete(coro)
280- if not exitcode:
281- stdout = stdout.decode('ascii').rstrip()
282- print("Platform: %s" % stdout)
353+
354+ date = loop.run_until_complete(get_date(loop))
355+ print("Current date: %s" % date)
356+ loop.close()
357+
358+
359+ Subprocess using streams
360+ ------------------------
361+
362+ Example using the :class: `~asyncio.subprocess.Process ` class to control the
363+ subprocess and the :class: `StreamReader ` class to read from the standard
364+ output. The subprocess is created by the :func: `create_subprocess_exec `
365+ function::
366+
367+ import asyncio.subprocess
368+ import sys
369+
370+ @asyncio.coroutine
371+ def get_date():
372+ code = 'import datetime; print(datetime.datetime.now())'
373+
374+ # Create the subprocess, redirect the standard output into a pipe
375+ create = asyncio.create_subprocess_exec(sys.executable, '-c', code,
376+ stdout=asyncio.subprocess.PIPE)
377+ proc = yield from create
378+
379+ # Read one line of output
380+ data = yield from proc.stdout.readline()
381+ line = data.decode('ascii').rstrip()
382+
383+ # Wait for the subprocess exit
384+ yield from proc.wait()
385+ return line
386+
387+ if sys.platform == "win32":
388+ loop = asyncio.ProactorEventLoop()
389+ asyncio.set_event_loop(loop)
283390 else:
284- print("Python failed with exit code %s:" % exitcode, flush=True)
285- sys.stdout.buffer.write(stdout)
286- sys.stdout.buffer.flush()
391+ loop = asyncio.get_event_loop()
392+
393+ date = loop.run_until_complete(get_date())
394+ print("Current date: %s" % date)
287395 loop.close()
0 commit comments