Issue #11377: Deprecate platform.popen() and reimplement it with os.popen().

This commit is contained in:
Victor Stinner 2011-03-03 12:54:07 +00:00
parent 7b3b20ad29
commit 1dfd380306
4 changed files with 26 additions and 82 deletions

View File

@ -214,6 +214,10 @@ Win95/98 specific
preferring :func:`win32pipe.popen`. On Windows NT, :func:`win32pipe.popen`
should work; on Windows 9x it hangs due to bugs in the MS C library.
.. deprecated:: 3.3
This function is obsolete. Use the :mod:`subprocess` module. Check
especially the :ref:`subprocess-replacements` section.
Mac OS Platform
---------------

View File

@ -357,92 +357,11 @@ def dist(distname='',version='',id='',
supported_dists=supported_dists,
full_distribution_name=0)
class _popen:
""" Fairly portable (alternative) popen implementation.
This is mostly needed in case os.popen() is not available, or
doesn't work as advertised, e.g. in Win9X GUI programs like
PythonWin or IDLE.
Writing to the pipe is currently not supported.
"""
tmpfile = ''
pipe = None
bufsize = None
mode = 'r'
def __init__(self,cmd,mode='r',bufsize=None):
if mode != 'r':
raise ValueError('popen()-emulation only supports read mode')
import tempfile
self.tmpfile = tmpfile = tempfile.mktemp()
os.system(cmd + ' > %s' % tmpfile)
self.pipe = open(tmpfile,'rb')
self.bufsize = bufsize
self.mode = mode
def read(self):
return self.pipe.read()
def readlines(self):
if self.bufsize is not None:
return self.pipe.readlines()
def close(self,
remove=os.unlink,error=os.error):
if self.pipe:
rc = self.pipe.close()
else:
rc = 255
if self.tmpfile:
try:
remove(self.tmpfile)
except error:
pass
return rc
# Alias
__del__ = close
def popen(cmd, mode='r', bufsize=None):
""" Portable popen() interface.
"""
# Find a working popen implementation preferring win32pipe.popen
# over os.popen over _popen
popen = None
if os.environ.get('OS','') == 'Windows_NT':
# On NT win32pipe should work; on Win9x it hangs due to bugs
# in the MS C lib (see MS KnowledgeBase article Q150956)
try:
import win32pipe
except ImportError:
pass
else:
popen = win32pipe.popen
if popen is None:
if hasattr(os,'popen'):
popen = os.popen
# Check whether it works... it doesn't in GUI programs
# on Windows platforms
if sys.platform == 'win32': # XXX Others too ?
try:
popen('')
except os.error:
popen = _popen
else:
popen = _popen
if bufsize is None:
return popen(cmd,mode)
else:
return popen(cmd,mode,bufsize)
return os.popen(cmd, mode, bufsize)
def _norm_version(version, build=''):

View File

@ -243,6 +243,25 @@ class PlatformTest(unittest.TestCase):
):
self.assertEqual(platform._parse_release_file(input), output)
def test_popen(self):
command = "'{}' -c 'print(\"Hello\")'".format(sys.executable)
with platform.popen(command) as stdout:
hello = stdout.read().strip()
stdout.close()
self.assertEqual(hello, "Hello")
command = "'{}' -c 'import sys; data=sys.stdin.read(); exit(len(data))'".format(sys.executable)
data = 'plop'
with platform.popen(command, 'w') as stdin:
stdout = stdin.write(data)
ret = stdin.close()
self.assertIsNotNone(ret)
if os.name == 'nt':
returncode = ret
else:
returncode = ret >> 8
self.assertEqual(returncode, len(data))
def test_main():
support.run_unittest(

View File

@ -52,6 +52,8 @@ Core and Builtins
Library
-------
- Issue #11377: Deprecate platform.popen() and reimplement it with os.popen().
- Issue #8513: On UNIX, subprocess supports bytes command string.
- Issue #10866: Add socket.sethostname(). Initial patch by Ross Lagerwall.