diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index 99a46fad060..0e65eb10c1b 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -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 --------------- diff --git a/Lib/platform.py b/Lib/platform.py index b9bc3036574..ab0f92f8be3 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -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=''): diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 7dd7eef2fed..1ab0d9caa52 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -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( diff --git a/Misc/NEWS b/Misc/NEWS index 128efa23e3c..ff6ee30d874 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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.