From 42dd86b8e2773c342ca7fa0ffcc9d1cbb8589bd3 Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Fri, 11 May 2007 06:57:33 +0000 Subject: [PATCH] Deprecate os.popen* and popen2 module in favor of the subprocess module. --- Lib/os.py | 38 +++++++++++++++++++++++++++++--------- Lib/plat-mac/pimp.py | 9 +++++---- Lib/popen2.py | 3 +++ Lib/test/test___all__.py | 2 ++ Lib/test/test_bz2.py | 18 ++++++++++-------- Lib/test/test_cmd_line.py | 13 +++++++------ Lib/test/test_popen2.py | 6 ++++++ Misc/NEWS | 2 ++ Tools/msi/msilib.py | 8 +++++--- 9 files changed, 69 insertions(+), 30 deletions(-) diff --git a/Lib/os.py b/Lib/os.py index 991716ed1fa..206aa371b34 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -666,9 +666,15 @@ if _exists("fork"): is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout) are returned.""" - import popen2 - stdout, stdin = popen2.popen2(cmd, bufsize) - return stdin, stdout + import warnings + msg = "os.popen2 is deprecated. Use the subprocess module." + warnings.warn(msg, DeprecationWarning, stacklevel=2) + + import subprocess + PIPE = subprocess.PIPE + p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, + stdin=PIPE, stdout=PIPE, close_fds=True) + return p.stdin, p.stdout __all__.append("popen2") if not _exists("popen3"): @@ -679,9 +685,16 @@ if _exists("fork"): is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout, child_stderr) are returned.""" - import popen2 - stdout, stdin, stderr = popen2.popen3(cmd, bufsize) - return stdin, stdout, stderr + import warnings + msg = "os.popen3 is deprecated. Use the subprocess module." + warnings.warn(msg, DeprecationWarning, stacklevel=2) + + import subprocess + PIPE = subprocess.PIPE + p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, + stdin=PIPE, stdout=PIPE, stderr=PIPE, + close_fds=True) + return p.stdin, p.stdout, p.stderr __all__.append("popen3") if not _exists("popen4"): @@ -692,9 +705,16 @@ if _exists("fork"): is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout_stderr) are returned.""" - import popen2 - stdout, stdin = popen2.popen4(cmd, bufsize) - return stdin, stdout + import warnings + msg = "os.popen4 is deprecated. Use the subprocess module." + warnings.warn(msg, DeprecationWarning, stacklevel=2) + + import subprocess + PIPE = subprocess.PIPE + p = subprocess.Popen(cmd, shell=True, bufsize=bufsize, + stdin=PIPE, stdout=PIPE, + stderr=subprocess.STDOUT, close_fds=True) + return p.stdin, p.stdout __all__.append("popen4") import copy_reg as _copy_reg diff --git a/Lib/plat-mac/pimp.py b/Lib/plat-mac/pimp.py index 456427c1cd2..e58f36d4ad9 100644 --- a/Lib/plat-mac/pimp.py +++ b/Lib/plat-mac/pimp.py @@ -14,7 +14,7 @@ intention is that the end user will use this through a GUI. """ import sys import os -import popen2 +import subprocess import urllib import urllib2 import urlparse @@ -101,10 +101,11 @@ def _cmd(output, dir, *cmditems): output.write("+ %s\n" % cmd) if NO_EXECUTE: return 0 - child = popen2.Popen4(cmd) - child.tochild.close() + child = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + child.stdin.close() while 1: - line = child.fromchild.readline() + line = child.stdout.readline() if not line: break if output: diff --git a/Lib/popen2.py b/Lib/popen2.py index ab30463e24a..145b3406cf5 100644 --- a/Lib/popen2.py +++ b/Lib/popen2.py @@ -8,6 +8,9 @@ and popen3(cmd) which return two or three pipes to the spawned command. import os import sys +import warnings +warnings.warn("The popen2 module is deprecated. Use the subprocess module.", + DeprecationWarning, stacklevel=2) __all__ = ["popen2", "popen3", "popen4"] diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 5e7d34e1d64..2b9f1dedea4 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -9,6 +9,8 @@ warnings.filterwarnings("ignore", "") warnings.filterwarnings("ignore", "the sets module is deprecated", DeprecationWarning, "") +warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*", + DeprecationWarning) class AllTest(unittest.TestCase): diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index 709850d2298..b8b3c031027 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -5,7 +5,7 @@ from test.test_support import TESTFN import unittest from cStringIO import StringIO import os -import popen2 +import subprocess import sys import bz2 @@ -21,18 +21,20 @@ class BaseTest(unittest.TestCase): if has_cmdline_bunzip2: def decompress(self, data): - pop = popen2.Popen3("bunzip2", capturestderr=1) - pop.tochild.write(data) - pop.tochild.close() - ret = pop.fromchild.read() - pop.fromchild.close() + pop = subprocess.Popen("bunzip2", shell=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT) + pop.stdin.write(data) + pop.stdin.close() + ret = pop.stdout.read() + pop.stdout.close() if pop.wait() != 0: ret = bz2.decompress(data) return ret else: - # popen2.Popen3 doesn't exist on Windows, and even if it did, bunzip2 - # isn't available to run. + # bunzip2 isn't available to run on Windows. def decompress(self, data): return bz2.decompress(data) diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index cacae7a697a..d3f07c7f134 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -1,18 +1,19 @@ import test.test_support, unittest import sys -import popen2 import subprocess class CmdLineTest(unittest.TestCase): def start_python(self, cmd_line): - outfp, infp = popen2.popen4('"%s" %s' % (sys.executable, cmd_line)) - infp.close() - data = outfp.read() - outfp.close() + cmd = '"%s" %s' % (sys.executable, cmd_line) + p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + p.stdin.close() + data = p.stdout.read() + p.stdout.close() # try to cleanup the child so we don't appear to leak when running # with regrtest -R. This should be a no-op on Windows. - popen2._cleanup() + subprocess._cleanup() return data def exit_code(self, *args): diff --git a/Lib/test/test_popen2.py b/Lib/test/test_popen2.py index 31f22d6adf1..023871f598b 100644 --- a/Lib/test/test_popen2.py +++ b/Lib/test/test_popen2.py @@ -1,6 +1,12 @@ #! /usr/bin/env python """Test script for popen2.py""" +import warnings +warnings.filterwarnings("ignore", ".*popen2 module is deprecated.*", + DeprecationWarning) +warnings.filterwarnings("ignore", "os\.popen. is deprecated.*", + DeprecationWarning) + import os import sys import unittest diff --git a/Misc/NEWS b/Misc/NEWS index 80bdc0a11f1..32531f6c40e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -207,6 +207,8 @@ Core and builtins Library ------- +- The popen2 module and os.popen* are deprecated. Use the subprocess module. + - Added an optional credentials argument to SMTPHandler, for use with SMTP servers which require authentication. diff --git a/Tools/msi/msilib.py b/Tools/msi/msilib.py index d7b86ccb0dc..548b640bc31 100644 --- a/Tools/msi/msilib.py +++ b/Tools/msi/msilib.py @@ -5,7 +5,7 @@ import win32com.client.gencache import win32com.client import pythoncom, pywintypes from win32com.client import constants -import re, string, os, sets, glob, popen2, sys, _winreg, struct +import re, string, os, sets, glob, subprocess, sys, _winreg, struct try: basestring @@ -388,8 +388,10 @@ class CAB: else: print "WARNING: cabarc.exe not found in registry" cabarc = "cabarc.exe" - f = popen2.popen4(r'"%s" -m lzx:21 n %s.cab @%s.txt' % (cabarc, self.name, self.name))[0] - for line in f: + cmd = r'"%s" -m lzx:21 n %s.cab @%s.txt' % (cabarc, self.name, self.name) + p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT)[0] + for line in (p.stdout, p.stdin): if line.startswith(" -- adding "): sys.stdout.write(".") else: