Index: Lib/subprocess.py =================================================================== --- Lib/subprocess.py (revision 85719) +++ Lib/subprocess.py (working copy) @@ -617,6 +617,8 @@ bufsize = 0 # Restore default if not isinstance(bufsize, int): raise TypeError("bufsize must be an integer") + if bufsize == 0 and universal_newlines: + raise ValueError("cannot use bufsize=0 with universal newlines") if mswindows: if preexec_fn is not None: @@ -677,8 +679,6 @@ if errread != -1: errread = msvcrt.open_osfhandle(errread.Detach(), 0) - if bufsize == 0: - bufsize = 1 # Nearly unbuffered (XXX for now) if p2cwrite != -1: self.stdin = io.open(p2cwrite, 'wb', bufsize) if self.universal_newlines: Index: Lib/test/test_subprocess.py =================================================================== --- Lib/test/test_subprocess.py (revision 85719) +++ Lib/test/test_subprocess.py (working copy) @@ -523,6 +523,20 @@ self.assertEqual(p.wait(), 0) + def test_bufsize_is_zero(self): + # bufsize=0 makes Popen unbuffered + p = subprocess.Popen([sys.executable, "-c", + 'import sys; sys.exit(sys.stdin.read(1) == "X")'], + stdin=subprocess.PIPE, bufsize=0) + p.stdin.write(b"X") + p.wait() + self.assertEqual(p.returncode, 1) + # cannot use bufsize=0 with universal new lines + with self.assertRaises(ValueError): + subprocess.Popen([sys.executable, "-c", "pass"], + stdin=subprocess.PIPE, bufsize=0, + universal_newlines=True) + def test_invalid_bufsize(self): # an invalid type of the bufsize argument should raise # TypeError.