Skip to content

Commit 978ada4

Browse files
committed
improve error handling robustness for os.execvpe
see: pexpect/pexpect#512
1 parent 3931cd4 commit 978ada4

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

ptyprocess/ptyprocess.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,18 @@ def spawn(
206206
if not isinstance(argv, (list, tuple)):
207207
raise TypeError("Expected a list or tuple for argv, got %r" % argv)
208208

209+
# env vars must be utf-8 encoded strings
210+
# https://github.com/pexpect/pexpect/issues/512
211+
#
212+
# from https://docs.python.org/3.8/library/os.html#os.execvpe
213+
# Errors will be reported as OSError exceptions.
214+
_text_type = str
215+
if not PY3:
216+
_text_type = unicode
217+
for k, v in env.items():
218+
if isinstance(v, _text_type):
219+
env[k] = v.encode('utf-8')
220+
209221
# Shallow copy of argv so we can modify it
210222
argv = argv[:]
211223
command = argv[0]
@@ -289,10 +301,14 @@ def spawn(
289301
os.execv(command, argv)
290302
else:
291303
os.execvpe(command, argv, env)
292-
except OSError as err:
304+
except Exception as err:
293305
# [issue #119] 5. If exec fails, the child writes the error
294306
# code back to the parent using the pipe, then exits.
295-
tosend = 'OSError:{}:{}'.format(err.errno, str(err))
307+
if isinstance(err, OSError):
308+
tosend = 'OSError:{}:{}'.format(err.errno, str(err))
309+
else:
310+
cls_name = err.__class__.__name__
311+
tosend = 'Exception:0:{}: {}'.format(cls_name, str(err))
296312
if PY3:
297313
tosend = tosend.encode('utf-8')
298314
os.write(exec_err_pipe_write, tosend)

0 commit comments

Comments
 (0)