Remove backticks from a plaintext PEP.
This commit is contained in:
parent
d651737d8b
commit
cddfac92a6
54
pep-3145.txt
54
pep-3145.txt
|
@ -12,10 +12,10 @@ Post-History:
|
||||||
|
|
||||||
Abstract:
|
Abstract:
|
||||||
|
|
||||||
In its present form, the ``subprocess.Popen`` implementation is prone to
|
In its present form, the subprocess.Popen implementation is prone to
|
||||||
dead-locking and blocking of the parent Python script while waiting on data
|
dead-locking and blocking of the parent Python script while waiting on data
|
||||||
from the child process. This PEP proposes to make
|
from the child process. This PEP proposes to make
|
||||||
``subprocess.Popen`` more asynchronous to help alleviate these
|
subprocess.Popen more asynchronous to help alleviate these
|
||||||
problems.
|
problems.
|
||||||
|
|
||||||
Motivation:
|
Motivation:
|
||||||
|
@ -26,7 +26,7 @@ Motivation:
|
||||||
blocking to wait for the program to produce data [1] [2] [3]. The current
|
blocking to wait for the program to produce data [1] [2] [3]. The current
|
||||||
behavior of the subprocess module is that when a user sends or receives
|
behavior of the subprocess module is that when a user sends or receives
|
||||||
data via the stdin, stderr and stdout file objects, dead locks are common
|
data via the stdin, stderr and stdout file objects, dead locks are common
|
||||||
and documented [4] [5]. While ``communicate`` can be used to alleviate some of
|
and documented [4] [5]. While communicate can be used to alleviate some of
|
||||||
the buffering issues, it will still cause the parent process to block while
|
the buffering issues, it will still cause the parent process to block while
|
||||||
attempting to read data when none is available to be read from the child
|
attempting to read data when none is available to be read from the child
|
||||||
process.
|
process.
|
||||||
|
@ -34,14 +34,13 @@ Motivation:
|
||||||
Rationale:
|
Rationale:
|
||||||
|
|
||||||
There is a documented need for asynchronous, non-blocking functionality in
|
There is a documented need for asynchronous, non-blocking functionality in
|
||||||
``subprocess.Popen`` [6] [7] [2] [3]. Inclusion of the code would improve the
|
subprocess.Popen [6] [7] [2] [3]. Inclusion of the code would improve the
|
||||||
utility of the Python standard library that can be used on Unix based and
|
utility of the Python standard library that can be used on Unix based and
|
||||||
Windows builds of Python. Practically every I/O object in Python has a
|
Windows builds of Python. Practically every I/O object in Python has a
|
||||||
file-like wrapper of some sort. Sockets already act as such and for
|
file-like wrapper of some sort. Sockets already act as such and for
|
||||||
strings there is ``StringIO``. Popen can be made to act like a file by simply
|
strings there is StringIO. Popen can be made to act like a file by simply
|
||||||
using the methods attached the the ``subprocess.Popen.stderr``,
|
using the methods attached the the subprocess.Popen.stderr, stdout and
|
||||||
``stdout`` and
|
stdin file-like objects. But when using the read and write methods of
|
||||||
``stdin`` file-like objects. But when using the read and write methods of
|
|
||||||
those options, you do not have the benefit of asynchronous I/O. In the
|
those options, you do not have the benefit of asynchronous I/O. In the
|
||||||
proposed solution the wrapper wraps the asynchronous methods to mimic a
|
proposed solution the wrapper wraps the asynchronous methods to mimic a
|
||||||
file object.
|
file object.
|
||||||
|
@ -53,43 +52,36 @@ Reference Implementation:
|
||||||
the problems I have come across in the development process [10].
|
the problems I have come across in the development process [10].
|
||||||
|
|
||||||
I have been working on implementing non-blocking asynchronous I/O in the
|
I have been working on implementing non-blocking asynchronous I/O in the
|
||||||
``subprocess.Popen`` module as well as a wrapper class for
|
subprocess.Popen module as well as a wrapper class for subprocess.Popen
|
||||||
``subprocess.Popen``
|
|
||||||
that makes it so that an executed process can take the place of a file by
|
that makes it so that an executed process can take the place of a file by
|
||||||
duplicating all of the methods and attributes that file objects have.
|
duplicating all of the methods and attributes that file objects have.
|
||||||
|
|
||||||
There are two base functions that have been added to the
|
There are two base functions that have been added to the subprocess.Popen
|
||||||
``subprocess.Popen``
|
class: Popen.send and Popen._recv, each with two separate implementations,
|
||||||
class: ``Popen.send`` and ``Popen._recv``, each with two separate implementations,
|
|
||||||
one for Windows and one for Unix based systems. The Windows
|
one for Windows and one for Unix based systems. The Windows
|
||||||
implementation uses ``ctypes`` to access the functions needed to control pipes
|
implementation uses ctypes to access the functions needed to control pipes
|
||||||
in the kernel 32 DLL in an asynchronous manner. On Unix based systems,
|
in the kernel 32 DLL in an asynchronous manner. On Unix based systems,
|
||||||
the Python interface for file control serves the same purpose. The
|
the Python interface for file control serves the same purpose. The
|
||||||
different implementations of ``Popen.send`` and ``Popen._recv`` have identical
|
different implementations of Popen.send and Popen._recv have identical
|
||||||
arguments to make code that uses these functions work across multiple
|
arguments to make code that uses these functions work across multiple
|
||||||
platforms.
|
platforms.
|
||||||
|
|
||||||
When calling the ``Popen._recv`` function, it requires the pipe name be
|
When calling the Popen._recv function, it requires the pipe name be
|
||||||
passed as an argument so there exists the ``Popen.recv`` function that passes
|
passed as an argument so there exists the Popen.recv function that passes
|
||||||
selects ``stdout`` as the pipe for ``Popen._recv`` by default.
|
selects stdout as the pipe for Popen._recv by default. Popen.recv_err
|
||||||
``Popen.recv_err``
|
selects stderr as the pipe by default. Popen.recv and Popen.recv_err
|
||||||
selects ``stderr`` as the pipe by default. ``Popen.recv`` and
|
are much easier to read and understand than Popen._recv('stdout' ...) and
|
||||||
``Popen.recv_err``
|
Popen._recv('stderr' ...) respectively.
|
||||||
are much easier to read and understand than
|
|
||||||
``Popen._recv('stdout' ...)`` and
|
|
||||||
``Popen._recv('stderr' ...)`` respectively.
|
|
||||||
|
|
||||||
Since the ``Popen._recv`` function does not wait on data to be produced
|
Since the Popen._recv function does not wait on data to be produced
|
||||||
before returning a value, it may return empty bytes.
|
before returning a value, it may return empty bytes. Popen.asyncread
|
||||||
``Popen.asyncread``
|
|
||||||
handles this issue by returning all data read over a given time
|
handles this issue by returning all data read over a given time
|
||||||
interval.
|
interval.
|
||||||
|
|
||||||
The ``ProcessIOWrapper`` class uses the ``asyncread`` and
|
The ProcessIOWrapper class uses the asyncread and asyncwrite functions to
|
||||||
``asyncwrite`` functions to
|
|
||||||
allow a process to act like a file so that there are no blocking issues
|
allow a process to act like a file so that there are no blocking issues
|
||||||
that can arise from using the ``stdout`` and ``stdin`` file objects produced from
|
that can arise from using the stdout and stdin file objects produced from
|
||||||
a ``subprocess.Popen`` call.
|
a subprocess.Popen call.
|
||||||
|
|
||||||
|
|
||||||
References:
|
References:
|
||||||
|
|
Loading…
Reference in New Issue