Merged revisions 73196,73278-73280,73299,73308,73312-73313,73317-73318,73321,73324,73331,73335,73340,73363 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r73196 | benjamin.peterson | 2009-06-03 20:40:29 -0500 (Wed, 03 Jun 2009) | 1 line

  use the offical api
........
  r73278 | benjamin.peterson | 2009-06-07 17:33:11 -0500 (Sun, 07 Jun 2009) | 1 line

  inherit from object
........
  r73279 | benjamin.peterson | 2009-06-07 17:35:00 -0500 (Sun, 07 Jun 2009) | 1 line

  always inherit from an appropiate base class
........
  r73280 | benjamin.peterson | 2009-06-07 17:54:35 -0500 (Sun, 07 Jun 2009) | 1 line

  use booleans for flags
........
  r73299 | georg.brandl | 2009-06-08 13:41:36 -0500 (Mon, 08 Jun 2009) | 1 line

  Typo fix.
........
  r73308 | benjamin.peterson | 2009-06-08 17:18:32 -0500 (Mon, 08 Jun 2009) | 1 line

  remove useless assertion
........
  r73312 | benjamin.peterson | 2009-06-08 18:44:13 -0500 (Mon, 08 Jun 2009) | 1 line

  remove error checks already done in set_context()
........
  r73313 | r.david.murray | 2009-06-08 19:44:22 -0500 (Mon, 08 Jun 2009) | 4 lines

  Issue 2947: document how return code handling translates from
  os.popen to subprocess.  Also fixes reference link in the
  os.spawn documentation.
........
  r73317 | benjamin.peterson | 2009-06-09 12:24:26 -0500 (Tue, 09 Jun 2009) | 1 line

  make ast.c depend on the grammar
........
  r73318 | benjamin.peterson | 2009-06-09 12:29:51 -0500 (Tue, 09 Jun 2009) | 1 line

  explain why keyword names are not just NAME
........
  r73321 | benjamin.peterson | 2009-06-09 16:13:43 -0500 (Tue, 09 Jun 2009) | 1 line

  update symbol.py from with statement changes
........
  r73324 | amaury.forgeotdarc | 2009-06-09 17:53:16 -0500 (Tue, 09 Jun 2009) | 2 lines

  Avoid invoking the parser/compiler just to test the presence of a function.
........
  r73331 | benjamin.peterson | 2009-06-10 08:45:31 -0500 (Wed, 10 Jun 2009) | 1 line

  fix spelling
........
  r73335 | raymond.hettinger | 2009-06-10 11:15:40 -0500 (Wed, 10 Jun 2009) | 1 line

  Fix signed/unsigned compiler warning.
........
  r73340 | amaury.forgeotdarc | 2009-06-10 15:30:19 -0500 (Wed, 10 Jun 2009) | 2 lines

  Fix a typo spotted by Nick Coghlan.
........
  r73363 | benjamin.peterson | 2009-06-11 12:51:17 -0500 (Thu, 11 Jun 2009) | 1 line

  use multi-with syntax
........
diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst
index 3318d43..d0e655d 100644
--- a/Doc/library/subprocess.rst
+++ b/Doc/library/subprocess.rst
@@ -412,8 +412,8 @@
    output = p2.communicate()[0]
 
 
-Replacing os.system()
-^^^^^^^^^^^^^^^^^^^^^
+Replacing :func:`os.system`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 ::
 
@@ -440,8 +440,8 @@
        print("Execution failed:", e, file=sys.stderr)
 
 
-Replacing the os.spawn family
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Replacing the :func:`os.spawn <os.spawnl>` family
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 P_NOWAIT example::
 
@@ -468,17 +468,85 @@
    Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"})
 
 
-Replacing os.popen
-^^^^^^^^^^^^^^^^^^
+
+Replacing :func:`os.popen`, :func:`os.popen2`, :func:`os.popen3`
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 ::
 
-   pipe = os.popen(cmd, 'r', bufsize)
+   (child_stdin, child_stdout) = os.popen2(cmd, mode, bufsize)
    ==>
-   pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
+   p = Popen(cmd, shell=True, bufsize=bufsize,
+             stdin=PIPE, stdout=PIPE, close_fds=True)
+   (child_stdin, child_stdout) = (p.stdin, p.stdout)
 
 ::
 
-   pipe = os.popen(cmd, 'w', bufsize)
+   (child_stdin,
+    child_stdout,
+    child_stderr) = os.popen3(cmd, mode, bufsize)
    ==>
-   pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
+   p = Popen(cmd, shell=True, bufsize=bufsize,
+             stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
+   (child_stdin,
+    child_stdout,
+    child_stderr) = (p.stdin, p.stdout, p.stderr)
+
+::
+
+   (child_stdin, child_stdout_and_stderr) = os.popen4(cmd, mode, bufsize)
+   ==>
+   p = Popen(cmd, shell=True, bufsize=bufsize,
+             stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
+   (child_stdin, child_stdout_and_stderr) = (p.stdin, p.stdout)
+
+Return code handling translates as follows::
+
+   pipe = os.popen(cmd, 'w')
+   ...
+   rc = pipe.close()
+   if  rc != None and rc % 256:
+       print "There were some errors"
+   ==>
+   process = Popen(cmd, 'w', stdin=PIPE)
+   ...
+   process.stdin.close()
+   if process.wait() != 0:
+       print "There were some errors"
+
+
+Replacing functions from the :mod:`popen2` module
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+
+   If the cmd argument to popen2 functions is a string, the command is executed
+   through /bin/sh.  If it is a list, the command is directly executed.
+
+::
+
+   (child_stdout, child_stdin) = popen2.popen2("somestring", bufsize, mode)
+   ==>
+   p = Popen(["somestring"], shell=True, bufsize=bufsize,
+             stdin=PIPE, stdout=PIPE, close_fds=True)
+   (child_stdout, child_stdin) = (p.stdout, p.stdin)
+
+::
+
+   (child_stdout, child_stdin) = popen2.popen2(["mycmd", "myarg"], bufsize, mode)
+   ==>
+   p = Popen(["mycmd", "myarg"], bufsize=bufsize,
+             stdin=PIPE, stdout=PIPE, close_fds=True)
+   (child_stdout, child_stdin) = (p.stdout, p.stdin)
+
+:class:`popen2.Popen3` and :class:`popen2.Popen4` basically work as
+:class:`subprocess.Popen`, except that:
+
+* :class:`Popen` raises an exception if the execution fails.
+
+* the *capturestderr* argument is replaced with the *stderr* argument.
+
+* ``stdin=PIPE`` and ``stdout=PIPE`` must be specified.
+
+* popen2 closes all file descriptors by default, but you have to specify
+  ``close_fds=True`` with :class:`Popen`.