[Python-checkins] cpython (merge 3.2 -> default): Issue #15592. Fix regression: subprocess.communicate() breaks on no input with

andrew.svetlov python-checkins at python.org
Tue Aug 14 17:43:13 CEST 2012


http://hg.python.org/cpython/rev/9d86480cc177
changeset:   78572:9d86480cc177
parent:      78565:05714e9811fa
parent:      78571:839bd8f98539
user:        Andrew Svetlov <andrew.svetlov at gmail.com>
date:        Tue Aug 14 18:40:21 2012 +0300
summary:
  Issue #15592. Fix regression: subprocess.communicate() breaks on no input with universal newlines true.

Patch by Chris Jerdonek.

files:
  Lib/subprocess.py           |  25 +++++++++++++------------
  Lib/test/test_subprocess.py |  14 ++++++++++++--
  2 files changed, 25 insertions(+), 14 deletions(-)


diff --git a/Lib/subprocess.py b/Lib/subprocess.py
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -1536,6 +1536,17 @@
             return (stdout, stderr)
 
 
+        def _save_input(self, input):
+            # This method is called from the _communicate_with_*() methods
+            # so that if we time out while communicating, we can continue
+            # sending input if we retry.
+            if self.stdin and self._input is None:
+                self._input_offset = 0
+                self._input = input
+                if self.universal_newlines and input is not None:
+                    self._input = self._input.encode(self.stdin.encoding)
+
+
         def _communicate_with_poll(self, input, endtime, orig_timeout):
             stdout = None # Return
             stderr = None # Return
@@ -1572,13 +1583,7 @@
                 register_and_append(self.stderr, select_POLLIN_POLLPRI)
                 stderr = self._fd2output[self.stderr.fileno()]
 
-            # Save the input here so that if we time out while communicating,
-            # we can continue sending input if we retry.
-            if self.stdin and self._input is None:
-                self._input_offset = 0
-                self._input = input
-                if self.universal_newlines:
-                    self._input = self._input.encode(self.stdin.encoding)
+            self._save_input(input)
 
             while self._fd2file:
                 timeout = self._remaining_time(endtime)
@@ -1632,11 +1637,7 @@
                 if self.stderr:
                     self._read_set.append(self.stderr)
 
-            if self.stdin and self._input is None:
-                self._input_offset = 0
-                self._input = input
-                if self.universal_newlines:
-                    self._input = self._input.encode(self.stdin.encoding)
+            self._save_input(input)
 
             stdout = None # Return
             stderr = None # Return
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -615,8 +615,6 @@
                              universal_newlines=1)
         self.addCleanup(p.stdout.close)
         self.addCleanup(p.stderr.close)
-        # BUG: can't give a non-empty stdin because it breaks both the
-        # select- and poll-based communicate() implementations.
         (stdout, stderr) = p.communicate()
         self.assertEqual(stdout,
                          "line2\nline4\nline5\nline6\nline7\nline8")
@@ -635,6 +633,18 @@
         (stdout, stderr) = p.communicate("line1\nline3\n")
         self.assertEqual(p.returncode, 0)
 
+    def test_universal_newlines_communicate_input_none(self):
+        # Test communicate(input=None) with universal newlines.
+        #
+        # We set stdout to PIPE because, as of this writing, a different
+        # code path is tested when the number of pipes is zero or one.
+        p = subprocess.Popen([sys.executable, "-c", "pass"],
+                             stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE,
+                             universal_newlines=True)
+        p.communicate()
+        self.assertEqual(p.returncode, 0)
+
     def test_no_leaking(self):
         # Make sure we leak no resources
         if not mswindows:

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list