From: <pj...@us...> - 2009-10-09 03:17:23
|
Revision: 6849 http://jython.svn.sourceforge.net/jython/?rev=6849&view=rev Author: pjenvey Date: 2009-10-09 03:17:04 +0000 (Fri, 09 Oct 2009) Log Message: ----------- rearrange/cleanup by exposing __call__ with ThreadState Modified Paths: -------------- trunk/jython/src/org/python/core/PyFunction.java Modified: trunk/jython/src/org/python/core/PyFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyFunction.java 2009-10-08 03:30:17 UTC (rev 6848) +++ trunk/jython/src/org/python/core/PyFunction.java 2009-10-09 03:17:04 UTC (rev 6849) @@ -348,7 +348,8 @@ @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) { - return func_code.call(state, arg0, arg1, arg2, arg3, func_globals, func_defaults, func_closure); + return func_code.call(state, arg0, arg1, arg2, arg3, func_globals, func_defaults, + func_closure); } @Override @@ -363,17 +364,17 @@ @Override public PyObject __call__(PyObject[] args, String[] keywords) { - return function___call__(args, keywords); + return __call__(Py.getThreadState(), args, keywords); } @Override public PyObject __call__(ThreadState state, PyObject[] args, String[] keywords) { - return func_code.call(state, args, keywords, func_globals, func_defaults, func_closure); + return function___call__(state, args, keywords); } @ExposedMethod(doc = BuiltinDocs.function___call___doc) - final PyObject function___call__(PyObject[] args, String[] keywords) { - return __call__(Py.getThreadState(), args, keywords); + final PyObject function___call__(ThreadState state, PyObject[] args, String[] keywords) { + return func_code.call(state, args, keywords, func_globals, func_defaults, func_closure); } @Override @@ -382,8 +383,10 @@ } @Override - public PyObject __call__(ThreadState state, PyObject arg1, PyObject[] args, String[] keywords) { - return func_code.call(state, arg1, args, keywords, func_globals, func_defaults, func_closure); + public PyObject __call__(ThreadState state, PyObject arg1, PyObject[] args, + String[] keywords) { + return func_code.call(state, arg1, args, keywords, func_globals, func_defaults, + func_closure); } @Override This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-11-30 23:27:11
|
Revision: 6952 http://jython.svn.sourceforge.net/jython/?rev=6952&view=rev Author: thobes Date: 2009-11-30 23:27:03 +0000 (Mon, 30 Nov 2009) Log Message: ----------- Added an initial implementation of automatic coercion of function objects to any single method interface. Modified Paths: -------------- trunk/jython/src/org/python/core/PyFunction.java Modified: trunk/jython/src/org/python/core/PyFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyFunction.java 2009-11-29 16:11:42 UTC (rev 6951) +++ trunk/jython/src/org/python/core/PyFunction.java 2009-11-30 23:27:03 UTC (rev 6952) @@ -1,6 +1,10 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; + import org.python.expose.ExposedDelete; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; @@ -388,6 +392,24 @@ public String toString() { return String.format("<function %s at %s>", __name__, Py.idstr(this)); } + + @Override + public Object __tojava__(Class<?> c) { + // Automatically coerce to single method interfaces + if (c.isInterface() && c.getDeclaredMethods().length == 1) { + return Proxy.newProxyInstance(c.getClassLoader(), new Class[]{c}, new InvocationHandler() { + // XXX: not the most efficient implementation - the invocation handler could be shared + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (args == null || args.length == 0) { + return __call__().__tojava__(method.getReturnType()); + } else { + return __call__(Py.javas2pys(args)).__tojava__(method.getReturnType()); + } + } + }); + } + return super.__tojava__( c ); + } @Override public boolean isMappingType() { return false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2010-02-25 03:53:24
|
Revision: 6982 http://jython.svn.sourceforge.net/jython/?rev=6982&view=rev Author: thobes Date: 2010-02-25 03:53:18 +0000 (Thu, 25 Feb 2010) Log Message: ----------- Added an update/fix for the automatic coercion of PyFunction to single method interfaces. Modified Paths: -------------- trunk/jython/src/org/python/core/PyFunction.java Modified: trunk/jython/src/org/python/core/PyFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyFunction.java 2010-02-22 22:55:30 UTC (rev 6981) +++ trunk/jython/src/org/python/core/PyFunction.java 2010-02-25 03:53:18 UTC (rev 6982) @@ -16,7 +16,7 @@ * A Python function. */ @ExposedType(name = "function", isBaseType = false, doc = BuiltinDocs.function_doc) -public class PyFunction extends PyObject { +public class PyFunction extends PyObject implements InvocationHandler { public static final PyType TYPE = PyType.fromClass(PyFunction.class); @@ -301,7 +301,7 @@ public PyObject __call__() { return __call__(Py.getThreadState()); } - + @Override public PyObject __call__(ThreadState state) { return func_code.call(state, func_globals, func_defaults, func_closure); @@ -311,7 +311,7 @@ public PyObject __call__(PyObject arg) { return __call__(Py.getThreadState(), arg); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0) { return func_code.call(state, arg0, func_globals, func_defaults, func_closure); @@ -321,7 +321,7 @@ public PyObject __call__(PyObject arg1, PyObject arg2) { return __call__(Py.getThreadState(), arg1, arg2); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1) { return func_code.call(state, arg0, arg1, func_globals, func_defaults, func_closure); @@ -331,31 +331,31 @@ public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) { return __call__(Py.getThreadState(), arg1, arg2, arg3); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2) { return func_code.call(state, arg0, arg1, arg2, func_globals, func_defaults, func_closure); } - + @Override public PyObject __call__(PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) { return __call__(Py.getThreadState(), arg0, arg1, arg2, arg3); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) { return func_code.call(state, arg0, arg1, arg2, arg3, func_globals, func_defaults, func_closure); } - + @Override public PyObject __call__(PyObject[] args) { return __call__(Py.getThreadState(), args); } - + @Override public PyObject __call__(ThreadState state, PyObject[] args) { return __call__(state, args, Py.NoKeywords); @@ -365,7 +365,7 @@ public PyObject __call__(PyObject[] args, String[] keywords) { return __call__(Py.getThreadState(), args, keywords); } - + @Override public PyObject __call__(ThreadState state, PyObject[] args, String[] keywords) { return function___call__(state, args, keywords); @@ -380,7 +380,7 @@ public PyObject __call__(PyObject arg1, PyObject[] args, String[] keywords) { return __call__(Py.getThreadState(), arg1, args, keywords); } - + @Override public PyObject __call__(ThreadState state, PyObject arg1, PyObject[] args, String[] keywords) { @@ -392,25 +392,56 @@ public String toString() { return String.format("<function %s at %s>", __name__, Py.idstr(this)); } - + @Override public Object __tojava__(Class<?> c) { // Automatically coerce to single method interfaces - if (c.isInterface() && c.getDeclaredMethods().length == 1) { - return Proxy.newProxyInstance(c.getClassLoader(), new Class[]{c}, new InvocationHandler() { - // XXX: not the most efficient implementation - the invocation handler could be shared - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if (args == null || args.length == 0) { - return __call__().__tojava__(method.getReturnType()); - } else { - return __call__(Py.javas2pys(args)).__tojava__(method.getReturnType()); + if (c.isInstance(this) && c != InvocationHandler.class) { + // for base types, conversion is simple - so don't wrap! + // InvocationHandler is special, since it's a single method interface + // that we implement, but if we coerce to it we want the arguments + return c.cast( this ); + } else if (c.isInterface()) { + if (c.getDeclaredMethods().length == 1 && c.getInterfaces().length == 0) { + // Proper single method interface + return proxy(c); + } else { + // Try coerce to interface with multiple overloaded versions of + // the same method (name) + String name = null; + for (Method method : c.getMethods()) { + if (method.getDeclaringClass() != Object.class) { + if (name == null || name.equals(method.getName())) { + name = method.getName(); + } else { + name = null; + break; + } } } - }); + if (name != null) { // single unique method name + return proxy(c); + } + } } - return super.__tojava__( c ); + return super.__tojava__(c); } + private Object proxy( Class<?> c ) { + return Proxy.newProxyInstance(c.getClassLoader(), new Class[]{c}, this); + } + + public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable { + // Handle invocation when invoked through Proxy (as coerced to single method interface) + if (method.getDeclaringClass() == Object.class) { + return method.invoke( this, args ); + } else if (args == null || args.length == 0) { + return __call__().__tojava__(method.getReturnType()); + } else { + return __call__(Py.javas2pys(args)).__tojava__(method.getReturnType()); + } + } + @Override public boolean isMappingType() { return false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |