Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8286071

Browse files
committed
Issue #15595: Fix subprocess.Popen(universal_newlines=True)
for certain locales (utf-16 and utf-32 family). Patch by Chris Jerdonek.
1 parent 6b96286 commit 8286071

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

Lib/subprocess.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,8 +755,8 @@ def __init__(self, args, bufsize=0, executable=None,
755755

756756

757757
def _translate_newlines(self, data, encoding):
758-
data = data.replace(b"\r\n", b"\n").replace(b"\r", b"\n")
759-
return data.decode(encoding)
758+
data = data.decode(encoding)
759+
return data.replace("\r\n", "\n").replace("\r", "\n")
760760

761761
def __enter__(self):
762762
return self

Lib/test/test_subprocess.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import sys
55
import signal
66
import io
7+
import locale
78
import os
89
import errno
910
import tempfile
@@ -560,6 +561,38 @@ def test_universal_newlines_communicate_input_none(self):
560561
p.communicate()
561562
self.assertEqual(p.returncode, 0)
562563

564+
def test_universal_newlines_communicate_encodings(self):
565+
# Check that universal newlines mode works for various encodings,
566+
# in particular for encodings in the UTF-16 and UTF-32 families.
567+
# See issue #15595.
568+
#
569+
# UTF-16 and UTF-32-BE are sufficient to check both with BOM and
570+
# without, and UTF-16 and UTF-32.
571+
for encoding in ['utf-16', 'utf-32-be']:
572+
old_getpreferredencoding = locale.getpreferredencoding
573+
# Indirectly via io.TextIOWrapper, Popen() defaults to
574+
# locale.getpreferredencoding(False) and earlier in Python 3.2 to
575+
# locale.getpreferredencoding().
576+
def getpreferredencoding(do_setlocale=True):
577+
return encoding
578+
code = ("import sys; "
579+
r"sys.stdout.buffer.write('1\r\n2\r3\n4'.encode('%s'))" %
580+
encoding)
581+
args = [sys.executable, '-c', code]
582+
try:
583+
locale.getpreferredencoding = getpreferredencoding
584+
# We set stdin to be non-None because, as of this writing,
585+
# a different code path is used when the number of pipes is
586+
# zero or one.
587+
popen = subprocess.Popen(args, universal_newlines=True,
588+
stdin=subprocess.PIPE,
589+
stdout=subprocess.PIPE)
590+
stdout, stderr = popen.communicate(input='')
591+
finally:
592+
locale.getpreferredencoding = old_getpreferredencoding
593+
594+
self.assertEqual(stdout, '1\n2\n3\n4')
595+
563596
def test_no_leaking(self):
564597
# Make sure we leak no resources
565598
if not mswindows:

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ Core and Builtins
104104
Library
105105
-------
106106

107+
- Issue #15595: Fix subprocess.Popen(universal_newlines=True)
108+
for certain locales (utf-16 and utf-32 family). Patch by Chris Jerdonek.
109+
107110
- Issue #15477: In cmath and math modules, add workaround for platforms whose
108111
system-supplied log1p function doesn't respect signs of zeros.
109112

0 commit comments

Comments
 (0)