Skip to content

Commit 3e4bbba

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

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

ptyprocess/ptyprocess.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,19 @@ 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+
if isinstance(env, dict):
215+
_text_type = str
216+
if not PY3:
217+
_text_type = unicode
218+
for k, v in env.items():
219+
if isinstance(v, _text_type):
220+
env[k] = v.encode('utf-8')
221+
209222
# Shallow copy of argv so we can modify it
210223
argv = argv[:]
211224
command = argv[0]
@@ -289,10 +302,14 @@ def spawn(
289302
os.execv(command, argv)
290303
else:
291304
os.execvpe(command, argv, env)
292-
except OSError as err:
305+
except Exception as err:
293306
# [issue #119] 5. If exec fails, the child writes the error
294307
# code back to the parent using the pipe, then exits.
295-
tosend = 'OSError:{}:{}'.format(err.errno, str(err))
308+
if isinstance(err, OSError):
309+
tosend = 'OSError:{}:{}'.format(err.errno, str(err))
310+
else:
311+
cls_name = err.__class__.__name__
312+
tosend = 'Exception:0:{}: {}'.format(cls_name, str(err))
296313
if PY3:
297314
tosend = tosend.encode('utf-8')
298315
os.write(exec_err_pipe_write, tosend)

0 commit comments

Comments
 (0)