Skip to content
This repository was archived by the owner on Aug 5, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion doc/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion jpyutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

<groupId>org.jpy</groupId>
<artifactId>jpy</artifactId>
<version>0.10.0-SNAPSHOT</version>
<version>0.9.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Java-Python Bridge</name>

Expand Down Expand Up @@ -188,4 +188,4 @@
</snapshotRepository>
</distributionManagement>

</project>
</project>
6 changes: 5 additions & 1 deletion src/main/java/org/jpy/PyLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/jpy/PyLibConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
31 changes: 29 additions & 2 deletions src/main/java/org/jpy/PyProxyHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down
43 changes: 26 additions & 17 deletions src/test/java/org/jpy/PyObjectTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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"));
Expand All @@ -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<String, Object> 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<String, Object> 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 {
Expand Down Expand Up @@ -209,7 +212,7 @@ public void testGetSetAttributes() throws Exception {
PyObject a = myobj.getAttribute("a");
Assert.assertEquals("Tut tut!", a.getStringValue());
}

private boolean hasKey(Map<PyObject, PyObject> dict, String key) {
for (Map.Entry<PyObject, PyObject> entry : dict.entrySet()) {
if (entry.getKey().isString()) {
Expand All @@ -220,22 +223,22 @@ private boolean hasKey(Map<PyObject, PyObject> 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();
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
}
}
13 changes: 12 additions & 1 deletion src/test/python/fixtures/hasheqstr.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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