Commits

Victor Stinner committed 20a5a08

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

Comments (0)

Files changed (4)

Doc/library/platform.rst

    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
 ---------------
                               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=''):
 

Lib/test/test_platform.py

             ):
             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(
 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.