diff --git a/doc/install.rst b/doc/install.rst
index d84382c589..44642ad2f5 100644
--- a/doc/install.rst
+++ b/doc/install.rst
@@ -84,6 +84,10 @@ Another optional parameter
* ``jpy.debug`` - which is either ``true`` or ``false`` can be used to output extra debugging information.
+The optional parameter
+
+* ``jpy.pythonPrefix`` - points to the location of the PYTHONHOME. If set, then jpy will call ``PyLib.setPythonHome()`` with the value of this parameter.
+
All the parameters can be passed directly to the JVM either as Java system properties or by using the single system property
* ``jpy.config`` - which is a path to a Java properties files containing the definitions of the two parameters named above.
@@ -96,7 +100,7 @@ Setting PYTHONHOME
If the environment variable ``PYTHONHOME`` is not set when you call Python from Java, you may get an error about
file system encodings not being found. It is possible to set the location of Python from your
Java program. Use ``PyLib.setPythonHome(pathToPythonHome)`` to do that, where ``pathToPythonHome`` is a ``String`` that
-contains the location of the Python installation.
+contains the location of the Python installation, or as described above, use the parameter ``jpy.pytyhonPrefix``.
========================
Build for Linux / Darwin
diff --git a/jpyutil.py b/jpyutil.py
index 5ab2463f5b..7d080c89d2 100644
--- a/jpyutil.py
+++ b/jpyutil.py
@@ -35,7 +35,7 @@
__author__ = "Norman Fomferra (Brockmann Consult GmbH) and contributors"
__copyright__ = "Copyright 2015-2018 Brockmann Consult GmbH and contributors"
__license__ = "Apache 2.0"
-__version__ = "0.10.0.dev1"
+__version__ = "0.9.1.dev1"
# Uncomment for debugging
diff --git a/pom.xml b/pom.xml
index c3f6fcff30..c587e9d8c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
org.jpy
jpy
- 0.10.0-SNAPSHOT
+ 0.9.1-SNAPSHOT
jar
Java-Python Bridge
@@ -188,4 +188,4 @@
-
\ No newline at end of file
+
diff --git a/src/main/java/org/jpy/PyLib.java b/src/main/java/org/jpy/PyLib.java
index 7c1509c42a..4b3e3ffada 100644
--- a/src/main/java/org/jpy/PyLib.java
+++ b/src/main/java/org/jpy/PyLib.java
@@ -22,7 +22,6 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
-import java.util.Map;
import static org.jpy.PyLibConfig.JPY_LIB_KEY;
import static org.jpy.PyLibConfig.OS;
@@ -204,6 +203,11 @@ public static void startPython(String... extraPaths) {
}
Diag.setFlags(Diag.F_EXEC);
}
+
+ String pythonHome = getProperty(PyLibConfig.JPY_CONFIG_PREFIX, false);
+ if (pythonHome != null) {
+ setPythonHome(pythonHome);
+ }
startPython0(extraPaths);
}
diff --git a/src/main/java/org/jpy/PyLibConfig.java b/src/main/java/org/jpy/PyLibConfig.java
index 3e16e62047..4a82342cec 100644
--- a/src/main/java/org/jpy/PyLibConfig.java
+++ b/src/main/java/org/jpy/PyLibConfig.java
@@ -38,6 +38,7 @@ class PyLibConfig {
public static final String JPY_LIB_KEY = "jpy.jpyLib";
public static final String JPY_CONFIG_KEY = "jpy.config";
public static final String JPY_CONFIG_RESOURCE = "jpyconfig.properties";
+ public static final String JPY_CONFIG_PREFIX = "jpy.pythonPrefix";
public enum OS {
WINDOWS,
diff --git a/src/main/java/org/jpy/PyProxyHandler.java b/src/main/java/org/jpy/PyProxyHandler.java
index 37ee54579e..dbb3f5ced9 100644
--- a/src/main/java/org/jpy/PyProxyHandler.java
+++ b/src/main/java/org/jpy/PyProxyHandler.java
@@ -100,9 +100,36 @@ public Object invoke(Object proxyObject, Method method, Object[] args) throws Th
} else if (method.equals(toStringMethod)) {
methodName = "__str__";
}
+ Class>[] parameterTypes = method.getParameterTypes();
- return PyLib.callAndReturnValue(this.pyObject.getPointer(), callableKind == PyLib.CallableKind.METHOD,
- methodName, args != null ? args.length : 0, args, method.getParameterTypes(), returnType);
+ if (args != null) {
+ for (int i = 0; i < args.length; i++) {
+ Object oneArg = args[i];
+ if (oneArg instanceof Proxy) {
+ PyObject possiblePyObject = proxyGetOtherPyObject(proxyObject, oneArg);
+ if (possiblePyObject != null) {
+ args[i] = possiblePyObject;
+ parameterTypes[i] = Object.class;
+ }
+ }
+ }
+ }
+ boolean returnTypeIsInterface = returnType.isInterface();
+ Class> originalReturnType = returnType;
+ if (returnTypeIsInterface) {
+ returnType = PyObject.class;
+ }
+ Object result = PyLib.callAndReturnValue(this.pyObject.getPointer(),
+ callableKind == PyLib.CallableKind.METHOD,
+ methodName,
+ args != null ? args.length : 0,
+ args,
+ parameterTypes,
+ returnType);
+ if (returnTypeIsInterface) {
+ result = ((PyObject)result).createProxy(originalReturnType);
+ }
+ return result;
}
/**
diff --git a/src/test/java/org/jpy/PyObjectTest.java b/src/test/java/org/jpy/PyObjectTest.java
index fac8db41fa..07fccf88db 100644
--- a/src/test/java/org/jpy/PyObjectTest.java
+++ b/src/test/java/org/jpy/PyObjectTest.java
@@ -8,10 +8,10 @@
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
* This file was modified by Illumon.
*
@@ -128,7 +128,6 @@ public void testExecuteCode_Script() throws Exception {
PyInputMode.SCRIPT, null, localMap);
assertNotNull(pyVoid);
assertEquals(null, pyVoid.getObjectValue());
-
assertNotNull(localMap.get("jpy"));
assertNotNull(localMap.get("File"));
assertNotNull(localMap.get("f"));
@@ -138,29 +137,33 @@ public void testExecuteCode_Script() throws Exception {
assertEquals(new File("test.txt"), localMap.get("f"));
}
-
+
@Test
public void testLocals() throws Exception {
HashMap localMap = new HashMap<>();
localMap.put("x", 7);
localMap.put("y", 6);
- PyObject pyVoid = PyObject.executeCode("z = x + y", PyInputMode.STATEMENT, null, localMap);
+ PyObject pyVoid = PyObject.executeCode("z = x + y",
+ PyInputMode.STATEMENT,
+ null,
+ localMap);
assertEquals(null, pyVoid.getObjectValue());
-
+
System.out.println("LocalMap size = " + localMap.size());
for (Map.Entry entry : localMap.entrySet()) {
System.out.println("LocalMap[" + entry.getKey() + "]: " + entry.getValue());
}
-
+
assertNotNull(localMap.get("x"));
assertNotNull(localMap.get("y"));
assertNotNull(localMap.get("z"));
-
+
assertEquals(7, localMap.get("x"));
assertEquals(6, localMap.get("y"));
assertEquals(13, localMap.get("z"));
+
}
-
+
@Test
public void testExecuteScript_ErrorExpr() throws Exception {
try {
@@ -209,7 +212,7 @@ public void testGetSetAttributes() throws Exception {
PyObject a = myobj.getAttribute("a");
Assert.assertEquals("Tut tut!", a.getStringValue());
}
-
+
private boolean hasKey(Map dict, String key) {
for (Map.Entry entry : dict.entrySet()) {
if (entry.getKey().isString()) {
@@ -220,22 +223,22 @@ private boolean hasKey(Map dict, String key) {
}
return false;
}
-
+
@Test
public void testDictCopy() throws Exception {
PyObject globals = PyLib.getMainGlobals();
PyDictWrapper dict = globals.asDict();
PyDictWrapper dictCopy = dict.copy();
-
+
PyObject.executeCode("x = 42", PyInputMode.STATEMENT, globals, dictCopy.unwrap());
-
+
boolean copyHasX = hasKey(dictCopy, "x");
boolean origHasX = hasKey(dict, "x");
-
+
assertTrue(copyHasX);
assertFalse(origHasX);
}
-
+
@Test
public void testCreateProxyAndCallSingleThreaded() throws Exception {
// addTestDirToPythonSysPath();
@@ -349,6 +352,7 @@ public String call() throws Exception {
private static interface ISimple {
public int getValue();
+ public ISimple add(ISimple other);
}
private static ISimple newTestObj(PyModule pyModule, String pythonClass, int value) {
@@ -375,5 +379,10 @@ private static void testOneClass(PyModule pyModule, String pythonClass, boolean
assertEquals(eqRes, eqResExpected);
assertEquals(simple.hashCode() == simple2.hashCode(), eqResExpected);
assertEquals(simple.equals(simple), true);
+ ISimple sum = simple.add(simple2);
+ assertEquals(sum.getValue(), 2468);
+ ISimple simple3 = newTestObj(pyModule, pythonClass, 5678);
+ sum = simple.add(simple3);
+ assertEquals(sum.getValue(), 1234 + 5678);
}
}
diff --git a/src/test/python/fixtures/hasheqstr.py b/src/test/python/fixtures/hasheqstr.py
index 59ef87da25..afa857818d 100644
--- a/src/test/python/fixtures/hasheqstr.py
+++ b/src/test/python/fixtures/hasheqstr.py
@@ -7,7 +7,13 @@ def __str__(self):
def getValue(self):
return self._v
-
+
+ def add(self, other):
+ if isinstance(other, self.__class__):
+ return Simple(self._v + other._v)
+ else:
+ return self
+
class HashSimple(object):
def __init__(self, v):
self._v = v
@@ -27,3 +33,8 @@ def __eq__(self, other):
else:
return False # Java can't support NotImplemented
+ def add(self, other):
+ if isinstance(other, self.__class__):
+ return HashSimple(self._v + other._v)
+ else:
+ return self
\ No newline at end of file