[Python-checkins] bpo-31904: Disable os.popen and popen test cases on VxWorks (GH-21687)

vstinner webhook-mailer at python.org
Tue Dec 15 16:20:27 EST 2020


https://github.com/python/cpython/commit/e1e3c2dac3da8a179f57bd3e3309ab65385bcc8a
commit: e1e3c2dac3da8a179f57bd3e3309ab65385bcc8a
branch: master
author: pxinwr <peixing.xin at windriver.com>
committer: vstinner <vstinner at python.org>
date: 2020-12-15T22:20:07+01:00
summary:

bpo-31904: Disable os.popen and popen test cases on VxWorks (GH-21687)

files:
A Misc/NEWS.d/next/Tests/2020-07-30-18-06-15.bpo-31904.y3d8dk.rst
M Doc/library/os.rst
M Lib/os.py
M Lib/test/test_os.py
M Lib/test/test_popen.py
M Lib/test/test_posix.py
M Lib/test/test_select.py

diff --git a/Doc/library/os.rst b/Doc/library/os.rst
index a4c5fbb481521..b309988688959 100644
--- a/Doc/library/os.rst
+++ b/Doc/library/os.rst
@@ -32,7 +32,7 @@ Notes on the availability of these functions:
   objects, and result in an object of the same type, if a path or file name is
   returned.
 
-* On VxWorks, os.fork, os.execv and os.spawn*p* are not supported.
+* On VxWorks, os.popen, os.fork, os.execv and os.spawn*p* are not supported.
 
 .. note::
 
diff --git a/Lib/os.py b/Lib/os.py
index b794159f86c33..05e9c32c5a711 100644
--- a/Lib/os.py
+++ b/Lib/os.py
@@ -36,7 +36,7 @@
 __all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
            "defpath", "name", "path", "devnull", "SEEK_SET", "SEEK_CUR",
            "SEEK_END", "fsencode", "fsdecode", "get_exec_path", "fdopen",
-           "popen", "extsep"]
+           "extsep"]
 
 def _exists(name):
     return name in globals()
@@ -969,51 +969,55 @@ def spawnlpe(mode, file, *args):
 
     __all__.extend(["spawnlp", "spawnlpe"])
 
-
-# Supply os.popen()
-def popen(cmd, mode="r", buffering=-1):
-    if not isinstance(cmd, str):
-        raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
-    if mode not in ("r", "w"):
-        raise ValueError("invalid mode %r" % mode)
-    if buffering == 0 or buffering is None:
-        raise ValueError("popen() does not support unbuffered streams")
-    import subprocess, io
-    if mode == "r":
-        proc = subprocess.Popen(cmd,
-                                shell=True,
-                                stdout=subprocess.PIPE,
-                                bufsize=buffering)
-        return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
-    else:
-        proc = subprocess.Popen(cmd,
-                                shell=True,
-                                stdin=subprocess.PIPE,
-                                bufsize=buffering)
-        return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
-
-# Helper for popen() -- a proxy for a file whose close waits for the process
-class _wrap_close:
-    def __init__(self, stream, proc):
-        self._stream = stream
-        self._proc = proc
-    def close(self):
-        self._stream.close()
-        returncode = self._proc.wait()
-        if returncode == 0:
-            return None
-        if name == 'nt':
-            return returncode
+# VxWorks has no user space shell provided. As a result, running
+# command in a shell can't be supported.
+if sys.platform != 'vxworks':
+    # Supply os.popen()
+    def popen(cmd, mode="r", buffering=-1):
+        if not isinstance(cmd, str):
+            raise TypeError("invalid cmd type (%s, expected string)" % type(cmd))
+        if mode not in ("r", "w"):
+            raise ValueError("invalid mode %r" % mode)
+        if buffering == 0 or buffering is None:
+            raise ValueError("popen() does not support unbuffered streams")
+        import subprocess, io
+        if mode == "r":
+            proc = subprocess.Popen(cmd,
+                                    shell=True,
+                                    stdout=subprocess.PIPE,
+                                    bufsize=buffering)
+            return _wrap_close(io.TextIOWrapper(proc.stdout), proc)
         else:
