Code references in this mail refer to the jython 2.1 source code which
I downloaded this afternoon.
----
I have included below a simplified version of the type of code I am
trying to get going at work. I have a class TestThing which behaves
like a number, and in Jython scripts I want to add them together.
Because the implementation of TestThing is ingrained into the system,
it is impossible for TestThing to extend PyObject, so I figured I
could add the functionality using ClassDictInit.
I started by adding a definition for __add__, but I found that only
one argument was being passed in. I thought maybe the "this" object
would be the other parameter, but of course "this" is the new PyObject
that I create to add the __call__ method to. No matter what I did, I
couldn't figure out where to get the other argument to the addition
from.
So I did some experimentation, and found that on line 731 of
PyInstance, __coerce_ex__ was being called on my argument to get it to
be the same type as "this". Of course, in PyInstance, "this" really is
the left hand value in the addition. So I used ClassDictInit to add a
__coerce__ to my class as well. However, it turns out that there also,
only one argument is being passed through. As far as I understand
__coerce__, I am supposed to receive two objects and make them the
same type and return them, but I am only getting one argument. You can
see this if you run my test program.
The problem seems to me to be somewhere around line 613 of PyInstance,
where it invokes __coerce__, but it does not pass "this" through as an
argument. If you're actually subclassing the PyObject, overriding
__coerce_ex__ is fine, but if the coerce method which is invoked comes
from the ClassDictInit stuff, the "this" context is lost, and we don't
know what to coerce to. It's absolutely vital that coerce know this
value, as it is used on line 735/736 of PyInstance.
So, am I doing the right thing? Is is really broken like I imagine? Or
is there something I'm not getting? I can't much doc for this level of
detail, so I am flying blind most of the time. Thanks for any help,
John
---------------------------
package test;
import java.util.Arrays;
import org.python.util.PythonInterpreter;
import org.python.core.*;
/**
* @author John Farrell (friendless.farrell@...)
*/
public class TestThing implements ClassDictInit {
private int i;
public TestThing(int i) {
this.i =3D i;
}
public static void classDictInit(PyObject dict) {
dict.__setitem__("__add__", new PyObject() {
public PyObject __call__(PyObject args[], String keywords[]) {
/* NOT ENOUGH ARGS */
System.out.println("__add__ args =3D " + Arrays.asList(args=
));
return null;
}
});
dict.__setitem__("__coerce__", new PyObject() {
public PyObject __call__(PyObject args[], String keywords[]) {
/* NOT ENOUGH ARGS */
System.out.println("__coerce__ args =3D " + Arrays.asList(a=
rgs));
return null;
}
});
}
public static void main(String[] args) {
PythonInterpreter pi =3D new PythonInterpreter();
pi.exec("from test import TestThing");
pi.exec("t1 =3D TestThing(3)");
pi.exec("t2 =3D TestThing(2)");
Object sum =3D pi.eval("t1 + t2");
System.out.println("sum =3D " + sum);
}
public String toString() {
return "" + i + " things";
}
}
|