summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-19 19:13:41 (GMT)
committerAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-19 19:13:41 (GMT)
commit828607170da3986af909defe99f956e5762e4dd0 (patch)
tree6951965e9b6f5af373180d2ec13349221462929d /Lib
parent6b962860e2bd2d08d8d5d38969ed4864f8c1219a (diff)
downloadcpython-828607170da3986af909defe99f956e5762e4dd0.zip
cpython-828607170da3986af909defe99f956e5762e4dd0.tar.gz
cpython-828607170da3986af909defe99f956e5762e4dd0.tar.bz2
Issue #15595: Fix subprocess.Popen(universal_newlines=True)
for certain locales (utf-16 and utf-32 family). Patch by Chris Jerdonek.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/subprocess.py4
-rw-r--r--Lib/test/test_subprocess.py33
2 files changed, 35 insertions, 2 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 179f41a..106af8b 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -755,8 +755,8 @@ class Popen(object):
def _translate_newlines(self, data, encoding):
- data = data.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
- return data.decode(encoding)
+ data = data.decode(encoding)
+ return data.replace("\r\n", "\n").replace("\r", "\n")
def __enter__(self):
return self
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 9e92a96..620cd8e 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -4,6 +4,7 @@ import subprocess
import sys
import signal
import io
+import locale
import os
import errno
import tempfile
@@ -560,6 +561,38 @@ class ProcessTestCase(BaseTestCase):
p.communicate()
self.assertEqual(p.returncode, 0)
+ def test_universal_newlines_communicate_encodings(self):
+ # Check that universal newlines mode works for various encodings,
+ # in particular for encodings in the UTF-16 and UTF-32 families.
+ # See issue #15595.
+ #
+ # UTF-16 and UTF-32-BE are sufficient to check both with BOM and
+ # without, and UTF-16 and UTF-32.
+ for encoding in ['utf-16', 'utf-32-be']:
+ old_getpreferredencoding = locale.getpreferredencoding
+ # Indirectly via io.TextIOWrapper, Popen() defaults to
+ # locale.getpreferredencoding(False) and earlier in Python 3.2 to
+ # locale.getpreferredencoding().
+ def getpreferredencoding(do_setlocale=True):
+ return encoding
+ code = ("import sys; "
+ r"sys.stdout.buffer.write('1\r\n2\r3\n4'.encode('%s'))" %
+ encoding)
+ args = [sys.executable, '-c', code]
+ try:
+ locale.getpreferredencoding = getpreferredencoding
+ # We set stdin to be non-None because, as of this writing,
+ # a different code path is used when the number of pipes is
+ # zero or one.
+ popen = subprocess.Popen(args, universal_newlines=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE)
+ stdout, stderr = popen.communicate(input='')
+ finally:
+ locale.getpreferredencoding = old_getpreferredencoding
+
+ self.assertEqual(stdout, '1\n2\n3\n4')
+
def test_no_leaking(self):
# Make sure we leak no resources
if not mswindows: