Skip to content

Commit f560485

Browse files
committed
Get rid of the close_fds DeprecationWarning. Changes the default on a per
platform basis. It remains False on Windows and changes to True on all other platforms (POSIX). Based on python-dev discussion and http://bugs.python.org/issue7213.
1 parent 8d28a92 commit f560485

File tree

3 files changed

+26
-46
lines changed

3 files changed

+26
-46
lines changed

Doc/library/subprocess.rst

+6-8
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Using the subprocess Module
2828
This module defines one class called :class:`Popen`:
2929

3030

31-
.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False)
31+
.. class:: Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0, restore_signals=True, start_new_session=False)
3232

3333
Arguments are:
3434

@@ -153,17 +153,14 @@ This module defines one class called :class:`Popen`:
153153

154154
If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and
155155
:const:`2` will be closed before the child process is executed. (Unix only).
156-
The recommended value for this argument is True.
156+
The default varies by platform: :const:`False` on Windows and :const:`True`
157+
on POSIX and other platforms.
157158
On Windows, if *close_fds* is true then no handles will be inherited by the
158159
child process. Note that on Windows, you cannot set *close_fds* to true and
159160
also redirect the standard handles by setting *stdin*, *stdout* or *stderr*.
160161

161162
.. versionchanged:: 3.2
162-
Callers should always specify a *close_fds* to avoid a DeprecationWarning.
163-
The default behavior of this argument will be changing in Python 3.3.
164-
165-
If *shell* is :const:`True`, the specified command will be executed through the
166-
shell.
163+
The default was changed to True on non Windows platforms.
167164

168165
If *cwd* is not ``None``, the child's current directory will be changed to *cwd*
169166
before it is executed. Note that this directory is not considered when
@@ -654,4 +651,5 @@ Replacing functions from the :mod:`popen2` module
654651
* ``stdin=PIPE`` and ``stdout=PIPE`` must be specified.
655652

656653
* popen2 closes all file descriptors by default, but you have to specify
657-
``close_fds=True`` with :class:`Popen`.
654+
``close_fds=True`` with :class:`Popen` to guarantee this behavior on
655+
all platforms or past Python versions.

Lib/subprocess.py

