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

Skip to content

Commit 13bb71c

Browse files
author
Victor Stinner
committed
Issue #8391: os.execvpe() and os.getenv() supports unicode with surrogates and
bytes strings for environment keys and values
1 parent 534db4e commit 13bb71c

5 files changed

Lines changed: 123 additions & 169 deletions

File tree

Lib/os.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ def setdefault(self, key, value):
450450
def getenv(key, default=None):
451451
"""Get an environment variable, return None if it doesn't exist.
452452
The optional second argument can specify an alternate default."""
453+
if isinstance(key, bytes):
454+
key = key.decode(sys.getfilesystemencoding(), "surrogateescape")
453455
return environ.get(key, default)
454456
__all__.append("getenv")
455457

Lib/subprocess.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,10 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
10901090
fs_encoding = sys.getfilesystemencoding()
10911091
def fs_encode(s):
10921092
"""Encode s for use in the env, fs or cmdline."""
1093-
return s.encode(fs_encoding, 'surrogateescape')
1093+
if isinstance(s, bytes):
1094+
return s
1095+
else:
1096+
return s.encode(fs_encoding, 'surrogateescape')
10941097

10951098
# We must avoid complex work that could involve
10961099
# malloc or free in the child process to avoid

Lib/test/test_subprocess.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ def test_terminate(self):
782782
self.assertStderrEqual(stderr, b'')
783783
self.assertEqual(p.wait(), -signal.SIGTERM)
784784

785-
def test_surrogates(self):
785+
def test_surrogates_error_message(self):
786786
def prepare():
787787
raise ValueError("surrogate:\uDCff")
788788

@@ -801,6 +801,28 @@ def prepare():
801801
else:
802802
self.fail("Expected ValueError or RuntimeError")
803803

804+
def test_undecodable_env(self):
805+
for key, value in (('test', 'abc\uDCFF'), ('test\uDCFF', '42')):
806+
value_repr = repr(value).encode("ascii")
807+
808+
# test str with surrogates
809+
script = "import os; print(repr(os.getenv(%s)))" % repr(key)
810+
stdout = subprocess.check_output(
811+
[sys.executable, "-c", script],
812+
env={key: value})
813+
stdout = stdout.rstrip(b'\n\r')
814+
self.assertEquals(stdout, value_repr)
815+
816+
# test bytes
817+
key = key.encode("ascii", "surrogateescape")
818+
value = value.encode("ascii", "surrogateescape")
819+
script = "import os; print(repr(os.getenv(%s)))" % repr(key)
820+
stdout = subprocess.check_output(
821+
[sys.executable, "-c", script],
822+
env={key: value})
823+
stdout = stdout.rstrip(b'\n\r')
824+
self.assertEquals(stdout, value_repr)
825+
804826

805827
@unittest.skipUnless(mswindows, "Windows specific tests")
806828
class Win32ProcessTestCase(BaseTestCase):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ C-API
333333
Library
334334
-------
335335

336+
- Issue #8391: os.execvpe() and os.getenv() supports unicode with surrogates
337+
and bytes strings for environment keys and values
338+
336339
- Issue #8467: Pure Python implementation of subprocess encodes the error
337340
message using surrogatepass error handler to support surrogates in the
338341
message

0 commit comments

Comments
 (0)