We can probably generalize for this. Note my comment in the patch, - "maybe __int__ too?" So good synchronicity here with SymPy's needs.

I'm not certain if this patch is the best approach, specifically trapping AttributeError (elsewhere in the code we use NotImplemented, etc.), but it's probably reasonable for 2.5.0 if that's just a possible performance issue, since other paths will be just as fast.

- Jim

On Mon, Mar 23, 2009 at 4:51 PM, Marc Downie <> wrote:
I've been following the lead of the examples that Charlie Groves gave
me when it comes to implementing special methods on Java classes

Everything is working great (with beta3) for my special __getattr__'s
and __call__'s and things like that, and my Python / Java integration
is incredibly tight.

But now, provoked by an odd feature request, I'm trying to implement a
__tojava__ method to extend what some of my (Java) classes can be
coerced to when they cross back across from Python to Java. If this
sounds like a bridge too far and implementing a __tojava__ in this
fashion is out of the design space of the interface then stop reading,
tell me and we'll forget I ever mentioned it.

The pattern is something like this:

PyBuiltinMethodNarrow meth = new PyBuiltinMethodNarrow("__call__", 0, 1) {
   public PyObject __call__(PyObject[] args, String[] kw) {
     // do something wonderful, thus making MySpecialCallableClass callable


So, by extension:

PyBuiltinMethodNarrow meth = new PyBuiltinMethodNarrow("__tojava__", 1, 1) {
   public PyObject __call__(PyObject targetType) {
      if (targetType == somethingInteresting)
             // return some interesting conversion of this.getSelf()
             // return what you'd normally return


I'm having a hard time populating either branch of this if statement.
Best I can do, for my class Vector4, is this hideous hack:

final PyBuiltinMethodNarrow meth = new
PyBuiltinMethodNarrow("__tojava__", 1, 1) {

    public PyObject __call__(PyObject o) {

         PyObject s = this.getSelf();
         try {
              Method m = PyObject.class.getDeclaredMethod("getJavaProxy");
              Vector4 actual = (Vector4) m.invoke(s);

              if (((PyType) o).getName().equals("int")) {
                   return Py.java2py(actual.toInt());
              return s;
           } catch (IllegalArgumentException e) {
           } catch (SecurityException e) {
           } catch (IllegalAccessException e) {
           } catch (InvocationTargetException e) {
           } catch (NoSuchMethodException e) {

         return Py.None;


This lets me use Vector4's to call java methods expecting int's, but
it doesn't let me use Vector4 in normal ways (I get a maximum
recursion depth exceeded error).

Clearly I'm well off the beaten path here, but any general advice
about, say, how to have Java classes emulate numeric types as they are
passed into Java calls would be appreciated. Brief experiments with
__int__ and the like have yielded nothing.



Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial.
Jython-dev mailing list

Jim Baker