From: Samuele P. <pe...@in...> - 2002-08-12 15:26:48
|
From: Chris Atkins <Chr...@al...> > I have a jython class which derives from junit.framework.TestCase, a java > class. I noticed several odd behaviors with jythonc while trying to get a > compiled jython class I could call from java. Following is my final code > which works: > > Following is the modified code which does: > # file JTest.py > import junit > > from money import * > > class JTest(junit.framework.TestCase): > def __init__(self, name): > self.name = name > # junit.framework.TestCase.__init__(self, name) > > def testSimpleAdd(self): > "@sig public void testSimpleAdd()" > print "Executing testSimpleAdd" > m12CHF = Money(12, "CHF") > m14CHF = Money(14, "CHF") > expected = Money(26, "CHF") > result = m12CHF.add(m14CHF) > junit.framework.Assert.assertEquals(expected, result) > > Following is the output of jythonc on the above > processing JTest > > Required packages: > money* > junit.framework > > Creating adapters: > > Creating .java files: > JTest module > JTest extends junit.framework.TestCase > > 1)When the the call to the TestCase.__init__(self, name) method is > uncommented, and I try to use the code with the following java code: > import JTest; > import junit.framework.*; > > public class Tester2 { > > public Tester2() {} > > public static void main(String[] args) { > JTest t = new JTest("testSimpleAdd"); > t.testEquals(); > TestSuite s = new TestSuite(JTest.class); > TestResult result = new TestResult(); > s.run(result); > System.out.println("Ran " + result.runCount() + " Failed: " + > result.failureCount() + " Errors: " + result.errorCount()); > } > } > > I get the following error: > Exception in thread "main" Java Traceback: > > at org.python.core.Py.TypeError(Py.java:120) > at > org.python.core.PyReflectedConstructor.__call__(PyReflectedConstructor.java: > 88) > at > org.python.core.PyReflectedConstructor.__call__(PyReflectedConstructor.java: > 72) > at > org.python.core.PyReflectedConstructor.__call__(PyReflectedConstructor.java: > 162) > at org.python.core.PyObject.__call__(PyObject.java:285) > at JTest$_PyInner.__init__$1(JTest.java:70) > at JTest$_PyInner.call_function(JTest.java:54) > at org.python.core.PyTableCode.call(PyTableCode.java:155) > at org.python.core.PyTableCode.call(PyTableCode.java:353) > at org.python.core.PyTableCode.call(PyTableCode.java:258) > at org.python.core.PyFunction.__call__(PyFunction.java:110) > at org.python.core.PyInstance.__init__(PyInstance.java:161) > at org.python.core.Py.initProxy(Py.java:751) > at JTest.<init>(JTest.java:167) > at Tester2.main(Tester2.java:9) > Traceback (innermost last): > File "/homes/atkicd/junit/mytests/money/JTest.py", line 0, in __init__ > TypeError: instance already instantiated for junit.framework.TestCase > > I do not understand this or see why I am getting this, I should be able to > call a specific subclass constructor from the __init__ method of my python > class. > > 1a)With the modification in 1) above, I could not compile my jython class > because the generated code was making a call to the no argument constructor > for TestCase() which happens to be non public. javac would therefore not > compile the generated java code. I do not have any calls to > junit.framework.TestCase() in my code and do not understand why jythonc put > one in the generated java code. (I modified the TestCase() constructor to > be public). > > 2)If I do not use the full class names for the java items, > junit.framework.TestCase, but instead use the minimum name based on my > import statements as in > import junit.framework.TestCase > and in the jython code use TestCase, my generated code for the jython class > inherits from java.lang.Object instead of TestCase. > > Following is the modified original class: > # file JTest.py > import junit.framework.TestCase > import junit.framework.Assert > > from money import * > > class JTest(TestCase): > def __init__(self, name): > self.name = name > TestCase.__init__(self, name) > > def testSimpleAdd(self): > "@sig public void testSimpleAdd()" > print "Executing testSimpleAdd" > m12CHF = Money(12, "CHF") > m14CHF = Money(14, "CHF") > expected = Money(26, "CHF") > result = m12CHF.add(m14CHF) > Assert.assertEquals(expected, result) > > Following is the output of running jythonc: > processing JTest > > Required packages: > junit.framework > money* > > Creating adapters: > > Creating .java files: > JTest module > > > This code would run in jython, but gets compiled improperly. This sure > seems like a bug. > no jythonc and jython interpeter have slightly different semantics, jythonc emits in the constructor a super that calls the supeclass constructor with the same signature, From jython side (jython interpreter) you construct a Python class that lazily construct a proxy class (the truly java subclassing class) instance either when you call the super class constructor, or at the end of the Python __init__. From java side with a jythonc-ed class you directly construct the proxy that setups the Python instance, we could add more policy control but you cannot have the flexibility of the other case. regards. |