summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-19 19:20:03 (GMT)
committerAndrew Svetlov <andrew.svetlov@gmail.com>2012-08-19 19:20:03 (GMT)
commita19de803e4661af947938df2db72d0cd5538f4a4 (patch)
tree2ee7a770a1529a23b0eddae70cc383361676d369 /Lib
parent377a152e0dab743b165236024f50602a325d8b93 (diff)
parent828607170da3986af909defe99f956e5762e4dd0 (diff)
downloadcpython-a19de803e4661af947938df2db72d0cd5538f4a4.zip
cpython-a19de803e4661af947938df2db72d0cd5538f4a4.tar.gz
cpython-a19de803e4661af947938df2db72d0cd5538f4a4.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.py32
2 files changed, 34 insertions, 2 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 249b5f6..cec1a24 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -828,8 +828,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 74ce091..2420772 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
@@ -675,6 +676,37 @@ class ProcessTestCase(BaseTestCase):
# Don't use assertStderrEqual because it strips CR and LF from output.
self.assertTrue(stderr.startswith("eline2\neline6\neline7\n"))
+ 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: