@@ -828,7 +828,7 @@ def process(self, argv=None, executable=None, tty=True, cwd=None, env=None, time
828
828
>>> print(s.process('false', preexec_fn=uses_globals).recvall().strip().decode()) # doctest: +ELLIPSIS
829
829
Traceback (most recent call last):
830
830
...
831
- NameError: global name 'bar' is not defined
831
+ NameError: name 'bar' is not defined
832
832
833
833
>>> s.process('echo hello', shell=True).recvall()
834
834
b'hello\n'
@@ -865,10 +865,14 @@ def process(self, argv=None, executable=None, tty=True, cwd=None, env=None, time
865
865
arg = oarg
866
866
if b'\x00 ' in arg [:- 1 ]:
867
867
self .error ('Inappropriate nulls in argv[%i]: %r' % (i , oarg ))
868
- argv [i ] = arg .rstrip (b'\x00 ' )
868
+ argv [i ] = bytearray ( arg .rstrip (b'\x00 ' ) )
869
869
870
+ if env is not None and not isinstance (env , dict ) and env != os .environ :
871
+ self .error ("env must be a dict: %r" % env )
872
+
873
+ # Converts the environment variables to a list of tuples to retain order.
874
+ env2 = []
870
875
# Python also doesn't like when envp contains '\x00'
871
- env2 = {}
872
876
if env and hasattr (env , 'items' ):
873
877
for k , v in env .items ():
874
878
if isinstance (k , six .text_type ):
@@ -879,17 +883,16 @@ def process(self, argv=None, executable=None, tty=True, cwd=None, env=None, time
879
883
self .error ('Inappropriate nulls in environment key %r' % k )
880
884
if b'\x00 ' in v [:- 1 ]:
881
885
self .error ('Inappropriate nulls in environment value %r=%r' % (k , v ))
882
- env2 [ k .rstrip (b'\x00 ' )] = v .rstrip (b'\x00 ' )
886
+ env2 . append (( bytearray ( k .rstrip (b'\x00 ' )), bytearray ( v .rstrip (b'\x00 ' ))) )
883
887
env = env2 or env
884
888
885
889
executable = executable or argv [0 ]
886
890
cwd = cwd or self .cwd
887
891
888
892
# Validate, since failures on the remote side will suck.
889
- if not isinstance (executable , (six .text_type , six .binary_type )):
893
+ if not isinstance (executable , (six .text_type , six .binary_type , bytearray )):
890
894
self .error ("executable / argv[0] must be a string: %r" % executable )
891
- if env is not None and not isinstance (env , dict ) and env != os .environ :
892
- self .error ("env must be a dict: %r" % env )
895
+ executable = context ._decode (executable )
893
896
894
897
# Allow passing in sys.stdin/stdout/stderr objects
895
898
handles = {sys .stdin : 0 , sys .stdout :1 , sys .stderr :2 }
@@ -912,22 +915,20 @@ def func(): pass
912
915
func_src = inspect .getsource (func ).strip ()
913
916
setuid = True if setuid is None else bool (setuid )
914
917
915
- # Converts the environment variables to a list of tuples to remain order.
916
- env = list (env .items ())
917
-
918
918
script = r"""
919
- #!/usr/bin/env python2
919
+ #!/usr/bin/env python
920
920
import os, sys, ctypes, resource, platform, stat
921
921
from collections import OrderedDict
922
922
exe = %(executable)r
923
- argv = %(argv)r
924
- env = OrderedDict( %(env)r)
923
+ argv = [bytes(a) for a in %(argv)r]
924
+ env = %(env)r
925
925
926
926
os.chdir(%(cwd)r)
927
927
928
928
if env is not None:
929
+ env = OrderedDict((bytes(k), bytes(v)) for k,v in env)
929
930
os.environ.clear()
930
- os .environ.update(env)
931
+ getattr(os, 'environb', os .environ) .update(env)
931
932
else:
932
933
env = os.environ
933
934
@@ -987,10 +988,11 @@ def is_exe(path):
987
988
988
989
for fd, newfd in {0: %(stdin)r, 1: %(stdout)r, 2:%(stderr)r}.items():
989
990
if newfd is None:
990
- close(fd)
991
- elif isinstance(newfd, str):
992
991
os.close(fd)
993
- os.open(newfd, os.O_RDONLY if fd == 0 else (os.O_RDWR|os.O_CREAT))
992
+ elif isinstance(newfd, (str, bytes)):
993
+ newfd = os.open(newfd, os.O_RDONLY if fd == 0 else (os.O_RDWR|os.O_CREAT))
994
+ os.dup2(newfd, fd)
995
+ os.close(newfd)
994
996
elif isinstance(newfd, int) and newfd != fd:
995
997
os.dup2(fd, newfd)
996
998
@@ -1015,7 +1017,7 @@ def is_exe(path):
1015
1017
pass
1016
1018
1017
1019
%(func_src)s
1018
- apply( %(func_name)s, %(func_args)r)
1020
+ %(func_name)s(* %(func_args)r)
1019
1021
1020
1022
os.execve(exe, argv, env)
1021
1023
""" % locals ()
@@ -1049,15 +1051,15 @@ def is_exe(path):
1049
1051
1050
1052
with self .progress (msg ) as h :
1051
1053
1052
- script = 'for py in python2.7 python2 python; do test -x "$(which $py 2>&1)" && exec $py -c %s check; done; echo 2' % sh_string (script )
1054
+ script = 'for py in python3 python; do test -x "$(which $py 2>&1)" && exec $py -c %s check; done; echo 2' % sh_string (script )
1053
1055
with context .local (log_level = 'error' ):
1054
1056
python = ssh_process (self , script , tty = True , raw = True , level = self .level , timeout = self .timeout )
1055
1057
1056
1058
try :
1057
1059
result = safeeval .const (python .recvline ())
1058
- except Exception :
1060
+ except ( EOFError , ValueError ) :
1059
1061
h .failure ("Process creation failed" )
1060
- self .warn_once ('Could not find a Python2 interpreter on %s\n ' % self .host \
1062
+ self .warn_once ('Could not find a Python interpreter on %s\n ' % self .host \
1061
1063
+ "Use ssh.run() instead of ssh.process()" )
1062
1064
return None
1063
1065
0 commit comments