views:

745

answers:

1

I wonder if it possible to not have jython automagicaly transform java objects to python types when you put them in a Java ArrayList.

Example copied from a jython-console:

>>> b = java.lang.Boolean("True");
>>> type(b)
<type 'javainstance'>
>>> isinstance(b, java.lang.Boolean);
1

So far, everything is fine but if I put the object in an ArrayList

>>> l = java.util.ArrayList();
>>> l.add(b)
1
>>> type(l.get(0))
<type 'int'>

the object is transformed into a python-like boolean (i.e. an int) and...

>>> isinstance(l.get(0), java.lang.Boolean)
0

which means that I can no longer see that this was once a java.lang.Boolean.

Clarification

I guess what really want to achieve is to get rid of the implicit conversion from Java-types to Python-types when passing objects from Java to Python. I will give another example for clarification.

A Python module:

import java

import IPythonModule

class PythonModule(IPythonModule):

    def method(self, data):
        print type(data);

And a Java-Class that uses this module:

import java.util.ArrayList;

import org.python.core.PyList;
import org.testng.annotations.*;

import static org.testng.AssertJUnit.*;

public class Test1 {

    IPythonModule m;

    @BeforeClass
    public void setUp() {
     JythonFactory jf = JythonFactory.getInstance();
     m = (IPythonModule) jf.getJythonObject(
       "IPythonModule",
     "/Users/sg/workspace/JythonTests/src/PythonModule.py");
    }

    @Test
    public void testFirst() {
     m.method(new Boolean("true"));
    } 
}

Here I will see the output 'bool' because of the implicit conversion, but what I would really like is to see 'javainstance' or 'java.lang.Boolean'. If you want to run this code you will also need the JythonFactory-class that can be found here.

+1  A: 

You appear to be using an old version of Jython. In current Jython versions, the Python bool type corresponds to a Java Boolean.

Jython is not transforming the Java type to a Python type on the way into the ArrayList - on the contrary, it will transform a primitive Python type to a primitive or wrapper Java type when passing it to a Java method, and a Java type to a Python type on the way out.

You can observe this by printing the contents of the array. Note that the Python bool is capitalized (True); the Java Boolean is not.

>>> from java.lang import Boolean
>>> b = Boolean('True')
>>> b      
true
>>> from java.util import ArrayList
>>> l = ArrayList()
>>> l.add(b)
True
>>> l
[true]
>>> l.add(True)
True
>>> l
[true, true]
>>> list(l) 
[True, True]

If this still doesn't do what you want, consider writing a small Java helper function that examines the array for you without conversion. It's arguably a bug that Jython doesn't automatically convert the Boolean you constructed into a Python bool, and in this case it gives you no advantage over using Boolean.TRUE or the Python True.

Nicholas Riley
Yes I am using the latest stable version, 2.2.1 which does not have support for the python bool type... Downloading 2.5b right now...
Sebastian Ganslandt
>>> b = java.lang.Boolean("true");>>> l = java.util.ArrayList();>>> l.add(b)True>>> type(l.get(0))<type 'bool'>>>> isinstance(l.get(0), java.lang.Boolean)FalseAs far as I can see, conversion still takes place, and it is this conversion that I don't want.
Sebastian Ganslandt
There's actually 2 potential conversions happening here, one going into the array and one coming out. When it's in the ArrayList, you've got a java.lang.Boolean, which you can see because it prints with a lowercase 't'.
Nicholas Riley
Since you can rely on this conversion on the way out, you can use isinstance(l.get(0), bool) or isinstance(l[0], bool).
Nicholas Riley
For sure! : ) The "updating to the latest version"-trick works fine with the bool-types. Next problem is seperate the Java-Floats from the Java-Doubles, which both of course get's converted to pythons 'float'-type... Anyway, thanks for the help this far!
Sebastian Ganslandt