]> granicus.if.org Git - python/commitdiff
Merge with 3.2
authorRoss Lagerwall <rosslagerwall@gmail.com>
Tue, 5 Apr 2011 14:07:49 +0000 (16:07 +0200)
committerRoss Lagerwall <rosslagerwall@gmail.com>
Tue, 5 Apr 2011 14:07:49 +0000 (16:07 +0200)
1  2 
Lib/subprocess.py
Lib/test/test_subprocess.py
Misc/NEWS

index 2bff4b6ecf4a917be477c99dc392c941b30e5641,b3fb9355c9bd3ea032ed009ab44f18ac074b6127..e4bb78e87991e0d6eff72208636961e39910a1f2
@@@ -348,12 -345,10 +348,13 @@@ import g
  import signal
  import builtins
  import warnings
+ import errno
  
  # Exception classes used by this module.
 -class CalledProcessError(Exception):
 +class SubprocessError(Exception): pass
 +
 +
 +class CalledProcessError(SubprocessError):
      """This exception is raised when a process run by check_call() or
      check_output() returns a non-zero exit status.
      The exit status will be stored in the returncode attribute;
@@@ -1104,31 -1023,17 +1108,35 @@@ class Popen(object)
  
              if self.stdin:
                  if input is not None:
-                     self.stdin.write(input)
+                     try:
+                         self.stdin.write(input)
+                     except IOError as e:
+                         if e.errno != errno.EPIPE:
+                             raise
                  self.stdin.close()
  
 +            # Wait for the reader threads, or time out.  If we time out, the
 +            # threads remain reading and the fds left open in case the user
 +            # calls communicate again.
 +            if self.stdout is not None:
 +                self.stdout_thread.join(self._remaining_time(endtime))
 +                if self.stdout_thread.isAlive():
 +                    raise TimeoutExpired(self.args, orig_timeout)
 +            if self.stderr is not None:
 +                self.stderr_thread.join(self._remaining_time(endtime))
 +                if self.stderr_thread.isAlive():
 +                    raise TimeoutExpired(self.args, orig_timeout)
 +
 +            # Collect the output from and close both pipes, now that we know
 +            # both have been read successfully.
 +            stdout = None
 +            stderr = None
              if self.stdout:
 -                stdout_thread.join()
 +                stdout = self._stdout_buff
 +                self.stdout.close()
              if self.stderr:
 -                stderr_thread.join()
 +                stderr = self._stderr_buff
 +                self.stderr.close()
  
              # All data exchanged.  Translate lists into strings.
              if stdout is not None:
  
                  for fd, mode in ready:
                      if mode & select.POLLOUT:
 -                        chunk = input[input_offset : input_offset + _PIPE_BUF]
 +                        chunk = self._input[self._input_offset :
 +                                            self._input_offset + _PIPE_BUF]
-                         self._input_offset += os.write(fd, chunk)
-                         if self._input_offset >= len(self._input):
-                             close_unregister_and_remove(fd)
+                         try:
 -                            input_offset += os.write(fd, chunk)
++                            self._input_offset += os.write(fd, chunk)
+                         except OSError as e:
+                             if e.errno == errno.EPIPE:
+                                 close_unregister_and_remove(fd)
+                             else:
+                                 raise
+                         else:
 -                            if input_offset >= len(input):
++                            if self._input_offset >= len(self._input):
+                                 close_unregister_and_remove(fd)
                      elif mode & select_POLLIN_POLLPRI:
                          data = os.read(fd, 4096)
                          if not data:
                  # file objects; they are no longer using C stdio!
  
                  if self.stdin in wlist:
 -                    chunk = input[input_offset : input_offset + _PIPE_BUF]
 +                    chunk = self._input[self._input_offset :
 +                                        self._input_offset + _PIPE_BUF]
-                     bytes_written = os.write(self.stdin.fileno(), chunk)
-                     self._input_offset += bytes_written
-                     if self._input_offset >= len(self._input):
-                         self.stdin.close()
-                         self._write_set.remove(self.stdin)
+                     try:
+                         bytes_written = os.write(self.stdin.fileno(), chunk)
+                     except OSError as e:
+                         if e.errno == errno.EPIPE:
+                             self.stdin.close()
 -                            write_set.remove(self.stdin)
++                            self._write_set.remove(self.stdin)
+                         else:
+                             raise
+                     else:
 -                        input_offset += bytes_written
 -                        if input_offset >= len(input):
++                        self._input_offset += bytes_written
++                        if self._input_offset >= len(self._input):
+                             self.stdin.close()
 -                            write_set.remove(self.stdin)
++                            self._write_set.remove(self.stdin)
  
                  if self.stdout in rlist:
                      data = os.read(self.stdout.fileno(), 1024)
Simple merge
diff --cc Misc/NEWS
index 3b59906c074dc66cfd888a9b5362906940da874c,7ab3a5d2be016170137f6a9643a45f9f862bef7e..91fe4bf1eec0fbe9562417f35765db58d8d8d5e9
+++ b/Misc/NEWS
@@@ -94,15 -49,8 +94,17 @@@ Core and Builtin
  Library
  -------
  
+ - Issue #10963: Ensure that subprocess.communicate() never raises EPIPE.
 +- Issue #10791: Implement missing method GzipFile.read1(), allowing GzipFile
 +  to be wrapped in a TextIOWrapper.  Patch by Nadeem Vawda.
 +
 +- Issue #11707: Added a fast C version of functools.cmp_to_key().
 +  Patch by Filip GruszczyƄski.
 +
 +- Issue #11688: Add sqlite3.Connection.set_trace_callback().  Patch by
 +  Torsten Landschoff.
 +
  - Issue #11746: Fix SSLContext.load_cert_chain() to accept elliptic curve
    private keys.