From: <cg...@us...> - 2009-08-22 07:53:28
|
Revision: 6703 http://jython.svn.sourceforge.net/jython/?rev=6703&view=rev Author: cgroves Date: 2009-08-22 07:53:18 +0000 (Sat, 22 Aug 2009) Log Message: ----------- Split the bits of PyType used to configure and initialize runtime types into PyUserType and move the bits that do the same for @Exposed classes and java types into PyBuiltinType. PyType just keeps the implementation of type logic and the fields necessary for that. I'd been worried that PyType was going to gain sentience and eat Chicago if it got any larger. Modified Paths: -------------- branches/customizable-proxymaker/src/org/python/core/PyClass.java branches/customizable-proxymaker/src/org/python/core/PyJavaType.java branches/customizable-proxymaker/src/org/python/core/PyType.java branches/customizable-proxymaker/src/templates/type.derived Added Paths: ----------- branches/customizable-proxymaker/src/org/python/core/PyBuiltinType.java branches/customizable-proxymaker/src/org/python/core/PyUserType.java branches/customizable-proxymaker/src/org/python/core/PyUserTypeDerived.java Removed Paths: ------------- branches/customizable-proxymaker/src/org/python/core/PyTypeDerived.java Added: branches/customizable-proxymaker/src/org/python/core/PyBuiltinType.java =================================================================== --- branches/customizable-proxymaker/src/org/python/core/PyBuiltinType.java (rev 0) +++ branches/customizable-proxymaker/src/org/python/core/PyBuiltinType.java 2009-08-22 07:53:18 UTC (rev 6703) @@ -0,0 +1,218 @@ +package org.python.core; + +import java.util.Map; +import java.util.Set; + +import org.python.expose.ExposeAsSuperclass; +import org.python.expose.ExposedType; +import org.python.expose.TypeBuilder; +import org.python.util.Generic; + + +public class PyBuiltinType extends PyType { + + /** Mapping of Java classes to their PyTypes. */ + private static Map<Class<?>, PyBuiltinType> class_to_type; + + /** Mapping of Java classes to their TypeBuilders. */ + private static Map<Class<?>, TypeBuilder> classToBuilder; + + PyBuiltinType(PyType pyType) { + super(pyType); + } + + private PyBuiltinType() { + } + + private PyBuiltinType(boolean b) { + super(b); + } + + public static synchronized PyBuiltinType fromClass(Class<?> c) { + if (c == PyBuiltinType.class) { + return fromClass(PyType.class); + } + if (class_to_type == null) { + class_to_type = Generic.map(); + addFromClass(PyType.class, null); + } + PyBuiltinType type = class_to_type.get(c); + if (type != null) { + return type; + } + // We haven't seen this class before, so it's type needs to be created. If it's being + // exposed as a Java class, defer processing its inner types until it's completely + // created in case the inner class references a class that references this class. + Set<PyJavaType> needsInners = Generic.set(); + PyBuiltinType result = addFromClass(c, needsInners); + for (PyJavaType javaType : needsInners) { + Class<?> forClass = javaType.getProxyType(); + if (forClass == null) { + continue; + } + for (Class<?> inner : forClass.getClasses()) { + // Only add the class if there isn't something else with that name and it came from this + // class + if (inner.getDeclaringClass() == forClass && + javaType.dict.__finditem__(inner.getSimpleName()) == null) { + // If this class is currently being loaded, any exposed types it contains won't have + // set their builder in PyType yet, so add them to BOOTSTRAP_TYPES so they're + // created as PyType instead of PyJavaType + if (inner.getAnnotation(ExposedType.class) != null + || ExposeAsSuperclass.class.isAssignableFrom(inner)) { + Py.BOOTSTRAP_TYPES.add(inner); + } + javaType.dict.__setitem__(inner.getSimpleName(), PyType.fromClass(inner)); + } + } + } + return result; + } + + public static void addBuilder(Class<?> forClass, TypeBuilder builder) { + + if (classToBuilder == null) { + classToBuilder = Generic.map(); + } + classToBuilder.put(forClass, builder); + + if (class_to_type.containsKey(forClass)) { + if (!Py.BOOTSTRAP_TYPES.remove(forClass)) { + Py.writeWarning("init", "Bootstrapping class not in Py.BOOTSTRAP_TYPES[class=" + + forClass + "]"); + } + // The types in Py.BOOTSTRAP_TYPES are initialized before their builders are assigned, + // so do the work of addFromClass & fillFromClass after the fact + PyBuiltinType.fromClass(builder.getTypeClass()).init(builder.getTypeClass(), null); + } + } + + /** + * Called on builtin types for a particular class. Should fill in dict, name, mro, base and + * bases from the class. + */ + protected void init(Class<?> forClass, Set<PyJavaType> needsInners) { + underlying_class = forClass; + if (underlying_class == PyObject.class) { + mro = new PyType[] {this}; + } else { + Class<?> baseClass; + if (!Py.BOOTSTRAP_TYPES.contains(underlying_class)) { + baseClass = classToBuilder.get(underlying_class).getBase(); + } else { + baseClass = PyObject.class; + } + if (baseClass == Object.class) { + baseClass = underlying_class.getSuperclass(); + } + computeLinearMro(baseClass); + } + if (Py.BOOTSTRAP_TYPES.contains(underlying_class)) { + // init will be called again from addBuilder which also removes underlying_class from + // BOOTSTRAP_TYPES + return; + } + TypeBuilder builder = classToBuilder.get(underlying_class); + name = builder.getName(); + dict = builder.getDict(this); + setIsBaseType(builder.getIsBaseType()); + instantiable = dict.__finditem__("__new__") != null; + fillHasSetAndDelete(); + } + + /** + * Fills the base and bases of this type with the type of baseClass as sets its mro to this type + * followed by the mro of baseClass. + */ + protected void computeLinearMro(Class<?> baseClass) { + base = PyType.fromClass(baseClass); + mro = new PyType[base.mro.length + 1]; + System.arraycopy(base.mro, 0, mro, 1, base.mro.length); + mro[0] = this; + bases = new PyObject[] {base}; + } + + private void setIsBaseType(boolean isBaseType) { + this.isBaseType = isBaseType; + tp_flags = isBaseType ? tp_flags | Py.TPFLAGS_BASETYPE : tp_flags & ~Py.TPFLAGS_BASETYPE; + } + + private static PyBuiltinType addFromClass(Class<?> c, Set<PyJavaType> needsInners) { + if (ExposeAsSuperclass.class.isAssignableFrom(c)) { + PyBuiltinType exposedAs = fromClass(c.getSuperclass()); + class_to_type.put(c, exposedAs); + return exposedAs; + } + return createType(c, needsInners); + } + + private static TypeBuilder getBuilder(Class<?> c) { + if (classToBuilder == null) { + // PyType itself has yet to be initialized. This should be a bootstrap type, so it'll + // go through the builder process in a second + return null; + } + if (c.isPrimitive() || !PyObject.class.isAssignableFrom(c)) { + // If this isn't a PyObject, don't bother forcing it to be initialized to load its + // builder + return null; + } + + // This is a PyObject, call forName to force static initialization on the class so if it has + // a builder, it'll be filled in + SecurityException exc = null; + try { + Class.forName(c.getName(), true, c.getClassLoader()); + } catch (ClassNotFoundException e) { + // Well, this is certainly surprising. + throw new RuntimeException("Got ClassNotFound calling Class.forName on an already " + + " found class.", e); + } catch (ExceptionInInitializerError e) { + throw Py.JavaError(e); + } catch (SecurityException e) { + exc = e; + } + TypeBuilder builder = classToBuilder.get(c); + if (builder == null && exc != null) { + Py.writeComment("type", + "Unable to initialize " + c.getName() + ", a PyObject subclass, due to a " + + "security exception, and no type builder could be found for it. If it's an " + + "exposed type, it may not work properly. Security exception: " + + exc.getMessage()); + } + return builder; + } + + private static PyBuiltinType createType(Class<?> c, Set<PyJavaType> needsInners) { + PyBuiltinType newtype; + if (c == PyJavaType.class) { + return (PyBuiltinType)PyType.fromClass(Class.class); + } else if (c == PyType.class) { + newtype = new PyBuiltinType(false); + } else if (Py.BOOTSTRAP_TYPES.contains(c) || getBuilder(c) != null) { + newtype = new PyBuiltinType(); + } else { + newtype = new PyJavaType(); + } + + + // If filling in the type above filled the type under creation, use that one + PyBuiltinType type = class_to_type.get(c); + if (type != null) { + return type; + } + + class_to_type.put(c, newtype); + newtype.builtin = true; + newtype.init(c, needsInners); + return newtype; + } + + static PyType fromClassSkippingInners(Class<?> c, Set<PyJavaType> needsInners) { + PyType type = class_to_type.get(c); + if (type != null) { + return type; + } + return addFromClass(c, needsInners); + } +} Modified: branches/customizable-proxymaker/src/org/python/core/PyClass.java =================================================================== --- branches/customizable-proxymaker/src/org/python/core/PyClass.java 2009-08-22 07:46:25 UTC (rev 6702) +++ branches/customizable-proxymaker/src/org/python/core/PyClass.java 2009-08-22 07:53:18 UTC (rev 6703) @@ -48,8 +48,8 @@ if (!(dict instanceof PyStringMap || dict instanceof PyDictionary)) { throw Py.TypeError("PyClass_New: dict must be a dictionary"); } - PyType.ensureDoc(dict); - PyType.ensureModule(dict); + PyUserType.ensureDoc(dict); + PyUserType.ensureModule(dict); if (!(bases instanceof PyTuple)) { throw Py.TypeError("PyClass_New: bases must be a tuple"); Modified: branches/customizable-proxymaker/src/org/python/core/PyJavaType.java =================================================================== --- branches/customizable-proxymaker/src/org/python/core/PyJavaType.java 2009-08-22 07:46:25 UTC (rev 6702) +++ branches/customizable-proxymaker/src/org/python/core/PyJavaType.java 2009-08-22 07:53:18 UTC (rev 6703) @@ -17,7 +17,7 @@ import org.python.core.util.StringUtil; import org.python.util.Generic; -public class PyJavaType extends PyType { +public class PyJavaType extends PyBuiltinType { private final static Class<?>[] OO = {PyObject.class, PyObject.class}; @@ -188,7 +188,7 @@ } else { needsInners.add(this); javaProxy = forClass; - objtype = PyType.fromClassSkippingInners(Class.class, needsInners); + objtype = PyBuiltinType.fromClassSkippingInners(Class.class, needsInners); // Wrapped Java types fill in their mro first using all of their interfaces then their // super class. List<PyObject> visibleBases = Generic.list(); @@ -205,16 +205,16 @@ // in the hierarchy, adding it here hides the forms from those interfaces. continue; } - visibleBases.add(PyType.fromClassSkippingInners(iface, needsInners)); + visibleBases.add(PyBuiltinType.fromClassSkippingInners(iface, needsInners)); } if (javaProxy == Object.class) { - base = PyType.fromClassSkippingInners(PyObject.class, needsInners); + base = PyBuiltinType.fromClassSkippingInners(PyObject.class, needsInners); } else if(baseClass == null) { - base = PyType.fromClassSkippingInners(Object.class, needsInners); + base = PyBuiltinType.fromClassSkippingInners(Object.class, needsInners); }else if (javaProxy == Class.class) { - base = PyType.fromClassSkippingInners(PyType.class, needsInners); + base = PyBuiltinType.fromClassSkippingInners(PyType.class, needsInners); } else { - base = PyType.fromClassSkippingInners(baseClass, needsInners); + base = PyBuiltinType.fromClassSkippingInners(baseClass, needsInners); } visibleBases.add(base); this.bases = visibleBases.toArray(new PyObject[visibleBases.size()]); Modified: branches/customizable-proxymaker/src/org/python/core/PyType.java =================================================================== --- branches/customizable-proxymaker/src/org/python/core/PyType.java 2009-08-22 07:46:25 UTC (rev 6702) +++ branches/customizable-proxymaker/src/org/python/core/PyType.java 2009-08-22 07:53:18 UTC (rev 6703) @@ -7,10 +7,8 @@ import java.lang.ref.WeakReference; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Set; -import org.python.expose.ExposeAsSuperclass; import org.python.expose.ExposedDelete; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; @@ -18,7 +16,6 @@ import org.python.expose.ExposedSet; import org.python.expose.ExposedType; import org.python.expose.TypeBuilder; -import org.python.modules._weakref.WeakrefModule; import org.python.util.Generic; /** @@ -47,9 +44,6 @@ /** __mro__, the method resolution. order */ protected PyObject[] mro; - /** __flags__, the type's options. */ - private long tp_flags; - /** * The Java Class instances of this type will be represented as, or null if it's * determined by a base type. @@ -62,46 +56,43 @@ /** Whether new instances of this type can be instantiated */ protected boolean instantiable = true; + /** Whether this type has a __dict__. */ + protected boolean needs_userdict; + + /** __flags__, the type's options. */ + long tp_flags; + /** Whether this type has set/delete descriptors */ boolean has_set; boolean has_delete; /** Whether this type allows subclassing. */ - private boolean isBaseType = true; + boolean isBaseType = true; - /** Whether this type has a __dict__. */ - protected boolean needs_userdict; - /** Whether this type has a __weakref__ slot (however all types are weakrefable). */ - protected boolean needs_weakref; + boolean needs_weakref; /** Whether finalization is required for this type's instances (implements __del__). */ - private boolean needs_finalizer; + boolean needs_finalizer; /** The number of __slots__ defined. */ - private int numSlots; + int numSlots; private ReferenceQueue<PyType> subclasses_refq = new ReferenceQueue<PyType>(); private Set<WeakReference<PyType>> subclasses = Generic.set(); - /** Mapping of Java classes to their PyTypes. */ - private static Map<Class<?>, PyType> class_to_type; - - /** Mapping of Java classes to their TypeBuilders. */ - private static Map<Class<?>, TypeBuilder> classToBuilder; - protected PyType(PyType subtype) { super(subtype); } - private PyType() { + PyType() { } /** * Creates the PyType instance for type itself. The argument just exists to make the constructor * distinct. */ - private PyType(boolean ignored) { + PyType(boolean ignored) { super(ignored); } @@ -130,8 +121,7 @@ public static PyObject newType(PyNewWrapper new_, PyType metatype, String name, PyTuple bases, PyObject dict) { - PyObject[] tmpBases = bases.getArray(); - PyType winner = findMostDerivedMetatype(tmpBases, metatype); + PyType winner = findMostDerivedMetatype(bases, metatype); if (winner != metatype) { PyObject winner_new_ = winner.lookup("__new__"); @@ -150,281 +140,13 @@ metatype = TYPE; } - PyType type; if (new_.for_type == metatype) { - // XXX: set metatype - type = new PyType(); + return new PyUserType(TYPE, name, bases, dict); } else { - type = new PyTypeDerived(metatype); + return new PyUserTypeDerived(metatype, name, bases, dict); } - - if (dict instanceof PyStringMap) { - dict = ((PyStringMap)dict).copy(); - } else { - dict = ((PyDictionary)dict).copy(); - } - - type.name = name; - type.bases = tmpBases.length == 0 ? new PyObject[] {PyObject.TYPE} : tmpBases; - type.dict = dict; - type.tp_flags = Py.TPFLAGS_HEAPTYPE | Py.TPFLAGS_BASETYPE; - - // immediately setup the javaProxy if applicable. may modify bases - List<Class<?>> interfaces = Generic.list(); - Class<?> baseProxyClass = getJavaLayout(type.bases, interfaces); - type.setupProxy(baseProxyClass, interfaces); - - PyType base = type.base = best_base(type.bases); - if (!base.isBaseType) { - throw Py.TypeError(String.format("type '%.100s' is not an acceptable base type", - base.name)); - } - - type.createAllSlots(!base.needs_userdict, !base.needs_weakref); - type.ensureAttributes(); - - for (PyObject cur : type.bases) { - if (cur instanceof PyType) - ((PyType)cur).attachSubclass(type); - } - - return type; } - /** - * Create all slots and related descriptors. - * - * @param mayAddDict whether a __dict__ descriptor is allowed on this type - * @param mayAddWeak whether a __weakref__ descriptor is allowed on this type - */ - private void createAllSlots(boolean mayAddDict, boolean mayAddWeak) { - numSlots = base.numSlots; - boolean wantDict = false; - boolean wantWeak = false; - PyObject slots = dict.__finditem__("__slots__"); - - if (slots == null) { - wantDict = mayAddDict; - wantWeak = mayAddWeak; - } else { - if (slots instanceof PyString) { - slots = new PyTuple(slots); - } - - // Check for valid slot names and create them. Handle two special cases - for (PyObject slot : slots.asIterable()) { - String slotName = confirmIdentifier(slot); - - if (slotName.equals("__dict__")) { - if (!mayAddDict || wantDict) { - throw Py.TypeError("__dict__ slot disallowed: we already got one"); - } - wantDict = true; - } else if (slotName.equals("__weakref__")) { - if (!mayAddWeak || wantWeak) { - throw Py.TypeError("__weakref__ slot disallowed: we already got one"); - } - wantWeak = true; - } else { - slotName = mangleName(name, slotName); - if (dict.__finditem__(slotName) == null) { - dict.__setitem__(slotName, new PySlot(this, slotName, numSlots++)); - } - } - } - - // Secondary bases may provide weakrefs or dict - if (bases.length > 1 - && ((mayAddDict && !wantDict) || (mayAddWeak && !wantWeak))) { - for (PyObject base : bases) { - if (base == this.base) { - // Skip primary base - continue; - } - - if (base instanceof PyClass) { - // Classic base class provides both - if (mayAddDict && !wantDict) { - wantDict = true; - } - if (mayAddWeak && !wantWeak) { - wantWeak = true; - } - break; - } - - PyType baseType = (PyType)base; - if (mayAddDict && !wantDict && baseType.needs_userdict) { - wantDict = true; - } - if (mayAddWeak && !wantWeak && baseType.needs_weakref) { - wantWeak = true; - } - if ((!mayAddDict || wantDict) && (!mayAddWeak || wantWeak)) { - // Nothing more to check - break; - } - } - } - } - - if (wantDict) { - createDictSlot(); - } - if (wantWeak) { - createWeakrefSlot(); - } - needs_finalizer = lookup("__del__") != null; - } - - /** - * Create the __dict__ descriptor. - */ - private void createDictSlot() { - dict.__setitem__("__dict__", new PyDataDescr(this, "__dict__", PyObject.class) { - @Override - public Object invokeGet(PyObject obj) { - return obj.getDict(); - } - - @Override - public boolean implementsDescrSet() { - return true; - } - - @Override - public void invokeSet(PyObject obj, Object value) { - obj.setDict((PyObject)value); - } - - @Override - public boolean implementsDescrDelete() { - return true; - } - - @Override - public void invokeDelete(PyObject obj) { - obj.delDict(); - } - }); - needs_userdict = true; - } - - /** - * Create the __weakref__ descriptor. - */ - private void createWeakrefSlot() { - dict.__setitem__("__weakref__", new PyDataDescr(this, "__weakref__", PyObject.class) { - private static final String writeMsg = - "attribute '%s' of '%s' objects is not writable"; - - private void notWritable(PyObject obj) { - throw Py.AttributeError(String.format(writeMsg, "__weakref__", - obj.getType().fastGetName())); - } - - @Override - public Object invokeGet(PyObject obj) { - PyList weakrefs = WeakrefModule.getweakrefs(obj); - switch (weakrefs.size()) { - case 0: - return Py.None; - case 1: - return weakrefs.pyget(0); - default: - return weakrefs; - - } - } - - @Override - public boolean implementsDescrSet() { - return true; - } - - @Override - public void invokeSet(PyObject obj, Object value) { - // XXX: Maybe have PyDataDescr do notWritable() for us - notWritable(obj); - } - - @Override - public boolean implementsDescrDelete() { - return true; - } - - @Override - public void invokeDelete(PyObject obj) { - notWritable(obj); - } - }); - needs_weakref = true; - } - - /** - * Setup this type's special attributes. - */ - private void ensureAttributes() { - inheritSpecial(); - - // special case __new__, if function => static method - PyObject new_ = dict.__finditem__("__new__"); - // XXX: java functions? - if (new_ != null && new_ instanceof PyFunction) { - dict.__setitem__("__new__", new PyStaticMethod(new_)); - } - - ensureDoc(dict); - ensureModule(dict); - - // Calculate method resolution order - mro_internal(); - fillHasSetAndDelete(); - } - - /** - * Inherit special attributes from the dominant base. - */ - private void inheritSpecial() { - if (!needs_userdict && base.needs_userdict) { - needs_userdict = true; - } - if (!needs_weakref && base.needs_weakref) { - needs_weakref = true; - } - } - - /** - * Ensure dict contains a __doc__. - * - * @param dict a PyObject mapping - */ - public static void ensureDoc(PyObject dict) { - if (dict.__finditem__("__doc__") == null) { - dict.__setitem__("__doc__", Py.None); - } - } - - /** - * Ensure dict contains a __module__, retrieving it from the current frame if it - * doesn't exist. - * - * @param dict a PyObject mapping - */ - public static void ensureModule(PyObject dict) { - if (dict.__finditem__("__module__") != null) { - return; - } - PyFrame frame = Py.getFrame(); - if (frame == null) { - return; - } - PyObject name = frame.f_globals.__finditem__("__name__"); - if (name != null) { - dict.__setitem__("__module__", name); - } - } - private static PyObject invoke_new_(PyObject new_, PyType type, boolean init, PyObject[] args, String[] keywords) { PyObject newobj; @@ -445,52 +167,7 @@ return newobj; } - /** - * Called on builtin types for a particular class. Should fill in dict, name, mro, base and - * bases from the class. - */ - protected void init(Class<?> forClass, Set<PyJavaType> needsInners) { - underlying_class = forClass; - if (underlying_class == PyObject.class) { - mro = new PyType[] {this}; - } else { - Class<?> baseClass; - if (!Py.BOOTSTRAP_TYPES.contains(underlying_class)) { - baseClass = classToBuilder.get(underlying_class).getBase(); - } else { - baseClass = PyObject.class; - } - if (baseClass == Object.class) { - baseClass = underlying_class.getSuperclass(); - } - computeLinearMro(baseClass); - } - if (Py.BOOTSTRAP_TYPES.contains(underlying_class)) { - // init will be called again from addBuilder which also removes underlying_class from - // BOOTSTRAP_TYPES - return; - } - TypeBuilder builder = classToBuilder.get(underlying_class); - name = builder.getName(); - dict = builder.getDict(this); - setIsBaseType(builder.getIsBaseType()); - instantiable = dict.__finditem__("__new__") != null; - fillHasSetAndDelete(); - } - - /** - * Fills the base and bases of this type with the type of baseClass as sets its mro to this type - * followed by the mro of baseClass. - */ - protected void computeLinearMro(Class<?> baseClass) { - base = PyType.fromClass(baseClass); - mro = new PyType[base.mro.length + 1]; - System.arraycopy(base.mro, 0, mro, 1, base.mro.length); - mro[0] = this; - bases = new PyObject[] {base}; - } - - private void fillHasSetAndDelete() { + void fillHasSetAndDelete() { has_set = lookup("__set__") != null; has_delete = lookup("__delete__") != null; } @@ -528,88 +205,6 @@ return base.getLayout(); } - /** - * Get the most parent Java proxy Class from bases, tallying any encountered Java - * interfaces. - * - * @param bases array of base Jython classes - * @param interfaces List for collecting interfaces to - * @return base Java proxy Class - * @raises Py.TypeError if multiple Java inheritance was attempted - */ - private static Class<?> getJavaLayout(PyObject[] bases, List<Class<?>> interfaces) { - Class<?> baseProxy = null; - - for (PyObject base : bases) { - if (!(base instanceof PyType)) { - continue; - } - Class<?> proxy = ((PyType)base).getProxyType(); - if (proxy == null) { - continue; - } - if (proxy.isInterface()) { - interfaces.add(proxy); - } else { - if (baseProxy != null) { - String msg = "no multiple inheritance for Java classes: %s and %s"; - throw Py.TypeError(String.format(msg, proxy.getName(), baseProxy.getName())); - } - baseProxy = proxy; - } - } - - return baseProxy; - } - - /** - * Setup the javaProxy for this type. - * - * @param baseProxyClass this type's base proxyClass - * @param interfaces a list of Java interfaces in bases - */ - private void setupProxy(Class<?> baseProxyClass, List<Class<?>> interfaces) { - if (baseProxyClass == null && interfaces.size() == 0) { - // javaProxy not applicable - return; - } - - String proxyName = name; - PyObject module = dict.__finditem__("__module__"); - if (module != null) { - proxyName = module.toString() + "$" + proxyName; - } - javaProxy = MakeProxies.makeProxy(baseProxyClass, interfaces, name, proxyName, dict); - - PyType proxyType = PyType.fromClass((Class<?>)javaProxy); - List<PyObject> cleanedBases = Generic.list(); - boolean addedProxyType = false; - for (PyObject base : bases) { - if (!(base instanceof PyType)) { - cleanedBases.add(base); - continue; - } - Class<?> proxy = ((PyType)base).getProxyType(); - if (proxy == null) { - // non-proxy types go straight into our lookup - cleanedBases.add(base); - } else { - - if (!(base instanceof PyJavaType)) { - // python subclasses of proxy types need to be added as a base so their - // version of methods will show up - cleanedBases.add(base); - } else if (!addedProxyType) { - // Only add a single Java type, since everything's going to go through the - // proxy type - cleanedBases.add(proxyType); - addedProxyType = true; - } - } - } - bases = cleanedBases.toArray(new PyObject[cleanedBases.size()]); - } - //XXX: needs __doc__ @ExposedGet(name = "__base__") public PyObject getBase() { @@ -685,12 +280,7 @@ } } - private void setIsBaseType(boolean isBaseType) { - this.isBaseType = isBaseType; - tp_flags = isBaseType ? tp_flags | Py.TPFLAGS_BASETYPE : tp_flags & ~Py.TPFLAGS_BASETYPE; - } - - private void mro_internal() { + void mro_internal() { if (getType() == TYPE) { mro = computeMro(); } else { @@ -781,7 +371,7 @@ return (Class<?>)javaProxy; } - private synchronized void attachSubclass(PyType subtype) { + synchronized void attachSubclass(PyType subtype) { cleanup_subclasses(); subclasses.add(new WeakReference<PyType>(subtype, subclasses_refq)); } @@ -955,7 +545,7 @@ * @throws Py.TypeError if the bases don't all derive from the same solid_base * @throws Py.TypeError if at least one of the bases isn't a new-style class */ - private static PyType best_base(PyObject[] bases) { + static PyType best_base(PyObject[] bases) { PyType winner = null; PyType candidate = null; PyType best = null; @@ -986,17 +576,15 @@ } /** - * Finds the most derived subtype of initialMetatype in the types - * of bases, or initialMetatype if it is already the most derived. + * Finds the most derived subtype of initialMetatype in the types of bases, or initialMetatype + * if it is already the most derived. * - * @raises Py.TypeError if the all the metaclasses don't descend - * from the same base - * @raises Py.TypeError if one of the bases is a PyJavaClass or a - * PyClass with no proxyClass + * @raises Py.TypeError if the all the metaclasses don't descend from the same base + * @raises Py.TypeError if one of the bases is a PyJavaClass or a PyClass with no proxyClass */ - private static PyType findMostDerivedMetatype(PyObject[] bases_list, PyType initialMetatype) { + private static PyType findMostDerivedMetatype(PyTuple bases, PyType initialMetatype) { PyType winner = initialMetatype; - for (PyObject base : bases_list) { + for (PyObject base : bases.asIterable()) { if (base instanceof PyClass) { continue; } @@ -1089,137 +677,13 @@ } public static void addBuilder(Class<?> forClass, TypeBuilder builder) { - if (classToBuilder == null) { - classToBuilder = Generic.map(); - } - classToBuilder.put(forClass, builder); - - if (class_to_type.containsKey(forClass)) { - if (!Py.BOOTSTRAP_TYPES.remove(forClass)) { - Py.writeWarning("init", "Bootstrapping class not in Py.BOOTSTRAP_TYPES[class=" - + forClass + "]"); - } - // The types in Py.BOOTSTRAP_TYPES are initialized before their builders are assigned, - // so do the work of addFromClass & fillFromClass after the fact - fromClass(builder.getTypeClass()).init(builder.getTypeClass(), null); - } + PyBuiltinType.addBuilder(forClass, builder); } - private static PyType addFromClass(Class<?> c, Set<PyJavaType> needsInners) { - if (ExposeAsSuperclass.class.isAssignableFrom(c)) { - PyType exposedAs = fromClass(c.getSuperclass()); - class_to_type.put(c, exposedAs); - return exposedAs; - } - return createType(c, needsInners); - } - - private static TypeBuilder getBuilder(Class<?> c) { - if (classToBuilder == null) { - // PyType itself has yet to be initialized. This should be a bootstrap type, so it'll - // go through the builder process in a second - return null; - } - if (c.isPrimitive() || !PyObject.class.isAssignableFrom(c)) { - // If this isn't a PyObject, don't bother forcing it to be initialized to load its - // builder - return null; - } - - // This is a PyObject, call forName to force static initialization on the class so if it has - // a builder, it'll be filled in - SecurityException exc = null; - try { - Class.forName(c.getName(), true, c.getClassLoader()); - } catch (ClassNotFoundException e) { - // Well, this is certainly surprising. - throw new RuntimeException("Got ClassNotFound calling Class.forName on an already " - + " found class.", e); - } catch (ExceptionInInitializerError e) { - throw Py.JavaError(e); - } catch (SecurityException e) { - exc = e; - } - TypeBuilder builder = classToBuilder.get(c); - if (builder == null && exc != null) { - Py.writeComment("type", - "Unable to initialize " + c.getName() + ", a PyObject subclass, due to a " + - "security exception, and no type builder could be found for it. If it's an " + - "exposed type, it may not work properly. Security exception: " + - exc.getMessage()); - } - return builder; - } - - private static PyType createType(Class<?> c, Set<PyJavaType> needsInners) { - PyType newtype; - if (c == PyType.class) { - newtype = new PyType(false); - } else if (Py.BOOTSTRAP_TYPES.contains(c) || getBuilder(c) != null) { - newtype = new PyType(); - } else { - newtype = new PyJavaType(); - } - - - // If filling in the type above filled the type under creation, use that one - PyType type = class_to_type.get(c); - if (type != null) { - return type; - } - - class_to_type.put(c, newtype); - newtype.builtin = true; - newtype.init(c,needsInners); - return newtype; - } - public static synchronized PyType fromClass(Class<?> c) { - if (class_to_type == null) { - class_to_type = Generic.map(); - addFromClass(PyType.class, null); - } - PyType type = class_to_type.get(c); - if (type != null) { - return type; - } - // We haven't seen this class before, so it's type needs to be created. If it's being - // exposed as a Java class, defer processing its inner types until it's completely - // created in case the inner class references a class that references this class. - Set<PyJavaType> needsInners = Generic.set(); - PyType result = addFromClass(c, needsInners); - for (PyJavaType javaType : needsInners) { - Class<?> forClass = javaType.getProxyType(); - if (forClass == null) { - continue; - } - for (Class<?> inner : forClass.getClasses()) { - // Only add the class if there isn't something else with that name and it came from this - // class - if (inner.getDeclaringClass() == forClass && - javaType.dict.__finditem__(inner.getSimpleName()) == null) { - // If this class is currently being loaded, any exposed types it contains won't have - // set their builder in PyType yet, so add them to BOOTSTRAP_TYPES so they're - // created as PyType instead of PyJavaType - if (inner.getAnnotation(ExposedType.class) != null - || ExposeAsSuperclass.class.isAssignableFrom(inner)) { - Py.BOOTSTRAP_TYPES.add(inner); - } - javaType.dict.__setitem__(inner.getSimpleName(), PyType.fromClass(inner)); - } - } - } - return result; + return PyBuiltinType.fromClass(c); } - static PyType fromClassSkippingInners(Class<?> c, Set<PyJavaType> needsInners) { - PyType type = class_to_type.get(c); - if (type != null) { - return type; - } - return addFromClass(c, needsInners); - } - @ExposedMethod(doc = BuiltinDocs.type___getattribute___doc) final PyObject type___getattribute__(PyObject name) { String n = asName(name); @@ -1535,46 +999,6 @@ fastGetName(), name)); } - //XXX: consider pulling this out into a generally accessible place - // I bet this is duplicated more or less in other places. - private static String confirmIdentifier(PyObject obj) { - String identifier; - if (!(obj instanceof PyString)) { - throw Py.TypeError(String.format("__slots__ items must be strings, not '%.200s'", - obj.getType().fastGetName())); - } else if (obj instanceof PyUnicode) { - identifier = ((PyUnicode)obj).encode(); - } else { - identifier = obj.toString(); - } - - String msg = "__slots__ must be identifiers"; - if (identifier.length() == 0 - || (!Character.isLetter(identifier.charAt(0)) && identifier.charAt(0) != '_')) { - throw Py.TypeError(msg); - } - for (char c : identifier.toCharArray()) { - if (!Character.isLetterOrDigit(c) && c != '_') { - throw Py.TypeError(msg); - } - } - return identifier; - } - - //XXX: copied from CodeCompiler.java and changed variable names. - // Maybe this should go someplace for all classes to use. - private static String mangleName(String classname, String methodname) { - if (classname != null && methodname.startsWith("__") && !methodname.endsWith("__")) { - //remove leading '_' from classname - int i = 0; - while (classname.charAt(i) == '_') { - i++; - } - return ("_" + classname.substring(i) + methodname).intern(); - } - return methodname; - } - /** Used when serializing this type. */ protected Object writeReplace() { return new TypeResolver(underlying_class, getModule().toString(), getName()); Deleted: branches/customizable-proxymaker/src/org/python/core/PyTypeDerived.java =================================================================== --- branches/customizable-proxymaker/src/org/python/core/PyTypeDerived.java 2009-08-22 07:46:25 UTC (rev 6702) +++ branches/customizable-proxymaker/src/org/python/core/PyTypeDerived.java 2009-08-22 07:53:18 UTC (rev 6703) @@ -1,1138 +0,0 @@ -/* Generated file, do not modify. See jython/src/templates/gderived.py. */ -package org.python.core; - -import java.io.Serializable; - -public class PyTypeDerived extends PyType implements Slotted { - - public PyObject getSlot(int index) { - return slots[index]; - } - - public void setSlot(int index,PyObject value) { - slots[index]=value; - } - - private PyObject[]slots; - - public PyTypeDerived(PyType subtype) { - super(subtype); - slots=new PyObject[subtype.getNumSlots()]; - } - - public PyString __str__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__str__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__str__"+" returned non-"+"string"+" (type "+res.getType().fastGetName()+")"); - } - return super.__str__(); - } - - public PyString __repr__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__repr__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__repr__"+" returned non-"+"string"+" (type "+res.getType().fastGetName()+")"); - } - return super.__repr__(); - } - - public PyString __hex__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__hex__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__hex__"+" returned non-"+"string"+" (type "+res.getType().fastGetName()+")"); - } - return super.__hex__(); - } - - public PyString __oct__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__oct__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__oct__"+" returned non-"+"string"+" (type "+res.getType().fastGetName()+")"); - } - return super.__oct__(); - } - - public PyFloat __float__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__float__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyFloat) - return(PyFloat)res; - throw Py.TypeError("__float__"+" returned non-"+"float"+" (type "+res.getType().fastGetName()+")"); - } - return super.__float__(); - } - - public PyComplex __complex__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__complex__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyComplex) - return(PyComplex)res; - throw Py.TypeError("__complex__"+" returned non-"+"complex"+" (type "+res.getType().fastGetName()+")"); - } - return super.__complex__(); - } - - public PyObject __pos__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__pos__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__pos__(); - } - - public PyObject __neg__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__neg__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__neg__(); - } - - public PyObject __abs__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__abs__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__abs__(); - } - - public PyObject __invert__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__invert__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__invert__(); - } - - public PyObject __reduce__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__reduce__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__reduce__(); - } - - public PyObject __add__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__add__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__add__(other); - } - - public PyObject __radd__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__radd__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__radd__(other); - } - - public PyObject __sub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__sub__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__sub__(other); - } - - public PyObject __rsub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rsub__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rsub__(other); - } - - public PyObject __mul__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__mul__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__mul__(other); - } - - public PyObject __rmul__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rmul__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rmul__(other); - } - - public PyObject __div__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__div__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__div__(other); - } - - public PyObject __rdiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rdiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rdiv__(other); - } - - public PyObject __floordiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__floordiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__floordiv__(other); - } - - public PyObject __rfloordiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rfloordiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rfloordiv__(other); - } - - public PyObject __truediv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__truediv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__truediv__(other); - } - - public PyObject __rtruediv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rtruediv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rtruediv__(other); - } - - public PyObject __mod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__mod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__mod__(other); - } - - public PyObject __rmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rmod__(other); - } - - public PyObject __divmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__divmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__divmod__(other); - } - - public PyObject __rdivmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rdivmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rdivmod__(other); - } - - public PyObject __rpow__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rpow__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rpow__(other); - } - - public PyObject __lshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__lshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__lshift__(other); - } - - public PyObject __rlshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rlshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rlshift__(other); - } - - public PyObject __rshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rshift__(other); - } - - public PyObject __rrshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rrshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rrshift__(other); - } - - public PyObject __and__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__and__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__and__(other); - } - - public PyObject __rand__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rand__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rand__(other); - } - - public PyObject __or__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__or__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__or__(other); - } - - public PyObject __ror__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ror__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__ror__(other); - } - - public PyObject __xor__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__xor__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__xor__(other); - } - - public PyObject __rxor__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rxor__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rxor__(other); - } - - public PyObject __lt__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__lt__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__lt__(other); - } - - public PyObject __le__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__le__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__le__(other); - } - - public PyObject __gt__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__gt__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__gt__(other); - } - - public PyObject __ge__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ge__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__ge__(other); - } - - public PyObject __eq__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__eq__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__eq__(other); - } - - public PyObject __ne__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ne__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__ne__(other); - } - - public PyObject __iadd__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__iadd__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__iadd__(other); - } - - public PyObject __isub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__isub__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__isub__(other)... [truncated message content] |