From: <cg...@us...> - 2008-10-27 03:09:58
|
Revision: 5516 http://jython.svn.sourceforge.net/jython/?rev=5516&view=rev Author: cgroves Date: 2008-10-27 03:09:47 +0000 (Mon, 27 Oct 2008) Log Message: ----------- Make non-PyObject subclasses wrapped in PyJavaType instantiable Modified Paths: -------------- trunk/jython/src/org/python/core/PyInstance.java trunk/jython/src/org/python/core/PyJavaClass.java trunk/jython/src/org/python/core/PyJavaInstance.java trunk/jython/src/org/python/core/PyJavaType.java trunk/jython/src/org/python/core/PyObject.java trunk/jython/src/org/python/core/PyReflectedConstructor.java trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/src/org/python/core/PyInstance.java =================================================================== --- trunk/jython/src/org/python/core/PyInstance.java 2008-10-27 03:08:48 UTC (rev 5515) +++ trunk/jython/src/org/python/core/PyInstance.java 2008-10-27 03:09:47 UTC (rev 5516) @@ -18,9 +18,6 @@ return instclass; } - //This field is only used by Python subclasses of Java classes - Object javaProxy; - /** The namespace of this instance. Contains all instance attributes. **/ Modified: trunk/jython/src/org/python/core/PyJavaClass.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaClass.java 2008-10-27 03:08:48 UTC (rev 5515) +++ trunk/jython/src/org/python/core/PyJavaClass.java 2008-10-27 03:09:47 UTC (rev 5516) @@ -740,16 +740,6 @@ public PyObject __call__(PyObject[] args, String[] keywords) { if (!constructorsInitialized) initConstructors(); - // xxx instantiation of PyObject subclass, still needed? - if (PyObject.class.isAssignableFrom(proxyClass)) { - if (Modifier.isAbstract(proxyClass.getModifiers())) { - throw Py.TypeError("can't instantiate abstract class (" + fullName() + ")"); - } - if (__init__ == null) { - throw Py.TypeError("no public constructors for " + fullName()); - } - return __init__.make(args, keywords); - } PyInstance inst = new PyJavaInstance(this); inst.__init__(args, keywords); return inst; Modified: trunk/jython/src/org/python/core/PyJavaInstance.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaInstance.java 2008-10-27 03:08:48 UTC (rev 5515) +++ trunk/jython/src/org/python/core/PyJavaInstance.java 2008-10-27 03:09:47 UTC (rev 5516) @@ -66,8 +66,7 @@ PyReflectedConstructor init = ((PyJavaClass)instclass).__init__; if (init == null) { - throw Py.TypeError("no public constructors for "+ - instclass.__name__); + throw Py.TypeError("no public constructors for " + instclass.__name__); } init.__call__(this, args, keywords); } Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2008-10-27 03:08:48 UTC (rev 5515) +++ trunk/jython/src/org/python/core/PyJavaType.java 2008-10-27 03:09:47 UTC (rev 5516) @@ -19,13 +19,15 @@ } @Override - protected void fillDict(Class<?> base) { + protected void fillDict() { dict = new PyStringMap(); Map<String, Object> propnames = new HashMap<String, Object>(); + Class<?> base = underlying_class.getSuperclass(); Method[] methods = underlying_class.getMethods(); for (Method meth : methods) { Class<?> declaring = meth.getDeclaringClass(); - if (declaring != base && base.isAssignableFrom(declaring) && !ignore(meth)) { + if (base == null || + (declaring != base && base.isAssignableFrom(declaring) && !ignore(meth))) { String methname = meth.getName(); String nmethname = normalize_name(methname); PyReflectedFunction reflfunc = (PyReflectedFunction)dict.__finditem__(nmethname); @@ -118,16 +120,20 @@ for (Constructor<?> ctr : ctrs) { reflctr.addConstructor(ctr); } - PyObject new_ = new PyNewWrapper(underlying_class, "__new__", -1, -1) { + if (PyObject.class.isAssignableFrom(underlying_class)) { + PyObject new_ = new PyNewWrapper(underlying_class, "__new__", -1, -1) { - public PyObject new_impl(boolean init, - PyType subtype, - PyObject[] args, - String[] keywords) { - return reflctr.make(args, keywords); - } - }; - dict.__setitem__("__new__", new_); + public PyObject new_impl(boolean init, + PyType subtype, + PyObject[] args, + String[] keywords) { + return reflctr.make(args, keywords); + } + }; + dict.__setitem__("__new__", new_); + } else { + dict.__setitem__("__init__", reflctr); + } } if (ClassDictInit.class.isAssignableFrom(underlying_class) && underlying_class != ClassDictInit.class) { Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2008-10-27 03:08:48 UTC (rev 5515) +++ trunk/jython/src/org/python/core/PyObject.java 2008-10-27 03:09:47 UTC (rev 5516) @@ -35,6 +35,10 @@ } + // This field is only filled on Python wrappers for Java objects and for Python subclasses of + // Java classes. + Object javaProxy; + private PyType objtype; @ExposedGet(name = "__class__") Modified: trunk/jython/src/org/python/core/PyReflectedConstructor.java =================================================================== --- trunk/jython/src/org/python/core/PyReflectedConstructor.java 2008-10-27 03:08:48 UTC (rev 5515) +++ trunk/jython/src/org/python/core/PyReflectedConstructor.java 2008-10-27 03:09:47 UTC (rev 5516) @@ -6,10 +6,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.InstantiationException; +public class PyReflectedConstructor extends PyReflectedFunction { -public class PyReflectedConstructor extends PyReflectedFunction -{ - public PyReflectedConstructor(String name) { super(name); __name__ = name; @@ -23,8 +21,7 @@ } private ReflectedArgs makeArgs(Constructor m) { - return new ReflectedArgs(m, m.getParameterTypes(), - m.getDeclaringClass(), true); + return new ReflectedArgs(m, m.getParameterTypes(), m.getDeclaringClass(), true); } public void addConstructor(Constructor m) { @@ -36,15 +33,13 @@ } // xxx temporary solution, type ctr will go through __new__ ... - PyObject make(PyObject[] args,String[] keywords) { + PyObject make(PyObject[] args, String[] keywords) { ReflectedArgs[] argsl = argslist; - ReflectedCallData callData = new ReflectedCallData(); - Object method=null; + Object method = null; boolean consumes_keywords = false; int nkeywords = keywords.length; PyObject[] allArgs = null; - // Check for a matching constructor to call if (nargs > 0) { // PyArgsKeywordsCall signature, if present, is the first if (argsl[0].matches(null, args, keywords, callData)) { @@ -67,140 +62,84 @@ } } } - // Throw an error if no valid set of arguments if (method == null) { - throwError(callData.errArg, args.length, true /*xxx?*/,false); + throwError(callData.errArg, args.length, true /* xxx? */, false); } - // Do the actual constructor call PyObject obj = null; - Constructor ctor = (Constructor)method; try { - obj = (PyObject)ctor.newInstance(callData.getArgsArray()); - } - catch (Throwable t) { + obj = (PyObject)((Constructor<?>)method).newInstance(callData.getArgsArray()); + } catch (Throwable t) { throw Py.JavaError(t); } - if (!consumes_keywords) { int offset = args.length; for (int i = 0; i < nkeywords; i++) { obj.__setattr__(keywords[i], allArgs[i + offset]); } } - return obj; } - public PyObject __call__(PyObject self, PyObject[] args, - String[] keywords) - { - ReflectedArgs[] argsl = argslist; - - if (self == null || !(self instanceof PyInstance)) { + public PyObject __call__(PyObject self, PyObject[] args, String[] keywords) { + if (self == null) { throw Py.TypeError("invalid self argument to constructor"); } - - PyInstance iself = (PyInstance)self; - Class javaClass = iself.instclass.proxyClass; - Class declaringClass = argsl[0].declaringClass; - - // If this is the constructor for a proxy class or not... - if (PyProxy.class.isAssignableFrom(declaringClass)) { -// if (self instanceof PyJavaInstance) { -// throw Py.TypeError( -// "invalid self argument to proxy constructor"); -// } + Class<?> javaClass; + if (self instanceof PyInstance) { + javaClass = ((PyInstance)self).instclass.proxyClass; + } else { + javaClass = self.getType().underlying_class; } - else { - if (!(iself instanceof PyJavaInstance)) { - // Get proxy constructor and call it - if (declaringClass.isAssignableFrom(javaClass)) { - } else { - throw Py.TypeError("invalid self argument"); - } - PyJavaClass jc = PyJavaClass.lookup(javaClass); // xxx - jc.initConstructors(); - return jc.__init__.__call__(iself, args, keywords); - } + Class<?> declaringClass = argslist[0].declaringClass; + if (!declaringClass.isAssignableFrom(javaClass)) { + throw Py.TypeError("self invalid - must implement: " + declaringClass.getName()); } - - if (declaringClass.isAssignableFrom(javaClass)) { - } else { - throw Py.TypeError("self invalid - must implement: "+ - declaringClass.getName()); + if (!PyProxy.class.isAssignableFrom(declaringClass) && !(self instanceof PyJavaInstance)) { + PyJavaClass jc = PyJavaClass.lookup(javaClass); + jc.initConstructors(); + return jc.__init__.__call__(self, args, keywords); } - if (iself.javaProxy != null) { - Class sup = iself.instclass.proxyClass; - if (PyProxy.class.isAssignableFrom(sup)) + if (self.javaProxy != null) { + Class<?> sup = javaClass; + if (PyProxy.class.isAssignableFrom(sup)) { sup = sup.getSuperclass(); - throw Py.TypeError("instance already instantiated for "+ - sup.getName()); + } + throw Py.TypeError("instance already instantiated for " + sup.getName()); } - ReflectedCallData callData = new ReflectedCallData(); - Object method=null; - + Object method = null; // Remove keyword args int nkeywords = keywords.length; PyObject[] allArgs = args; if (nkeywords > 0) { - args = new PyObject[allArgs.length-nkeywords]; + args = new PyObject[allArgs.length - nkeywords]; System.arraycopy(allArgs, 0, args, 0, args.length); } - // Check for a matching constructor to call int n = nargs; - for (int i=0; i<n; i++) { - ReflectedArgs rargs = argsl[i]; + for (int i = 0; i < n; i++) { + ReflectedArgs rargs = argslist[i]; if (rargs.matches(null, args, Py.NoKeywords, callData)) { method = rargs.data; break; } } - // Throw an error if no valid set of arguments if (method == null) { throwError(callData.errArg, args.length, false, false); } - // Do the actual constructor call - Object jself = null; - ThreadState ts = Py.getThreadState(); - try { - ts.pushInitializingProxy(iself); - Constructor ctor = (Constructor)method; - try { - jself = ctor.newInstance(callData.getArgsArray()); - } - catch (InvocationTargetException e) { - if (e.getTargetException() instanceof InstantiationException){ - Class sup = iself.instclass.proxyClass.getSuperclass(); - String msg = "Constructor failed for Java superclass"; - if (sup != null) - msg += " " + sup.getName(); - throw Py.TypeError(msg); - } - else throw Py.JavaError(e); - } - catch (Throwable t) { - throw Py.JavaError(t); - } - } - finally { - ts.popInitializingProxy(); - } + constructProxy(self, (Constructor<?>)method, callData.getArgsArray(), javaClass); - iself.javaProxy = jself; - // Do setattr's for keyword args int offset = args.length; - for (int i=0; i<nkeywords; i++) { - iself.__setattr__(keywords[i], allArgs[i+offset]); + for (int i = 0; i < nkeywords; i++) { + self.__setattr__(keywords[i], allArgs[i + offset]); } return Py.None; } @@ -209,14 +148,44 @@ if (args.length < 1) { throw Py.TypeError("constructor requires self argument"); } - PyObject[] newArgs = new PyObject[args.length-1]; + PyObject[] newArgs = new PyObject[args.length - 1]; System.arraycopy(args, 1, newArgs, 0, newArgs.length); - return __call__(args[0], newArgs, keywords); } + protected void constructProxy(PyObject obj, Constructor<?> ctor, Object[] args, Class<?> proxy) { + // Do the actual constructor call + Object jself = null; + ThreadState ts = Py.getThreadState(); + try { + if (obj instanceof PyInstance) { + ts.pushInitializingProxy((PyInstance)obj); + } + try { + jself = ctor.newInstance(args); + } catch (InvocationTargetException e) { + if (e.getTargetException() instanceof InstantiationException) { + Class<?> sup = proxy.getSuperclass(); + String msg = "Constructor failed for Java superclass"; + if (sup != null) { + msg += " " + sup.getName(); + } + throw Py.TypeError(msg); + } else + throw Py.JavaError(e); + } catch (Throwable t) { + throw Py.JavaError(t); + } + } finally { + if (obj instanceof PyInstance) { + ts.popInitializingProxy(); + } + } + obj.javaProxy = jself; + } + public String toString() { - //printArgs(); - return "<java constructor "+__name__+" "+Py.idstr(this)+">"; + // printArgs(); + return "<java constructor " + __name__ + " " + Py.idstr(this) + ">"; } } Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2008-10-27 03:08:48 UTC (rev 5515) +++ trunk/jython/src/org/python/core/PyType.java 2008-10-27 03:09:47 UTC (rev 5516) @@ -279,7 +279,7 @@ return newobj; } - protected void fillDict(Class<?> base) { + protected void fillDict() { if (Py.BOOTSTRAP_TYPES.contains(underlying_class)) { return; } @@ -295,8 +295,13 @@ private static void fillInMRO(PyType type, Class<?> base) { PyType[] mro; - if (base == Object.class) { - mro = new PyType[] {type}; + + if (base == Object.class || base == null) { + if (type.underlying_class == Object.class) { + mro = new PyType[] {type, PyObject.TYPE}; + } else { + mro = new PyType[] {type}; + } } else { PyType baseType = fromClass(base); mro = new PyType[baseType.mro.length + 1]; @@ -923,7 +928,7 @@ newtype.underlying_class = c; newtype.builtin = true; fillInMRO(newtype, base); // basic mro, base, bases - newtype.fillDict(base); + newtype.fillDict(); return newtype; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |