From: Marc D. <ma...@op...> - 2009-03-23 23:13:48
|
Hello, I've been following the lead of the examples that Charlie Groves gave me when it comes to implementing special methods on Java classes (see http://fisheye3.atlassian.com/browse/jython/trunk/jython/tests/java/org/python/tests/CustomizableMapHolder.java?r=5940 ). 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 }; PyType.fromClass(MySpecialCallableClass.class).addMethod(meth); 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() } else { // return what you'd normally return } }; PyType.fromClass(MySpecialClass.class).addMethod(meth); 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) { @Override public PyObject __call__(PyObject o) { PyObject s = this.getSelf(); try { Method m = PyObject.class.getDeclaredMethod("getJavaProxy"); m.setAccessible(true); 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; } }; PyType.fromClass(Vector4.class).addMethod(meth); 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. best, Marc. |
From: Jim B. <jb...@zy...> - 2009-03-24 00:12:45
|
Marc, We can probably generalize http://bugs.jython.org/issue1198 for this. Note my comment in the patch, http://bugs.jython.org/file634/faux_float.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 <ma...@op...>wrote: > Hello, > I've been following the lead of the examples that Charlie Groves gave > me when it comes to implementing special methods on Java classes > (see > http://fisheye3.atlassian.com/browse/jython/trunk/jython/tests/java/org/python/tests/CustomizableMapHolder.java?r=5940 > ). > > 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 > }; > > PyType.fromClass(MySpecialCallableClass.class).addMethod(meth); > > 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() > } > else > { > // return what you'd normally return > } > }; > > PyType.fromClass(MySpecialClass.class).addMethod(meth); > > 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) { > > @Override > public PyObject __call__(PyObject o) { > > PyObject s = this.getSelf(); > try { > Method m = PyObject.class.getDeclaredMethod("getJavaProxy"); > m.setAccessible(true); > 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; > } > }; > > PyType.fromClass(Vector4.class).addMethod(meth); > > 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. > > best, > > Marc. > > > ------------------------------------------------------------------------------ > 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. http://p.sf.net/sfu/www-adobe-com > _______________________________________________ > Jython-dev mailing list > Jyt...@li... > https://lists.sourceforge.net/lists/listinfo/jython-dev > -- Jim Baker jb...@zy... |