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"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src/main/java"/> <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="src" path="src/example/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="var" path="JYTHON_HOME/jython.jar" sourcepath="/JYTHON_HOME/src"/> <classpathentry kind="var" path="JYTHON_HOME/jython.jar" sourcepath="/JYTHON_HOME/src"/>

View File

@ -2,6 +2,9 @@
<?eclipse-pydev version="1.0"?> <?eclipse-pydev version="1.0"?>
<pydev_project> <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_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> </pydev_project>

View File

@ -8,6 +8,18 @@ import org.junit.Test;
public class DependentTest { 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 Employee Employee_ = JyWrapper.wrap(Employee.class, "person.Employee");
private final Dependent Dependent_ = JyWrapper.wrap(Dependent.class, "person.Dependent"); 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.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import net.abhinavsarkar.jywrapper.JyWrapper; import net.abhinavsarkar.jywrapper.JyWrapper;
import org.junit.Test; import org.junit.Test;
public class EmployeeTest { 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 Employee Employee_ = JyWrapper.wrap(Employee.class, "person.Employee");
private final Dependent Dependent_ = JyWrapper.wrap(Dependent.class, "person.Dependent"); 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 static net.abhinavsarkar.jywrapper.Messages._;
import java.net.URI;
import net.abhinavsarkar.jywrapper.annotation.Wraps; import net.abhinavsarkar.jywrapper.annotation.Wraps;
import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException; import net.abhinavsarkar.jywrapper.exception.PythonImportNotFoundException;
import org.python.core.Py;
import org.python.core.PyClass; import org.python.core.PyClass;
import org.python.core.PyFunction; import org.python.core.PyFunction;
import org.python.core.PyModule; import org.python.core.PyModule;
import org.python.core.PyObject; import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PySystemState;
import org.python.core.PyType; import org.python.core.PyType;
/** /**
@ -89,4 +92,21 @@ public final class JyWrapper {
return newInstance; 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.Py;
import org.python.core.PyException; import org.python.core.PyException;
import org.python.core.PyObject; import org.python.core.PyObject;
import org.python.core.PySystemState;
/** /**
* @author AbhinavSarkar * @author AbhinavSarkar
@ -17,8 +16,8 @@ import org.python.core.PySystemState;
*/ */
public final class PyImportLoader { public final class PyImportLoader {
private static final PyObject importer = new PySystemState().getBuiltins() private static final PyObject importer =
.__getitem__(Py.newString("__import__")); //$NON-NLS-1$ Py.getSystemState().getBuiltins().__getitem__(Py.newString("__import__"));
private static final ConcurrentHashMap<String, PyObject> loadedPyImports = private static final ConcurrentHashMap<String, PyObject> loadedPyImports =
new ConcurrentHashMap<String, PyObject>(); new ConcurrentHashMap<String, PyObject>();
@ -35,7 +34,7 @@ public final class PyImportLoader {
throws PythonImportNotFoundException { throws PythonImportNotFoundException {
if (!loadedPyImports.containsKey(fullImportName)) { if (!loadedPyImports.containsKey(fullImportName)) {
final int i = fullImportName.lastIndexOf('.'); 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; PyObject pyImport;
if (i == -1) { if (i == -1) {
final String pyModuleName = fullImportName; final String pyModuleName = fullImportName;
@ -59,4 +58,5 @@ public final class PyImportLoader {
} }
return loadedPyImports.get(fullImportName); return loadedPyImports.get(fullImportName);
} }
} }

View File

@ -2,6 +2,10 @@ package net.abhinavsarkar.jywrapper;
import static net.abhinavsarkar.jywrapper.Messages._; 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.Py;
import org.python.core.PyClass; import org.python.core.PyClass;
import org.python.core.PyFunction; 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$ 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.13=Can''t set attribute: {0}
JyWrapper.14=Trying to set instance attribute "{0}" in a python class JyWrapper.14=Trying to set instance attribute "{0}" in a python class
JyWrapper.15=No {0} named "{1}" in the backing Python Type {2} 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}