Added support for importing Python modules from paths other than Java Classpath.

master
Abhinav Sarkar 2009-10-31 15:32:06 +05:30
parent 6ef5078412
commit 906e5222f3
9 changed files with 103 additions and 22 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/main/java"/>
<classpathentry excluding="src/example/java/|src/main/java/" including="Lib/" kind="src" path=""/>
<classpathentry kind="src" path="src/example/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="JYTHON_HOME/jython.jar" sourcepath="/JYTHON_HOME/src"/>

View File

@ -2,6 +2,9 @@
<?eclipse-pydev version="1.0"?>
<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.6</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">jython 2.5</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/jywrapper/Lib</path>
</pydev_pathproperty>
</pydev_project>

View File

@ -8,6 +8,18 @@ import org.junit.Test;
public class DependentTest {
private static final String PYLIB_DIR_NAME = "Lib";
static {
try {
JyWrapper.addToPythonPath(
DependentTest.class.getClassLoader()
.getResource(PYLIB_DIR_NAME).toURI());
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private final Employee Employee_ = JyWrapper.wrap(Employee.class, "person.Employee");
private final Dependent Dependent_ = JyWrapper.wrap(Dependent.class, "person.Dependent");

View File

@ -3,12 +3,25 @@ package net.abhinavsarkar.jywrapper.example;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import net.abhinavsarkar.jywrapper.JyWrapper;
import org.junit.Test;
public class EmployeeTest {
private static final String PYLIB_DIR_NAME = "Lib";
static {
try {
JyWrapper.addToPythonPath(
DependentTest.class.getClassLoader()
.getResource(PYLIB_DIR_NAME).toURI());
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private final Employee Employee_ = JyWrapper.wrap(Employee.class, "person.Employee");
private final Dependent Dependent_ = JyWrapper.wrap(Dependent.class, "person.Dependent");

View File

@ -2,14 +2,17 @@ package net.abhinavsarkar.jywrapper;
import static net.abhinavsarkar.jywrapper.Messages._;
import java.net.URI;
import net.abhinavsarkar.jywrapper.annotation.Wraps;
import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException;
import org.python.core.Py;
import org.python.core.PyClass;
import org.python.core.PyFunction;
import org.python.core.PyModule;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PySystemState;
import org.python.core.PyType;
/**
@ -89,4 +92,21 @@ public final class JyWrapper {
return newInstance;
}
public static void addToPythonPath(final URI path) {
final PySystemState pySystemState = Py.getSystemState();
final PyString resolvedPath = Util.resolvePath(path);
if (resolvedPath != null && !pySystemState.path.contains(resolvedPath)) {
pySystemState.path.append(resolvedPath);
}
}
public static void removeFromPythonPath(final URI path) {
final PySystemState pySystemState = Py.getSystemState();
final PyString resolvedPath = Util.resolvePath(path);
if (resolvedPath != null && pySystemState.path.contains(resolvedPath)) {
pySystemState.path.remove(resolvedPath);
}
}
}

View File

@ -9,7 +9,6 @@ import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException;
import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyObject;
import org.python.core.PySystemState;
/**
* @author AbhinavSarkar
@ -17,8 +16,8 @@ import org.python.core.PySystemState;
*/
public final class PyImportLoader {
private static final PyObject importer = new PySystemState().getBuiltins()
.__getitem__(Py.newString("__import__")); //$NON-NLS-1$
private static final PyObject importer =
Py.getSystemState().getBuiltins().__getitem__(Py.newString("__import__"));
private static final ConcurrentHashMap<String, PyObject> loadedPyImports =
new ConcurrentHashMap<String, PyObject>();
@ -35,7 +34,7 @@ public final class PyImportLoader {
throws PythonImportNotFoundException {
if (!loadedPyImports.containsKey(fullImportName)) {
final int i = fullImportName.lastIndexOf('.');
final String errorMsg = _("PyImportLoader.1", fullImportName); //$NON-NLS-1$
final String errorMsg = _("PyImportLoader.1", fullImportName, Py.getSystemState().path); //$NON-NLS-1$
PyObject pyImport;
if (i == -1) {
final String pyModuleName = fullImportName;
@ -59,4 +58,5 @@ public final class PyImportLoader {
}
return loadedPyImports.get(fullImportName);
}
}

View File

@ -2,6 +2,10 @@ package net.abhinavsarkar.jywrapper;
import static net.abhinavsarkar.jywrapper.Messages._;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import org.python.core.Py;
import org.python.core.PyClass;
import org.python.core.PyFunction;
@ -83,4 +87,32 @@ final class Util {
return word.replaceAll("([A-Z])", "_$1").toLowerCase(); //$NON-NLS-1$ //$NON-NLS-2$
}
static PyString resolvePath(final URI pythonPath) {
PyString resolvedPath = null;
if (pythonPath.getScheme().equals("jar")) {
final String schemeSpecificPart = pythonPath.getSchemeSpecificPart();
final int lastIndexOf = schemeSpecificPart.lastIndexOf("!");
final String jarPath = schemeSpecificPart.substring(5, lastIndexOf);
final File file = new File(jarPath);
if (file.exists()) {
try {
resolvedPath = Py.newString(file.getCanonicalPath()
+ schemeSpecificPart.substring(lastIndexOf + 1));
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
} else if (pythonPath.getScheme().equals("file")) {
final File file = new File(pythonPath);
if (file.exists()) {
try {
resolvedPath = Py.newString(file.getCanonicalPath());
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
}
return resolvedPath;
}
}

View File

@ -14,4 +14,4 @@ JyWrapper.12=Trying to get instance attribute "{0}" from a Python Type
JyWrapper.13=Can''t set attribute: {0}
JyWrapper.14=Trying to set instance attribute "{0}" in a python class
JyWrapper.15=No {0} named "{1}" in the backing Python Type {2}
PyImportLoader.1=Python Import "{0}" not found in pythonpath
PyImportLoader.1=Python Import "{0}" not found in pythonpath {1}