PEP 446: update after Guido's review
This commit is contained in:
parent
091eb3e838
commit
fbeac3a6e1
41
pep-0446.txt
41
pep-0446.txt
|
@ -24,6 +24,10 @@ fixes also a race condition in multi-threaded applications on operating
|
||||||
systems supporting atomic flags to create non-inheritable file
|
systems supporting atomic flags to create non-inheritable file
|
||||||
descriptors.
|
descriptors.
|
||||||
|
|
||||||
|
We are aware of the code breakage this is likely to cause, and doing it
|
||||||
|
anyway for the good of mankind. (Details in the section "Backward
|
||||||
|
Compatibility" below.)
|
||||||
|
|
||||||
|
|
||||||
Rationale
|
Rationale
|
||||||
=========
|
=========
|
||||||
|
@ -79,6 +83,11 @@ the *dwFlags* field of the ``STARTUPINFO`` structure and the
|
||||||
``TRUE``. So when at least one standard stream is replaced, all
|
``TRUE``. So when at least one standard stream is replaced, all
|
||||||
inheritable handles are inherited by the child process.
|
inheritable handles are inherited by the child process.
|
||||||
|
|
||||||
|
The default value of the *close_fds* parameter of ``subprocess`` process
|
||||||
|
is ``True`` (``bInheritHandles=FALSE``) if *stdin*, *stdout* and
|
||||||
|
*stderr* parameters are ``None``, ``False`` (``bInheritHandles=TRUE``)
|
||||||
|
otherwise.
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
* `Handle Inheritance
|
* `Handle Inheritance
|
||||||
|
@ -430,12 +439,6 @@ MAXFD is the maximum number of file descriptors, even if there are only
|
||||||
few open file descriptors. This maximum can be read using:
|
few open file descriptors. This maximum can be read using:
|
||||||
``os.sysconf("SC_OPEN_MAX")``.
|
``os.sysconf("SC_OPEN_MAX")``.
|
||||||
|
|
||||||
There is no portable nor reliable function to close all open file
|
|
||||||
descriptors between ``fork()`` and ``execv()``. Another thread may
|
|
||||||
create an inheritable file descriptors while we are closing existing
|
|
||||||
file descriptors. Holding the CPython GIL reduces the risk of the race
|
|
||||||
condition.
|
|
||||||
|
|
||||||
The operation can be slow if MAXFD is large. For example, on a FreeBSD
|
The operation can be slow if MAXFD is large. For example, on a FreeBSD
|
||||||
buildbot with ``MAXFD=655,000``, the operation took 300 ms: see
|
buildbot with ``MAXFD=655,000``, the operation took 300 ms: see
|
||||||
`issue #11284: slow close file descriptors
|
`issue #11284: slow close file descriptors
|
||||||
|
@ -445,10 +448,6 @@ On Linux, Python 3.3 gets the list of all open file descriptors from
|
||||||
``/proc/<PID>/fd/``, and so performances depends on the number of open
|
``/proc/<PID>/fd/``, and so performances depends on the number of open
|
||||||
file descriptors, not on MAXFD.
|
file descriptors, not on MAXFD.
|
||||||
|
|
||||||
FreeBSD, OpenBSD and Solaris provide a ``closefrom()`` function. It
|
|
||||||
cannot be used by the ``subprocess`` module when the *pass_fds*
|
|
||||||
parameter is a non-empty list of file descriptors.
|
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
* `Python issue #1663329 <http://bugs.python.org/issue1663329>`_:
|
* `Python issue #1663329 <http://bugs.python.org/issue1663329>`_:
|
||||||
|
@ -485,6 +484,8 @@ descriptors non-inheritable by default:
|
||||||
* ``socket.socket.fromfd()``
|
* ``socket.socket.fromfd()``
|
||||||
* ``socket.socketpair()``
|
* ``socket.socketpair()``
|
||||||
|
|
||||||
|
``os.dup2()`` still creates inheritable by default, see below.
|
||||||
|
|
||||||
When available, atomic flags are used to make file descriptors
|
When available, atomic flags are used to make file descriptors
|
||||||
non-inheritable. The atomicity is not guaranteed because a fallback is
|
non-inheritable. The atomicity is not guaranteed because a fallback is
|
||||||
required when atomic flags are not available.
|
required when atomic flags are not available.
|
||||||
|
@ -518,14 +519,20 @@ New methods:
|
||||||
Other Changes
|
Other Changes
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
* On UNIX, subprocess makes file descriptors of the *pass_fds* parameter
|
On UNIX, subprocess makes file descriptors of the *pass_fds* parameter
|
||||||
inheritable. The file descriptor is made inheritable in the child
|
inheritable. The file descriptor is made inheritable in the child
|
||||||
process after the ``fork()`` and before ``execv()``, so the inheritable
|
process after the ``fork()`` and before ``execv()``, so the inheritable
|
||||||
flag of file descriptors is unchanged in the parent process.
|
flag of file descriptors is unchanged in the parent process.
|
||||||
|
|
||||||
* ``os.dup2()`` has a new optional *inheritable* parameter:
|
``os.dup2()`` has a new optional *inheritable* parameter: ``os.dup2(fd,
|
||||||
``os.dup2(fd, fd2, inheritable=True)``. *fd2* is created inheritable
|
fd2, inheritable=True)``. *fd2* is created inheritable by default, but
|
||||||
by default, but non-inheritable if *inheritable* is ``False``.
|
non-inheritable if *inheritable* is ``False``.
|
||||||
|
|
||||||
|
``os.dup2()`` behaves differently than ``os.dup()`` because the most
|
||||||
|
common use case of ``os.dup2()`` is to replace the file descriptors of
|
||||||
|
the standard streams: ``stdin`` (``0``), ``stdout`` (``1``) and
|
||||||
|
``stdout`` (``2``). Standard streams are expected to be inherited by
|
||||||
|
child processes.
|
||||||
|
|
||||||
Since Python should only create non-inheritable file descriptors, it is
|
Since Python should only create non-inheritable file descriptors, it is
|
||||||
safe to use subprocess with the *close_fds* parameter set to ``False``.
|
safe to use subprocess with the *close_fds* parameter set to ``False``.
|
||||||
|
|
Loading…
Reference in New Issue