+19-20
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
2828
class Popen(args, bufsize=0, executable=None,
2929
stdin=None, stdout=None, stderr=None,
30-
preexec_fn=None, close_fds=False, shell=False,
30+
preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False,
3131
cwd=None, env=None, universal_newlines=False,
3232
startupinfo=None, creationflags=0,
3333
restore_signals=True, start_new_session=False):
@@ -39,12 +39,12 @@ class Popen(args, bufsize=0, executable=None,
3939
program to execute is normally the first item in the args sequence or
4040
string, but can be explicitly set by using the executable argument.
4141
42-
On UNIX, with shell=False (default): In this case, the Popen class
42+
On POSIX, with shell=False (default): In this case, the Popen class
4343
uses os.execvp() to execute the child program. args should normally
4444
be a sequence. A string will be treated as a sequence with the string
4545
as the only item (the program to execute).
4646
47-
On UNIX, with shell=True: If args is a string, it specifies the
47+
On POSIX, with shell=True: If args is a string, it specifies the
4848
command string to execute through the shell. If args is a sequence,
4949
the first item specifies the command string, and any additional items
5050
will be treated as additional shell arguments.
@@ -73,35 +73,37 @@ class Popen(args, bufsize=0, executable=None,
7373
stderr data from the applications should be captured into the same
7474
file handle as for stdout.
7575
76-
On UNIX, if preexec_fn is set to a callable object, this object will be
76+
On POSIX, if preexec_fn is set to a callable object, this object will be
7777
called in the child process just before the child is executed. The use
7878
of preexec_fn is not thread safe, using it in the presence of threads
7979
could lead to a deadlock in the child process before the new executable
8080
is executed.
8181
8282
If close_fds is true, all file descriptors except 0, 1 and 2 will be
83-
closed before the child process is executed.
83+
closed before the child process is executed. The default for close_fds
84+
varies by platform: False on Windows and True on all other platforms
85+
such as POSIX.
8486
8587
if shell is true, the specified command will be executed through the
8688
shell.
8789
8890
If cwd is not None, the current directory will be changed to cwd
8991
before the child is executed.
9092
91-
On UNIX, if restore_signals is True all signals that Python sets to
93+
On POSIX, if restore_signals is True all signals that Python sets to
9294
SIG_IGN are restored to SIG_DFL in the child process before the exec.
9395
Currently this includes the SIGPIPE, SIGXFZ and SIGXFSZ signals. This
9496
parameter does nothing on Windows.
9597
96-
On UNIX, if start_new_session is True, the setsid() system call will be made
98+
On POSIX, if start_new_session is True, the setsid() system call will be made
9799
in the child process prior to executing the command.
98100
99101
If env is not None, it defines the environment variables for the new
100102
process.
101103
102104
If universal_newlines is true, the file objects stdout and stderr are
103105
opened as a text files, but lines may be terminated by any of '\n',
104-
the Unix end-of-line convention, '\r', the Macintosh convention or
106+
the Unix end-of-line convention, '\r', the old Macintosh convention or
105107
'\r\n', the Windows convention. All of these external representations
106108
are seen as '\n' by the Python program. Note: This feature is only
107109
available if Python is built with universal newline support (the
@@ -242,7 +244,7 @@ class Popen(args, bufsize=0, executable=None,
242244
returncode
243245
The child return code. A None value indicates that the process
244246
hasn't terminated yet. A negative value -N indicates that the
245-
child was terminated by signal N (UNIX only).
247+
child was terminated by signal N (POSIX only).
246248
247249
248250
Replacing older functions with the subprocess module
@@ -562,7 +564,7 @@ def list2cmdline(seq):
562564

563565
# Various tools for executing commands and looking at their output and status.
564566
#
565-
# NB This only works (and is only relevant) for UNIX.
567+
# NB This only works (and is only relevant) for POSIX.
566568

567569
def getstatusoutput(cmd):
568570
"""Return (status, output) of executing cmd in a shell.
@@ -602,10 +604,16 @@ def getoutput(cmd):
602604
return getstatusoutput(cmd)[1]
603605

604606

607+
if mswindows:
608+
_PLATFORM_DEFAULT = False
609+
else:
610+
_PLATFORM_DEFAULT = True
611+
612+
605613
class Popen(object):
606614
def __init__(self, args, bufsize=0, executable=None,
607615
stdin=None, stdout=None, stderr=None,
608-
preexec_fn=None, close_fds=None, shell=False,
616+
preexec_fn=None, close_fds=_PLATFORM_DEFAULT, shell=False,
609617
cwd=None, env=None, universal_newlines=False,
610618
startupinfo=None, creationflags=0,
611619
restore_signals=True, start_new_session=False,
@@ -619,15 +627,6 @@ def __init__(self, args, bufsize=0, executable=None,
619627
if not isinstance(bufsize, int):
620628
raise TypeError("bufsize must be an integer")
621629

622-
if close_fds is None:
623-
# Notification for http://bugs.python.org/issue7213 & issue2320
624-
warnings.warn(
625-
'The close_fds parameter was not specified. Its default'
626-
' behavior will change in a future Python version. '
627-
' Most users should set it to True. Please'
628-
' update your code explicitly set close_fds.',
629-
DeprecationWarning)
630-
631630
if mswindows:
632631
if preexec_fn is not None:
633632
raise ValueError("preexec_fn is not supported on Windows "

Lib/test/test_subprocess.py

+1-18
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,6 @@ def assertStderrEqual(self, stderr, expected, msg=None):
5858
self.assertEqual(actual, expected, msg)
5959

6060

61-
class DeprecationWarningTests(BaseTestCase):
62-
def testCloseFdsWarning(self):
63-
quick_process = [sys.executable, "-c", "import sys; sys.exit(0)"]
64-
with warnings.catch_warnings(record=True) as warnlist:
65-
warnings.simplefilter("always")
66-
subprocess.call(quick_process, close_fds=True)
67-
self.assertEqual([], warnlist)
68-
subprocess.call(quick_process, close_fds=False)
69-
self.assertEqual([], warnlist)
70-
with self.assertWarns(DeprecationWarning) as wm:
71-
subprocess.Popen(quick_process).wait()
72-
self.assertEqual(1, len(wm.warnings))
73-
self.assertIn('close_fds parameter was not specified',
74-
str(wm.warnings[0]))
75-
76-
7761
class ProcessTestCase(BaseTestCase):
7862

7963
def test_call_seq(self):
@@ -1250,8 +1234,7 @@ def test_main():
12501234
ProcessTestCaseNoPoll,
12511235
HelperFunctionTests,
12521236
CommandsWithSpaces,
1253-
ContextManagerTests,
1254-
DeprecationWarningTests)
1237+
ContextManagerTests)
12551238

12561239
support.run_unittest(*unit_tests)
12571240
support.reap_children()

0 commit comments

Comments
 (0)