From: <pj...@us...> - 2009-04-03 00:52:45
|
Revision: 6149 http://jython.svn.sourceforge.net/jython/?rev=6149&view=rev Author: pjenvey Date: 2009-04-03 00:52:31 +0000 (Fri, 03 Apr 2009) Log Message: ----------- ensure sane args to subprocess, fix OSError message Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-04-02 02:32:59 UTC (rev 6148) +++ trunk/jython/Lib/subprocess.py 2009-04-03 00:52:31 UTC (rev 6149) @@ -1143,7 +1143,14 @@ if isinstance(args, types.StringTypes): args = [args] else: - args = escape_args(list(args)) + args = list(args) + for arg in args: + # XXX: CPython posix (execv) will str() any unicode + # args first, maybe we should do the same on + # posix. Windows passes unicode through however + if not isinstance(arg, (str, unicode)): + raise TypeError('args must contain only strings') + args = escape_args(args) if shell: args = shell_command + args @@ -1171,7 +1178,7 @@ elif not os.path.exists(cwd): raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), cwd) elif not os.path.isdir(cwd): - raise OSError(errno.ENOTDIR, os.strerror(errno.ENOENT), cwd) + raise OSError(errno.ENOTDIR, os.strerror(errno.ENOTDIR), cwd) builder.directory(java.io.File(cwd)) # Let Java manage redirection of stderr to stdout (it's more This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-05 07:19:39
|
Revision: 6296 http://jython.svn.sourceforge.net/jython/?rev=6296&view=rev Author: pjenvey Date: 2009-05-05 07:19:13 +0000 (Tue, 05 May 2009) Log Message: ----------- avoid overwriting any ProcessBuilder env vars unless it's necessary. it inherits them from Sysem.getenv and will maintain their underlying byte values (which may be butchered as Strings) on UNIX platforms if we don't touch them Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-05-05 01:31:30 UTC (rev 6295) +++ trunk/jython/Lib/subprocess.py 2009-05-05 07:19:13 UTC (rev 6296) @@ -1132,6 +1132,30 @@ return CouplerThread(*args, **kwargs) + def _setup_env(self, env, builder_env): + """Carefully merge env with ProcessBuilder's only + overwriting key/values that differ + + System.getenv (Map<String, String>) may be backed by + <byte[], byte[]> on UNIX platforms where these are really + bytes. ProcessBuilder's env inherits its contents and will + maintain those byte values (which may be butchered as + Strings) for the subprocess if they haven't been modified. + """ + # Determine what's safe to merge + merge_env = dict((key, value) for key, value in env.iteritems() + if key not in builder_env or + builder_env.get(key) != value) + + # Prune anything not in env + entries = builder_env.entrySet().iterator() + for entry in entries: + if entry.getKey() not in env: + entries.remove() + + builder_env.putAll(merge_env) + + def _execute_child(self, args, executable, preexec_fn, close_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, @@ -1163,16 +1187,10 @@ except java.lang.IllegalArgumentException, iae: raise OSError(iae.getMessage() or iae) - if env is None: - # For compatibility with CPython which calls - # os.execvp(). os.environ is "inherited" there if env is - # not explicitly set - env = os.environ + # os.environ may be inherited for compatibility with CPython + self._setup_env(dict(os.environ if env is None else env), + builder.environment()) - builder_env = builder.environment() - builder_env.clear() - builder_env.putAll(dict(env)) - if cwd is None: cwd = os.getcwd() elif not os.path.exists(cwd): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-23 02:22:28
|
Revision: 6365 http://jython.svn.sourceforge.net/jython/?rev=6365&view=rev Author: pjenvey Date: 2009-05-23 01:42:59 +0000 (Sat, 23 May 2009) Log Message: ----------- make the Jython extras especially private Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-05-23 01:23:24 UTC (rev 6364) +++ trunk/jython/Lib/subprocess.py 2009-05-23 01:42:59 UTC (rev 6365) @@ -545,45 +545,45 @@ if jython: # Escape the command line arguments with list2cmdline on Windows - escape_args_oses = ['nt'] + _escape_args_oses = ['nt'] - escape_args = None - shell_command = None + _escape_args = None + _shell_command = None - def setup_platform(): + def _setup_platform(): """Setup the shell command and the command line argument escape function depending on the underlying platform """ - global escape_args, shell_command + global _escape_args, _shell_command - if os._name in escape_args_oses: - escape_args = lambda args: [list2cmdline([arg]) for arg in args] + if os._name in _escape_args_oses: + _escape_args = lambda args: [list2cmdline([arg]) for arg in args] else: - escape_args = lambda args: args + _escape_args = lambda args: args os_info = os._os_map.get(os._name) if os_info is None: os_info = os._os_map.get('posix') - for _shell_command in os_info[1]: - executable = _shell_command[0] + for shell_command in os_info[1]: + executable = shell_command[0] if not os.path.isabs(executable): import distutils.spawn executable = distutils.spawn.find_executable(executable) if not executable or not os.path.exists(executable): continue - _shell_command[0] = executable - shell_command = _shell_command + shell_command[0] = executable + _shell_command = shell_command return - if not shell_command: + if not _shell_command: import warnings - warnings.warn('Unable to determine shell_command for ' + warnings.warn('Unable to determine _shell_command for ' 'underlying os: %s' % os._name, RuntimeWarning, 3) - setup_platform() + _setup_platform() - class CouplerThread(java.lang.Thread): + class _CouplerThread(java.lang.Thread): """Couples a reader and writer RawIOBase. @@ -603,7 +603,8 @@ self.read_func = read_func self.write_func = write_func self.close_func = close_func - self.setName('CouplerThread-%s (%s)' % (id(self), name)) + self.setName('%s-%s (%s)' % (self.__class__.__name__, id(self), + name)) self.setDaemon(True) def run(self): @@ -720,7 +721,7 @@ self._stdout_thread = None self._stderr_thread = None - # 'ct' is for CouplerThread + # 'ct' is for _CouplerThread proc = self._process ct2cwrite = org.python.core.io.StreamIO(proc.getOutputStream(), True) @@ -737,8 +738,9 @@ if p2cread is None: # Coupling stdin is not supported: there's no way to # cleanly interrupt it if it blocks the - # CouplerThread forever (we can Thread.interrupt() - # its CouplerThread but that closes stdin's Channel) + # _CouplerThread forever (we can Thread.interrupt() + # its _CouplerThread but that closes stdin's + # Channel) pass else: self._stdin_thread = self._coupler_thread('stdin', @@ -1128,8 +1130,8 @@ def _coupler_thread(self, *args, **kwargs): - """Return a CouplerThread""" - return CouplerThread(*args, **kwargs) + """Return a _CouplerThread""" + return _CouplerThread(*args, **kwargs) def _setup_env(self, env, builder_env): @@ -1174,10 +1176,10 @@ # posix. Windows passes unicode through however if not isinstance(arg, (str, unicode)): raise TypeError('args must contain only strings') - args = escape_args(args) + args = _escape_args(args) if shell: - args = shell_command + args + args = _shell_command + args if executable is not None: args[0] = executable @@ -1200,8 +1202,8 @@ builder.directory(java.io.File(cwd)) # Let Java manage redirection of stderr to stdout (it's more - # accurate at doing so than CouplerThreads). We redirect not - # only when stderr is marked as STDOUT, but also when + # accurate at doing so than _CouplerThreads). We redirect + # not only when stderr is marked as STDOUT, but also when # c2pwrite is errwrite if self._stderr_is_stdout(errwrite, c2pwrite): builder.redirectErrorStream(True) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-23 20:33:33
|
Revision: 6371 http://jython.svn.sourceforge.net/jython/?rev=6371&view=rev Author: pjenvey Date: 2009-05-23 20:33:14 +0000 (Sat, 23 May 2009) Log Message: ----------- was catching potential IllegalArgumentExceptions in the wrong place Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-05-23 20:01:52 UTC (rev 6370) +++ trunk/jython/Lib/subprocess.py 2009-05-23 20:33:14 UTC (rev 6371) @@ -1170,12 +1170,11 @@ args = [args] else: args = list(args) - for arg in args: - # XXX: CPython posix (execv) will str() any unicode - # args first, maybe we should do the same on - # posix. Windows passes unicode through however - if not isinstance(arg, (str, unicode)): - raise TypeError('args must contain only strings') + # NOTE: CPython posix (execv) will str() any unicode + # args first, maybe we should do the same on + # posix. Windows passes unicode through, however + if any(not isinstance(arg, (str, unicode)) for arg in args): + raise TypeError('args must contain only strings') args = _escape_args(args) if shell: @@ -1184,11 +1183,7 @@ if executable is not None: args[0] = executable - try: - builder = java.lang.ProcessBuilder(args) - except java.lang.IllegalArgumentException, iae: - raise OSError(iae.getMessage() or iae) - + builder = java.lang.ProcessBuilder(args) # os.environ may be inherited for compatibility with CPython self._setup_env(dict(os.environ if env is None else env), builder.environment()) @@ -1210,8 +1205,9 @@ try: self._process = builder.start() - except java.io.IOException, ioe: - raise OSError(ioe.getMessage() or ioe) + except (java.io.IOException, + java.lang.IllegalArgumentException), e: + raise OSError(e.getMessage() or e) self._child_created = True This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-05-27 06:44:08
|
Revision: 6395 http://jython.svn.sourceforge.net/jython/?rev=6395&view=rev Author: pjenvey Date: 2009-05-27 06:44:07 +0000 (Wed, 27 May 2009) Log Message: ----------- poll should set returncode if the process terminated Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-05-27 03:29:59 UTC (rev 6394) +++ trunk/jython/Lib/subprocess.py 2009-05-27 06:44:07 UTC (rev 6395) @@ -1275,7 +1275,7 @@ attribute.""" if self.returncode is None: try: - return self._process.exitValue() + self.returncode = self._process.exitValue() except java.lang.IllegalThreadStateException: pass return self.returncode This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-05-29 09:44:28
|
Revision: 6422 http://jython.svn.sourceforge.net/jython/?rev=6422&view=rev Author: otmarhumbel Date: 2009-05-29 09:44:21 +0000 (Fri, 29 May 2009) Log Message: ----------- fix subprocess.test_executable() in the java -jar case Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-05-29 05:28:56 UTC (rev 6421) +++ trunk/jython/Lib/subprocess.py 2009-05-29 09:44:21 UTC (rev 6422) @@ -1244,6 +1244,8 @@ if executable is not None: args[0] = executable + if '.jar' == executable[-4:]: + args = ['java', '-jar'] + args builder = java.lang.ProcessBuilder(args) # os.environ may be inherited for compatibility with CPython This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-06-02 08:23:29
|
Revision: 6439 http://jython.svn.sourceforge.net/jython/?rev=6439&view=rev Author: otmarhumbel Date: 2009-06-02 08:23:27 +0000 (Tue, 02 Jun 2009) Log Message: ----------- - restrict jar sys.executable to our own jython.jar - pass the following tests in the java -jar case: test_subprocess, test_subprocess_jy, test_popen, test_popen2 Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-06-02 08:23:00 UTC (rev 6438) +++ trunk/jython/Lib/subprocess.py 2009-06-02 08:23:27 UTC (rev 6439) @@ -1236,16 +1236,21 @@ raise TypeError('args must contain only strings') args = _escape_args(args) - if len(args) > 0 and '.jar' == args[0][-4:] and executable is None: - args = ['java', '-jar'] + args + if len(args) > 0 and self.isJarExecutable(args[0]) and executable is None: + args = self.prefixJarExecutable(args) if shell: + if len(args) == 1: + splittedArgs = args[0].split(' ') + # TODO:Oti breaks if path to jython.jar contains spaces + if self.isJarExecutable(splittedArgs[0]): + args = self.prefixJarExecutable(args, single=True) args = _shell_command + args if executable is not None: args[0] = executable - if '.jar' == executable[-4:]: - args = ['java', '-jar'] + args + if self.isJarExecutable(args[0]): + args = self.prefixJarExecutable(args) builder = java.lang.ProcessBuilder(args) # os.environ may be inherited for compatibility with CPython @@ -1274,7 +1279,19 @@ raise OSError(e.getMessage() or e) self._child_created = True + def isJarExecutable(self, argument): + """returns true if argument is a path to jython.jar""" + return 'jython.jar' == argument[-10:] + def prefixJarExecutable(self, args, single=False): + """prepend java -jar to args + if single is True, args list is assumed to consit of one single element only""" + if not single: + args = ['java', '-jar'] + args + else: + args[0] = 'java -jar ' + args[0] + return args + def poll(self, _deadstate=None): """Check if child process has terminated. Returns returncode attribute.""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-06-06 02:05:55
|
Revision: 6454 http://jython.svn.sourceforge.net/jython/?rev=6454&view=rev Author: pjenvey Date: 2009-06-06 02:05:42 +0000 (Sat, 06 Jun 2009) Log Message: ----------- fix the jython.jar workaround when it contains spaces Modified Paths: -------------- trunk/jython/Lib/subprocess.py Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-06-06 01:09:38 UTC (rev 6453) +++ trunk/jython/Lib/subprocess.py 2009-06-06 02:05:42 UTC (rev 6454) @@ -547,7 +547,9 @@ # Parse command line arguments for Windows _win_oses = ['nt'] + _JYTHON_JAR = 'jython.jar' _cmdline2list = None + _forcecmdline2list = None _escape_args = None _shell_command = None @@ -611,13 +613,19 @@ """Setup the shell command and the command line argument escape function depending on the underlying platform """ - global _cmdline2list, _escape_args, _shell_command + global _cmdline2list, _forcecmdline2list, _escape_args, _shell_command if os._name in _win_oses: - _cmdline2list = cmdline2list + _cmdline2list = _forcecmdline2list = cmdline2list _escape_args = lambda args: [list2cmdline([arg]) for arg in args] else: - _cmdline2list = lambda args: [args] + _cmdline2list = lambda arg: [arg] + def _forcecmdline2list(arg): + import shlex + try: + return shlex.split(arg) + except ValueError: + return [arg] _escape_args = lambda args: args os_info = os._os_map.get(os._name) @@ -1217,6 +1225,28 @@ builder_env.putAll(merge_env) + def _should_run_jar(self, args): + """Determine if command should be run via jar -jar. + + When running the standalone Jython jar without the official + command line script runner (e.g. java -jar jython.jar) + sys.executable cannot be determined, so Jython sets it to + the path to jython.jar. + + This detects when a subprocess command executable is that + special sys.executable value. + """ + if not sys.executable or not sys.executable.endswith(_JYTHON_JAR): + # Not applicable + return False + + args = (_forcecmdline2list(args) + if isinstance(args, types.StringTypes) else list(args)) + if not args: + return False + return args[0] == sys.executable + + def _execute_child(self, args, executable, preexec_fn, close_fds, cwd, env, universal_newlines, startupinfo, creationflags, shell, @@ -1225,7 +1255,10 @@ errread, errwrite): """Execute program (Java version)""" + run_jar = self._should_run_jar(args) if isinstance(args, types.StringTypes): + if run_jar: + args = 'java -jar ' + args args = _cmdline2list(args) else: args = list(args) @@ -1234,23 +1267,15 @@ # posix. Windows passes unicode through, however if any(not isinstance(arg, (str, unicode)) for arg in args): raise TypeError('args must contain only strings') + if run_jar: + args = ['java', '-jar'] + args args = _escape_args(args) - if len(args) > 0 and self.isJarExecutable(args[0]) and executable is None: - args = self.prefixJarExecutable(args) - if shell: - if len(args) == 1: - splittedArgs = args[0].split(' ') - # TODO:Oti breaks if path to jython.jar contains spaces - if self.isJarExecutable(splittedArgs[0]): - args = self.prefixJarExecutable(args, single=True) args = _shell_command + args if executable is not None: args[0] = executable - if self.isJarExecutable(args[0]): - args = self.prefixJarExecutable(args) builder = java.lang.ProcessBuilder(args) # os.environ may be inherited for compatibility with CPython @@ -1279,19 +1304,7 @@ raise OSError(e.getMessage() or e) self._child_created = True - def isJarExecutable(self, argument): - """returns true if argument is a path to jython.jar""" - return 'jython.jar' == argument[-10:] - def prefixJarExecutable(self, args, single=False): - """prepend java -jar to args - if single is True, args list is assumed to consit of one single element only""" - if not single: - args = ['java', '-jar'] + args - else: - args[0] = 'java -jar ' + args[0] - return args - def poll(self, _deadstate=None): """Check if child process has terminated. Returns returncode attribute.""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |