Issue1646

classification
Title: Proxy getInterface not change for more PyObject
Type: behaviour Severity: normal
Components: Any Versions: Jython 2.5
Milestone:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: denis.rangel, fwierzbicki, zyasoft
Priority: Keywords: patch

Created on 2010-08-18.11:21:28 by denis.rangel, last changed 2015-01-09.03:19:50 by zyasoft.

Files
File name Uploaded Description Edit Remove
PythonObjectHolderProxy.java denis.rangel, 2010-08-18.11:21:26
unnamed denis.rangel, 2010-08-20.19:00:56
Messages
msg5989 (view) Author: Denis Guedes Rangel (denis.rangel) Date: 2010-08-18.11:21:25
When we took the class he should get a proxy object of the python (PyObject), no proxy. When the proxy so we can not turn the proxy object in python. Below is the problem and the solution simple.

Problem:

///////////////////////////// app.java
package test.test;

import java.io.FileReader;
import java.io.Reader;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class App {
	public static void main(String[] args) throws Exception {
		// cria a engine para gerenciar os scripts
		ScriptEngineManager factory = new ScriptEngineManager();
		ScriptEngine python = factory.getEngineByName("jython");
		
		final Reader test = new FileReader(App.class.getResource("test.py").getFile());
		python.eval(test);
		Object pyobject = python.eval("Test()");
		
		Test proxy= (Test) ((Invocable)python).getInterface(pyobject, Test.class);
		
		proxy.test(proxy);
		proxy.test(pyobject);
	}
}

################## test.py
class Test:
    def test(self, object):
        print object.__class__.__name__

//////////////// test.java

package test.test;

public interface Test {
	void test(Object object);
}

Output:

$Proxy8
Test

Solution:

--- src/org/python/jsr223/PyScriptEngine.java	(revisão 7093)
+++ src/org/python/jsr223/PyScriptEngine.java	(cópia de trabalho)
@@ -93,7 +93,9 @@
             NoSuchMethodException {
         try {
             interp.setLocals(new PyScriptEngineScope(this, context));
-            if (!(thiz instanceof PyObject)) {
+            if (thiz instanceof Proxy) {
+            	thiz = ((PythonObjectHolderProxy)thiz).__topython__();
+            } else if (!(thiz instanceof PyObject)) {
                 thiz = Py.java2py(thiz);
             }
             PyObject method = ((PyObject) thiz).__findattr__(name);

@@ -136,16 +138,34 @@
         @SuppressWarnings("unchecked")
         T proxy = (T) Proxy.newProxyInstance(
             clazz.getClassLoader(),
-            new Class[] { clazz },
+            new Class[] { clazz, PythonObjectHolderProxy.class },
             new InvocationHandler() {
                 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                     try {
                         interp.setLocals(new PyScriptEngineScope(PyScriptEngine.this, context));
-                        PyObject pyMethod = thiz.__findattr__(method.getName());
+
+                        String methodName = method.getName();
+                        int length = args == null ? 0 : args.length;
+                        // FIXME: wtf is this? Why would these use the class?
+                        if (methodName == "toString" && length == 0) {
+                            return proxy.getClass().getName();
+                        } else if (methodName == "hashCode" && length == 0) {
+                            return Integer.valueOf(proxy.getClass().hashCode());
+                        } else if (methodName == "__topython__" && length == 0) {
+                            return thiz;
+                        }
+
+                        PyObject pyMethod = thiz.__findattr__(methodName);
                         if (pyMethod == null)
-                            throw new NoSuchMethodException(method.getName());
-                        PyObject result = pyMethod.__call__(Py.javas2pys(args));
-                        return result.__tojava__(Object.class);
+                            throw new NoSuchMethodException(methodName);
+
+                        PyObject result;
+                        if(args != null) {
+                            result = pyMethod.__call__(Py.javas2pys(args));
+                        } else {
+                            result = pyMethod.__call__();
+                        }
+                        return result.__tojava__(method.getReturnType());
                     } catch (PyException pye) {
                         throw scriptException(pye);
                     }
msg5993 (view) Author: Jim Baker (zyasoft) Date: 2010-08-20.18:35:06
I don't understand the problem raised here. Are you referring to the functionality supported by Py#java2py and Py#tojava (or PyObject#__tojava__, which is often overridden)?

You may want to look at the Java Book chapter on Java Integration, see http://jythonpodcast.hostjava.net/jythonbook/en/1.0/JythonAndJavaIntegration.html
msg5994 (view) Author: Denis Guedes Rangel (denis.rangel) Date: 2010-08-20.19:00:57
Hi Jim,

   The problem is when you turn your python object (PyObject) but using the
Invocable.getInterface (PyObject, Class.class). It returns a
java.lang.reflect.Proxy, if you want to get the PyObject original from the
Proxy fails.

Ex:
PyObject py = Py.tojava(proxy);
System.out.println(py); // Proxty$18

On Fri, Aug 20, 2010 at 3:35 PM, Jim Baker <report@bugs.jython.org> wrote:

>
> Jim Baker <zyasoft@users.sourceforge.net> added the comment:
>
> I don't understand the problem raised here. Are you referring to the
> functionality supported by Py#java2py and Py#tojava (or PyObject#__tojava__,
> which is often overridden)?
>
> You may want to look at the Java Book chapter on Java Integration, see
> http://jythonpodcast.hostjava.net/jythonbook/en/1.0/JythonAndJavaIntegration.html
>
> ----------
> nosy: +zyasoft
>
> _______________________________________
> Jython tracker <report@bugs.jython.org>
> <http://bugs.jython.org/issue1646>
> _______________________________________
>
msg9361 (view) Author: Jim Baker (zyasoft) Date: 2015-01-09.03:19:50
We should support this optional JSR 223 functionality.
History
Date User Action Args
2015-01-09 03:19:50zyasoftsetmessages: + msg9361
2013-02-19 18:02:19fwierzbickisetkeywords: + patch
nosy: + fwierzbicki
versions: + Jython 2.5, - 2.5.2b1
2010-08-20 19:00:57denis.rangelsetfiles: + unnamed
messages: + msg5994
2010-08-20 18:35:07zyasoftsetnosy: + zyasoft
messages: + msg5993
2010-08-18 11:21:29denis.rangelcreate