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 @@ -150,16 +150,29 @@ self.assertEqual(p.stdin, None) def test_stdout_none(self): - # .stdout is None when not redirected - p = subprocess.Popen([sys.executable, "-c", - 'print " this bit of output is from a ' - 'test of stdout in a different ' - 'process ..."'], - stdin=subprocess.PIPE, stderr=subprocess.PIPE) + # .stdout is None when not redirected, and the child's stdout will + # be inherited from the parent. In order to test this we run a + # subprocess in a subprocess: + # this_test + # \-- subprocess created by this test (parent) + # \-- subprocess created by the parent subprocess (child) + # The parent doesn't specify stdout, so the child will use the + # parent's stdout. This test checks that the message printed by the + # child goes to the parent stdout. The parent also checks that the + # child's stdout is None. See #11963. + code = ('import sys; from subprocess import Popen, PIPE;' + 'p = Popen([sys.executable, "-c", "print \'test_stdout_none\'"],' + ' stdin=PIPE, stderr=PIPE);' + 'p.wait(); assert p.stdout == None;') + PIPE = subprocess.PIPE + p = subprocess.Popen([sys.executable, "-c", code], + stdout=PIPE, stdin=PIPE, stderr=PIPE) self.addCleanup(p.stdin.close) + self.addCleanup(p.stdout.close) self.addCleanup(p.stderr.close) - p.wait() - self.assertEqual(p.stdout, None) + out, err = p.communicate() + self.assertEqual(p.returncode, 0) + self.assertEqual(out, 'test_stdout_none\n') def test_stderr_none(self): # .stderr is None when not redirected @@ -308,9 +321,21 @@ def test_stdout_filedes_of_stdout(self): # stdout is set to 1 (#1531862). - cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))" - rc = subprocess.call([sys.executable, "-c", cmd], stdout=1) - self.assertEqual(rc, 2) + # To avoid printing the '.\n' on stdout, we do something similar to + # test_stdout_none (see above). The parent subprocess calls the child + # subprocess passing stdout=1, and this tests uses stdout=PIPE in + # order to capture and check the output of the parent. See #11963. + code = ('import sys, subprocess; ' + 'rc = subprocess.call([sys.executable, "-c", ' + ' "import os, sys; sys.exit(os.write(sys.stdout.fileno(), ' + '\'.\\\\n\'))"], stdout=1); ' + 'assert rc == 2') + PIPE = subprocess.PIPE + p = subprocess.Popen([sys.executable, "-c", code], + stdout=PIPE, stdin=PIPE, stderr=PIPE) + out, err = p.communicate() + self.assertEqual(p.returncode, 0) + self.assertEqual(out, '.\n') def test_cwd(self): tmpdir = tempfile.gettempdir()