[Jython-checkins] jython: Moved getJarFileName() to public API and solved Issue 2386.
stefan.richthofer
jython-checkins at python.org
Thu Sep 3 14:43:24 CEST 2015
https://hg.python.org/jython/rev/9bb29fb686d2
changeset: 7719:9bb29fb686d2
user: Stefan Richthofer <stefan.richthofer at gmx.de>
date: Thu Sep 03 14:42:46 2015 +0200
summary:
Moved getJarFileName() to public API and solved Issue 2386.
files:
Lib/distutils/sysconfig.py | 16 +-
lib-python/2.7/distutils/command/build.py | 6 +-
src/org/python/core/Py.java | 155 +++++++++-
src/org/python/core/PySystemState.java | 66 +----
tests/java/org/python/core/PySystemStateTest.java | 20 +-
5 files changed, 181 insertions(+), 82 deletions(-)
diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py
--- a/Lib/distutils/sysconfig.py
+++ b/Lib/distutils/sysconfig.py
@@ -15,6 +15,7 @@
import re
import string
import sys
+from org.python.core import Py
from distutils.errors import DistutilsPlatformError
@@ -25,7 +26,14 @@
# Path to the base directory of the project. On Windows the binary may
# live in project/PCBuild9. If we're dealing with an x64 Windows build,
# it'll live in project/PCbuild/amd64.
-project_base = os.path.dirname(os.path.realpath(sys.executable))
+
+def getJythonBinDir():
+ if not sys.executable is None:
+ return os.path.dirname(os.path.realpath(sys.executable))
+ else:
+ return Py.getDefaultBinDir()
+
+project_base = getJythonBinDir()
if os.name == "nt" and "pcbuild" in project_base[-8:].lower():
project_base = os.path.abspath(os.path.join(project_base, os.path.pardir))
# PC/VS7.1
@@ -74,7 +82,7 @@
if os.name == "posix":
if python_build:
- buildir = os.path.dirname(os.path.realpath(sys.executable))
+ buildir = getJythonBinDir()
if plat_specific:
# python.h is located in the buildir
inc_dir = buildir
@@ -222,7 +230,7 @@
def get_makefile_filename():
"""Return full pathname of installed Makefile from the Python build."""
if python_build:
- return os.path.join(os.path.dirname(os.path.realpath(sys.executable)),
+ return os.path.join(getJythonBinDir(),
"Makefile")
lib_dir = get_python_lib(plat_specific=1, standard_lib=1)
return os.path.join(lib_dir, "config", "Makefile")
@@ -460,7 +468,7 @@
g['SO'] = '.pyd'
g['EXE'] = ".exe"
g['VERSION'] = get_python_version().replace(".", "")
- g['BINDIR'] = os.path.dirname(os.path.realpath(sys.executable))
+ g['BINDIR'] = getJythonBinDir()
global _config_vars
_config_vars = g
diff --git a/lib-python/2.7/distutils/command/build.py b/lib-python/2.7/distutils/command/build.py
--- a/lib-python/2.7/distutils/command/build.py
+++ b/lib-python/2.7/distutils/command/build.py
@@ -115,7 +115,11 @@
'scripts-' + sys.version[0:3])
if self.executable is None:
- self.executable = os.path.normpath(sys.executable)
+ if not sys.executable is None:
+ self.executable = os.path.normpath(sys.executable)
+ else:
+ from org.python.core import Py
+ self.executable = Py.getDefaultExecutableName()
def run(self):
# Run all relevant sub-commands. This will be some subset of:
diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java
--- a/src/org/python/core/Py.java
+++ b/src/org/python/core/Py.java
@@ -15,6 +15,8 @@
import java.io.StreamCorruptedException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLDecoder;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
@@ -29,8 +31,8 @@
import jnr.constants.platform.Errno;
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
+import jnr.posix.util.Platform;
-import jnr.posix.util.Platform;
import org.python.antlr.base.mod;
import org.python.core.adapter.ClassicPyObjectAdapter;
import org.python.core.adapter.ExtensiblePyObjectAdapter;
@@ -2301,6 +2303,155 @@
}
return objs.toArray(Py.EmptyObjects);
}
+
+ /**
+ * Infers the usual Jython executable name from the position of the
+ * jar-file returned by {@link #getJarFileName()} by replacing the
+ * file name with "bin/jython". This is intended as an easy fallback
+ * for cases where {@code sys.executable} is {@code None} due to
+ * direct launching via the java executable.<br>
+ * Note that this does not necessarily return the actual executable,
+ * but instead infers the place where it is usually expected to be.
+ * Use {@code sys.executable} to get the actual executable (may be
+ * {@code None}.
+ *
+ * In contrast to {@link #getJarFileName()} and
+ * {@link #getJarFileNameFromURL(java.net.URL)} this method returns
+ * the path using system-specific separator characters.
+ *
+ * @return usual Jython-executable as absolute path
+ */
+ public static String getDefaultExecutableName() {
+ return getDefaultBinDir()+File.separator+(
+ Platform.IS_WINDOWS ? "jython.exe" : "jython");
+ }
+
+ /**
+ * Infers the usual Jython bin-dir from the position of the jar-file
+ * returned by {@link #getJarFileName()} byr replacing the file name
+ * with "bin". This is intended as an easy fallback for cases where
+ * {@code sys.executable} is {@code null} due to direct launching via
+ * the java executable.<br>
+ * Note that this does not necessarily return the actual bin-directory,
+ * but instead infers the place where it is usually expected to be.
+ *
+ * In contrast to {@link #getJarFileName()} and
+ * {@link #getJarFileNameFromURL(java.net.URL)} this method returns
+ * the path using system-specific separator characters.
+ *
+ * @return usual Jython bin-dir as absolute path
+ */
+ public static String getDefaultBinDir() {
+ String jar = _getJarFileName();
+ if (File.separatorChar != '/') {
+ jar = jar.replace('/', File.separatorChar);
+ }
+ int start = 0;
+ if (Platform.IS_WINDOWS && jar.startsWith(File.separator)) {
+ ++start;
+ }
+ return jar.substring(start, jar.lastIndexOf(File.separatorChar)+1)+"bin";
+ }
+
+ /**
+ * Utility-method to obtain the name (including absolute path) of the currently used
+ * jython-jar-file. Usually this is jython.jar, but can also be jython-dev.jar or
+ * jython-standalone.jar or something custom.
+ *
+ * @return the full name of the jar file containing this class, <code>null</code>
+ * if not available.
+ */
+ public static String getJarFileName() {
+ String jar = _getJarFileName();
+ if (File.separatorChar != '/') {
+ jar = jar.replace('/', File.separatorChar);
+ }
+ int start = 0;
+ if (Platform.IS_WINDOWS && jar.startsWith(File.separator)) {
+ ++start;
+ }
+ return jar.substring(start);
+ }
+
+ /**
+ * Utility-method to obtain the name (including absolute path) of the currently used
+ * jython-jar-file. Usually this is jython.jar, but can also be jython-dev.jar or
+ * jython-standalone.jar or something custom.
+ *
+ * Note that it does not use system-specific seperator-chars, but always
+ * '/'. Also, on windows it might prepend a '/' before the drive-letter. (Is this a bug?)
+ *
+ * @return the full name of the jar file containing this class, <code>null</code>
+ * if not available.
+ */
+ protected static String _getJarFileName() {
+ Class<Py> thisClass = Py.class;
+ String fullClassName = thisClass.getName();
+ String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
+ URL url = thisClass.getResource(className + ".class");
+ return getJarFileNameFromURL(url);
+ }
+
+ /**exclusively used by {@link #getJarFileNameFromURL(java.net.URL)}.*/
+ private static final String JAR_URL_PREFIX = "jar:file:";
+ /**exclusively used by {@link #getJarFileNameFromURL(java.net.URL)}.*/
+ private static final String JAR_SEPARATOR = "!";
+ /**exclusively used by {@link #getJarFileNameFromURL(java.net.URL)}.*/
+ private static final String VFSZIP_PREFIX = "vfszip:";
+ /**exclusively used by {@link #getJarFileNameFromURL(java.net.URL)}.*/
+ private static final String VFS_PREFIX = "vfs:";
+
+ /**
+ * Converts a url that points to a jar-file to the actual jar-file name.
+ * Note that it does not use system-specific seperator-chars, but always
+ * '/'. Also, on windows it might prepend a '/' before the drive-letter.
+ */
+ public static String getJarFileNameFromURL(URL url) {
+ String jarFileName = null;
+ if (url != null) {
+ try {
+ // escape plus signs, since the URLDecoder would turn them into spaces
+ final String plus = "\\+";
+ final String escapedPlus = "__ppluss__";
+ String rawUrl = url.toString();
+ rawUrl = rawUrl.replaceAll(plus, escapedPlus);
+ String urlString = URLDecoder.decode(rawUrl, "UTF-8");
+ urlString = urlString.replaceAll(escapedPlus, plus);
+ int jarSeparatorIndex = urlString.lastIndexOf(JAR_SEPARATOR);
+ if (urlString.startsWith(JAR_URL_PREFIX) && jarSeparatorIndex > 0) {
+ // jar:file:/install_dir/jython.jar!/org/python/core/PySystemState.class
+ jarFileName = urlString.substring(JAR_URL_PREFIX.length(), jarSeparatorIndex);
+ } else if (urlString.startsWith(VFSZIP_PREFIX)) {
+ // vfszip:/some/path/jython.jar/org/python/core/PySystemState.class
+ final String path = Py.class.getName().replace('.', '/');
+ int jarIndex = urlString.indexOf(".jar/".concat(path));
+ if (jarIndex > 0) {
+ jarIndex += 4;
+ int start = VFSZIP_PREFIX.length();
+ if (Platform.IS_WINDOWS) {
+ // vfszip:/C:/some/path/jython.jar/org/python/core/PySystemState.class
+ start++;
+ }
+ jarFileName = urlString.substring(start, jarIndex);
+ }
+ } else if (urlString.startsWith(VFS_PREFIX)) {
+ // vfs:/some/path/jython.jar/org/python/core/PySystemState.class
+ final String path = Py.class.getName().replace('.', '/');
+ int jarIndex = urlString.indexOf(".jar/".concat(path));
+ if (jarIndex > 0) {
+ jarIndex += 4;
+ int start = VFS_PREFIX.length();
+ if (Platform.IS_WINDOWS) {
+ // vfs:/C:/some/path/jython.jar/org/python/core/PySystemState.class
+ start++;
+ }
+ jarFileName = urlString.substring(start, jarIndex);
+ }
+ }
+ } catch (Exception e) {}
+ }
+ return jarFileName;
+ }
}
class FixedFileWrapper extends StdoutWrapper {
@@ -2407,7 +2558,7 @@
}
/**
- * A function object wrapper for a java method which comply with the
+ * A function object wrapper for a java method that complies with the
* PyArgsKeywordsCall standard.
*/
@Untraversable
diff --git a/src/org/python/core/PySystemState.java b/src/org/python/core/PySystemState.java
--- a/src/org/python/core/PySystemState.java
+++ b/src/org/python/core/PySystemState.java
@@ -64,11 +64,6 @@
public static final String JYTHON_JAR = "jython.jar";
public static final String JYTHON_DEV_JAR = "jython-dev.jar";
- private static final String JAR_URL_PREFIX = "jar:file:";
- private static final String JAR_SEPARATOR = "!";
- private static final String VFSZIP_PREFIX = "vfszip:";
- private static final String VFS_PREFIX = "vfs:";
-
public static final PyString version = new PyString(Version.getVersion());
public static final PyTuple subversion = new PyTuple(new PyString("Jython"), Py.newString(""),
@@ -1036,7 +1031,7 @@
initialized = true;
Py.setAdapter(adapter);
boolean standalone = false;
- String jarFileName = getJarFileName();
+ String jarFileName = Py._getJarFileName();
if (jarFileName != null) {
standalone = isStandalone(jarFileName);
}
@@ -1343,65 +1338,6 @@
return standalone;
}
- /**
- * @return the full name of the jar file containing this class, <code>null</code> if not
- * available.
- */
- private static String getJarFileName() {
- Class<PySystemState> thisClass = PySystemState.class;
- String fullClassName = thisClass.getName();
- String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
- URL url = thisClass.getResource(className + ".class");
- return getJarFileNameFromURL(url);
- }
-
- protected static String getJarFileNameFromURL(URL url) {
- String jarFileName = null;
- if (url != null) {
- try {
- // escape plus signs, since the URLDecoder would turn them into spaces
- final String plus = "\\+";
- final String escapedPlus = "__ppluss__";
- String rawUrl = url.toString();
- rawUrl = rawUrl.replaceAll(plus, escapedPlus);
- String urlString = URLDecoder.decode(rawUrl, "UTF-8");
- urlString = urlString.replaceAll(escapedPlus, plus);
- int jarSeparatorIndex = urlString.lastIndexOf(JAR_SEPARATOR);
- if (urlString.startsWith(JAR_URL_PREFIX) && jarSeparatorIndex > 0) {
- // jar:file:/install_dir/jython.jar!/org/python/core/PySystemState.class
- jarFileName = urlString.substring(JAR_URL_PREFIX.length(), jarSeparatorIndex);
- } else if (urlString.startsWith(VFSZIP_PREFIX)) {
- // vfszip:/some/path/jython.jar/org/python/core/PySystemState.class
- final String path = PySystemState.class.getName().replace('.', '/');
- int jarIndex = urlString.indexOf(".jar/".concat(path));
- if (jarIndex > 0) {
- jarIndex += 4;
- int start = VFSZIP_PREFIX.length();
- if (Platform.IS_WINDOWS) {
- // vfszip:/C:/some/path/jython.jar/org/python/core/PySystemState.class
- start++;
- }
- jarFileName = urlString.substring(start, jarIndex);
- }
- } else if (urlString.startsWith(VFS_PREFIX)) {
- // vfs:/some/path/jython.jar/org/python/core/PySystemState.class
- final String path = PySystemState.class.getName().replace('.', '/');
- int jarIndex = urlString.indexOf(".jar/".concat(path));
- if (jarIndex > 0) {
- jarIndex += 4;
- int start = VFS_PREFIX.length();
- if (Platform.IS_WINDOWS) {
- // vfs:/C:/some/path/jython.jar/org/python/core/PySystemState.class
- start++;
- }
- jarFileName = urlString.substring(start, jarIndex);
- }
- }
- } catch (Exception e) {}
- }
- return jarFileName;
- }
-
private static void addPaths(PyList path, String pypath) {
StringTokenizer tok = new StringTokenizer(pypath, java.io.File.pathSeparator);
while (tok.hasMoreTokens()) {
diff --git a/tests/java/org/python/core/PySystemStateTest.java b/tests/java/org/python/core/PySystemStateTest.java
--- a/tests/java/org/python/core/PySystemStateTest.java
+++ b/tests/java/org/python/core/PySystemStateTest.java
@@ -13,19 +13,19 @@
public void testGetJarFileNameFromURL() throws Exception {
// null
- assertNull(PySystemState.getJarFileNameFromURL(null));
+ assertNull(Py.getJarFileNameFromURL(null));
// plain jar url
String urlString = "jar:file:/some_dir/some.jar!/a/package/with/A.class";
URL url = new URL(urlString);
- assertEquals("/some_dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("/some_dir/some.jar", Py.getJarFileNameFromURL(url));
// jar url to decode
urlString = "jar:file:/some%20dir/some.jar!/a/package/with/A.class";
url = new URL(urlString);
- assertEquals("/some dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("/some dir/some.jar", Py.getJarFileNameFromURL(url));
// jar url with + signs to escape
urlString = "jar:file:/some+dir/some.jar!/a/package/with/A.class";
url = new URL(urlString);
- assertEquals("/some+dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("/some+dir/some.jar", Py.getJarFileNameFromURL(url));
}
public void testGetJarFileNameFromURL_jboss() throws Exception {
@@ -41,33 +41,33 @@
url = new URL(protocol, host, port, file, handler);
// tests with jboss on windows gave URL's like this:
assertEquals("vfszip:/C:/some_dir/some.jar/org/python/core/PySystemState.class", url.toString());
- assertEquals("C:/some_dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("C:/some_dir/some.jar", Py.getJarFileNameFromURL(url));
// jboss url to decode
file = "/C:/some%20dir/some.jar/org/python/core/PySystemState.class";
url = new URL(protocol, host, port, file, handler);
assertEquals("vfszip:/C:/some%20dir/some.jar/org/python/core/PySystemState.class", url.toString());
- assertEquals("C:/some dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("C:/some dir/some.jar", Py.getJarFileNameFromURL(url));
// jboss url with + to escape
file = "/C:/some+dir/some.jar/org/python/core/PySystemState.class";
url = new URL(protocol, host, port, file, handler);
assertEquals("vfszip:/C:/some+dir/some.jar/org/python/core/PySystemState.class", url.toString());
- assertEquals("C:/some+dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("C:/some+dir/some.jar", Py.getJarFileNameFromURL(url));
} else {
// plain jboss url
file = "/some_dir/some.jar/org/python/core/PySystemState.class";
url = new URL(protocol, host, port, file, handler);
assertEquals("vfszip:/some_dir/some.jar/org/python/core/PySystemState.class", url.toString());
- assertEquals("/some_dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("/some_dir/some.jar", Py.getJarFileNameFromURL(url));
// jboss url to decode
file = "/some%20dir/some.jar/org/python/core/PySystemState.class";
url = new URL(protocol, host, port, file, handler);
assertEquals("vfszip:/some%20dir/some.jar/org/python/core/PySystemState.class", url.toString());
- assertEquals("/some dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("/some dir/some.jar", Py.getJarFileNameFromURL(url));
// jboss url with + to escape
file = "/some+dir/some.jar/org/python/core/PySystemState.class";
url = new URL(protocol, host, port, file, handler);
assertEquals("vfszip:/some+dir/some.jar/org/python/core/PySystemState.class", url.toString());
- assertEquals("/some+dir/some.jar", PySystemState.getJarFileNameFromURL(url));
+ assertEquals("/some+dir/some.jar", Py.getJarFileNameFromURL(url));
}
}
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list