-            return returncode << 8  # Shift left to match old behavior
-    def __enter__(self):
-        return self
-    def __exit__(self, *args):
-        self.close()
-    def __getattr__(self, name):
-        return getattr(self._stream, name)
-    def __iter__(self):
-        return iter(self._stream)
+            proc = subprocess.Popen(cmd,
+                                    shell=True,
+                                    stdin=subprocess.PIPE,
+                                    bufsize=buffering)
+            return _wrap_close(io.TextIOWrapper(proc.stdin), proc)
+
+    # Helper for popen() -- a proxy for a file whose close waits for the process
+    class _wrap_close:
+        def __init__(self, stream, proc):
+            self._stream = stream
+            self._proc = proc
+        def close(self):
+            self._stream.close()
+            returncode = self._proc.wait()
+            if returncode == 0:
+                return None
+            if name == 'nt':
+                return returncode
+            else:
+                return returncode << 8  # Shift left to match old behavior
+        def __enter__(self):
+            return self
+        def __exit__(self, *args):
+            self.close()
+        def __getattr__(self, name):
+            return getattr(self._stream, name)
+        def __iter__(self):
+            return iter(self._stream)
+
+    __all__.append("popen")
 
 # Supply os.fdopen()
 def fdopen(fd, *args, **kwargs):
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index dbb2975c0eee4..08d7ab8a30ba7 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -991,6 +991,7 @@ def _empty_mapping(self):
     # Bug 1110478
     @unittest.skipUnless(unix_shell and os.path.exists(unix_shell),
                          'requires a shell')
+    @unittest.skipUnless(hasattr(os, 'popen'), "needs os.popen()")
     def test_update2(self):
         os.environ.clear()
         os.environ.update(HELLO="World")
@@ -1000,6 +1001,7 @@ def test_update2(self):
 
     @unittest.skipUnless(unix_shell and os.path.exists(unix_shell),
                          'requires a shell')
+    @unittest.skipUnless(hasattr(os, 'popen'), "needs os.popen()")
     def test_os_popen_iter(self):
         with os.popen("%s -c 'echo \"line1\nline2\nline3\"'"
                       % unix_shell) as popen:
diff --git a/Lib/test/test_popen.py b/Lib/test/test_popen.py
index ab1bc776552ca..cac2f6177f325 100644
--- a/Lib/test/test_popen.py
+++ b/Lib/test/test_popen.py
@@ -7,6 +7,9 @@
 from test import support
 import os, sys
 
+if not hasattr(os, 'popen'):
+    raise unittest.SkipTest("need os.popen()")
+
 # Test that command-lines get down as we expect.
 # To do this we execute:
 #    python -c "import sys;print(sys.argv)" {rest_of_commandline}
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 185b293b07046..cd18a4972fa2c 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -1045,6 +1045,7 @@ def test_getgrouplist(self):
 
 
     @unittest.skipUnless(hasattr(os, 'getegid'), "test needs os.getegid()")
+    @unittest.skipUnless(hasattr(os, 'popen'), "test needs os.popen()")
     def test_getgroups(self):
         with os.popen('id -G 2>/dev/null') as idg:
             groups = idg.read().strip()
diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py
index 4ddd5fb96e0ce..f63564e6b0ee6 100644
--- a/Lib/test/test_select.py
+++ b/Lib/test/test_select.py
@@ -46,6 +46,7 @@ def test_returned_list_identity(self):
         self.assertIsNot(r, x)
         self.assertIsNot(w, x)
 
+    @unittest.skipUnless(hasattr(os, 'popen'), "need os.popen()")
     def test_select(self):
         code = textwrap.dedent('''
             import time
diff --git a/Misc/NEWS.d/next/Tests/2020-07-30-18-06-15.bpo-31904.y3d8dk.rst b/Misc/NEWS.d/next/Tests/2020-07-30-18-06-15.bpo-31904.y3d8dk.rst
new file mode 100644
index 0000000000000..fa2974963bf01
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2020-07-30-18-06-15.bpo-31904.y3d8dk.rst
@@ -0,0 +1 @@
+Disable os.popen and impacted tests on VxWorks



More information about the Python-checkins mailing list