From: Chris A. <Chr...@al...> - 2002-08-12 15:46:26
|
Samuele, Can you give me more information about the differences between jython and jythonc semantics. I still do not understand how I can control the subclass constructor which will be called. I would like the following to happen: def __init__(self, *args): if(len(args) == 2: BaseClass.__init__(self, args[0], args[1]) elif(len(args) == 1: value = somefunc(args[0]); BaseClass.__init__(self, args[0], value) elif(len(args0)==0: BaseClass.__init__(self) However, you are indicating that I should not be placing the BaseClass.__init__() calls in my jython code???? I would really like to be able to call my jython class from either jython or java with the same semantics and have control over which base class constructor my jython class is going to call. My jython class may want to call a constructor which has a different signature as in: def __init__(self) BaseClass.__init__(self, "arg1", 5) Can you please explain how I can control which subclass constructor is called. > -----Original Message----- > From: Samuele Pedroni [mailto:pe...@in...] > Sent: Monday, August 12, 2002 10:26 AM > To: Chr...@al...; jyt...@li... > Subject: Re: [Jython-users] Compiling jython subclassing java classes > > > > 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__(PyReflectedCon > structor.java: > > 88) > > at > > > org.python.core.PyReflectedConstructor.__call__(PyReflectedCon > structor.java: > > 72) > > at > > > org.python.core.PyReflectedConstructor.__call__(PyReflectedCon > structor.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. > > > |