From: <pj...@us...> - 2009-04-05 01:53:37
|
Revision: 6161 http://jython.svn.sourceforge.net/jython/?rev=6161&view=rev Author: pjenvey Date: 2009-04-05 01:53:25 +0000 (Sun, 05 Apr 2009) Log Message: ----------- convert PyClass to exposed annotations Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PyClass.java trunk/jython/src/org/python/modules/_newmodule.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/CoreExposed.includes 2009-04-05 01:53:25 UTC (rev 6161) @@ -6,6 +6,7 @@ org/python/core/PyBoolean.class org/python/core/PyBuiltinCallable.class org/python/core/PyCell.class +org/python/core/PyClass.class org/python/core/PyClassMethod.class org/python/core/PyClassMethodDescr.class org/python/core/PyComplex.class Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/src/org/python/core/Py.java 2009-04-05 01:53:25 UTC (rev 6161) @@ -1532,8 +1532,6 @@ String.class, PyTuple.class, PyObject.class, Class.class }; - static private final PyType CLASS_TYPE = PyType.fromClass(PyClass.class); - // XXX: The following two makeClass overrides are *only* for the // old compiler, they should be removed when the newcompiler hits public static PyObject makeClass(String name, PyObject[] bases, @@ -1590,21 +1588,10 @@ if (globals != null) { metaclass = globals.__finditem__("__metaclass__"); } - } - } - - if (metaclass == null || metaclass == CLASS_TYPE) { - boolean moreGeneral = false; - for (PyObject base : bases) { - if (!(base instanceof PyClass)) { - metaclass = base.getType(); - moreGeneral = true; - break; + if (metaclass == null) { + metaclass = PyClass.TYPE; } } - if (!moreGeneral) { - return new PyClass(name, new PyTuple(bases), dict); - } } try { Modified: trunk/jython/src/org/python/core/PyClass.java =================================================================== --- trunk/jython/src/org/python/core/PyClass.java 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/src/org/python/core/PyClass.java 2009-04-05 01:53:25 UTC (rev 6161) @@ -1,56 +1,91 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedSet; +import org.python.expose.ExposedType; + /** - * A python class. + * The classic Python class. */ +@ExposedType(name = "classobj", isBaseType = false) public class PyClass extends PyObject { - /** - * Holds the namespace for this class - */ + + public static final PyType TYPE = PyType.fromClass(PyClass.class); + + /** Holds the namespace for this class */ + @ExposedGet public PyObject __dict__; - /** - * The base classes of this class - */ + /** The base classes of this class */ + @ExposedGet public PyTuple __bases__; - /** - * The name of this class - */ + /** The name of this class */ + @ExposedGet + @ExposedSet public String __name__; - // Store these methods for performance optimization - // These are only used by PyInstance - PyObject __getattr__, __setattr__, __delattr__, __tojava__, __del__, - __contains__; + // Store these methods for performance optimization. These are only used by PyInstance + PyObject __getattr__, __setattr__, __delattr__, __tojava__, __del__, __contains__; - protected PyClass() { - super(); - } - /** - * Create a python class. - * - * @param name name of the class. - * @param bases A list of base classes. - * @param dict The class dict. Normally this dict is returned by the class - * code object. - * - * @see org.python.core.Py#makeClass(String, PyObject[], PyCode, PyObject) + * Create a new instance of a Python classic class. */ - public PyClass(String name, PyTuple bases, PyObject dict) { - __name__ = name; - __bases__ = bases; - __dict__ = dict; + private PyClass() { + super(TYPE); + } - findModule(dict); + @ExposedNew + public static PyObject classobj___new__(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + ArgParser ap = new ArgParser("function", args, keywords, "name", "bases", "dict"); + PyObject name = ap.getPyObject(0); + PyObject bases = ap.getPyObject(1); + PyObject dict = ap.getPyObject(2); + return classobj___new__(name, bases, dict); + } + public static PyObject classobj___new__(PyObject name, PyObject bases, PyObject dict) { + if (!name.getType().isSubType(PyString.TYPE)) { + throw Py.TypeError("PyClass_New: name must be a string"); + } + if (!(dict instanceof PyStringMap || dict instanceof PyDictionary)) { + throw Py.TypeError("PyClass_New: dict must be a dictionary"); + } if (dict.__finditem__("__doc__") == null) { dict.__setitem__("__doc__", Py.None); } + findModule(dict); - // Setup cached references to methods where performance really counts + if (!(bases instanceof PyTuple)) { + throw Py.TypeError("PyClass_New: bases must be a tuple"); + } + PyTuple basesTuple = (PyTuple)bases; + for (PyObject base : basesTuple.getArray()) { + if (!(base instanceof PyClass)) { + if (base.getType().isCallable()) { + return base.getType().__call__(name, bases, dict); + } else { + throw Py.TypeError("PyClass_New: base must be a class"); + } + } + } + + PyClass klass = new PyClass(); + klass.__name__ = name.toString(); + klass.__bases__ = basesTuple; + klass.__dict__ = dict; + klass.cacheDescriptors(); + return klass; + } + + /** + * Setup cached references to methods where performance really counts + */ + private void cacheDescriptors() { __getattr__ = lookup("__getattr__", false); __setattr__ = lookup("__setattr__", false); __delattr__ = lookup("__delattr__", false); @@ -59,7 +94,7 @@ __contains__ = lookup("__contains__", false); } - protected void findModule(PyObject dict) { + private static void findModule(PyObject dict) { PyObject module = dict.__finditem__("__module__"); if (module == null || module == Py.None) { PyFrame f = Py.getFrame(); @@ -89,68 +124,27 @@ return new PyObject[] { result, resolvedClass }; } - public PyObject fastGetDict() { - return __dict__; - } - PyObject lookup(String name, boolean stop_at_java) { PyObject[] result = lookupGivingClass(name, stop_at_java); return result[0]; } + @Override + public PyObject fastGetDict() { + return __dict__; + } + + @Override public PyObject __findattr_ex__(String name) { - if (name == "__dict__") { - return __dict__; - } - if (name == "__name__") { - return new PyString(__name__); - } - if (name == "__bases__") { - return __bases__; - } - if (name == "__class__") { - return null; - } - PyObject[] result = lookupGivingClass(name, false); - if (result[0] == null) { return super.__findattr_ex__(name); } - // xxx do we need to use result[1] (wherefound) for java cases for backw - // comp? + // XXX: do we need to use result[1] (wherefound) for java cases for backw comp? return result[0].__get__(null, this); } - public void __setattr__(String name, PyObject value) { - if (name == "__dict__") { - if (!value.isMappingType()) - throw Py.TypeError("__dict__ must be a dictionary object"); - __dict__ = value; - return; - } - if (name == "__name__") { - if (!(value instanceof PyString)) { - throw Py.TypeError("__name__ must be a string object"); - } - __name__ = value.toString(); - return; - } - if (name == "__bases__") { - if (!(value instanceof PyTuple)) { - throw Py.TypeError("__bases__ must be a tuple object"); - } - __bases__ = (PyTuple) value; - return; - } - - __dict__.__setitem__(name, value); - } - - public void __delattr__(String name) { - __dict__.__delitem__(name); - } - + @Override public void __rawdir__(PyDictionary accum) { mergeClassDict(accum, this); } @@ -158,25 +152,28 @@ /** * Customized AttributeError for class objects. */ + @Override public void noAttributeError(String name) { throw Py.AttributeError(String.format("class %.50s has no attribute '%.400s'", __name__, name)); } + @Override + @ExposedMethod public PyObject __call__(PyObject[] args, String[] keywords) { PyInstance inst; if (__del__ == null) { inst = new PyInstance(this); } else { - // the class defined an __del__ method + // the class defined a __del__ method inst = new PyFinalizableInstance(this); } inst.__init__(args, keywords); - return inst; } /* PyClass's are compared based on __name__ */ + @Override public int __cmp__(PyObject other) { if (!(other instanceof PyClass)) { return -2; @@ -185,6 +182,7 @@ return c < 0 ? -1 : c > 0 ? 1 : 0; } + @Override public PyString __str__() { // Current CPython standard is that str(class) prints as // module.class. If the class has no module, then just the class @@ -200,6 +198,7 @@ return new PyString(smod + "." + __name__); } + @Override public String toString() { PyObject mod = __dict__.__finditem__("__module__"); String smod; @@ -215,17 +214,35 @@ if (this == superclass) { return true; } - if (this.__bases__ == null || superclass.__bases__ == null) { + if (__bases__ == null || superclass.__bases__ == null) { return false; } - PyObject[] bases = this.__bases__.getArray(); - int n = bases.length; - for (int i = 0; i < n; i++) { - PyClass c = (PyClass) bases[i]; - if (c.isSubClass(superclass)) { + for (PyObject base: __bases__.getArray()) { + if (((PyClass)base).isSubClass(superclass)) { return true; } } return false; } + + @ExposedSet(name = "__dict__") + public void setDict(PyObject value) { + if (!(value instanceof PyStringMap || value instanceof PyDictionary)) { + throw Py.TypeError("__dict__ must be a dictionary object"); + } + __dict__ = value; + } + + @ExposedSet(name = "__bases__") + public void setBases(PyTuple value) { + for (PyObject base : value.getArray()) { + if (!(base instanceof PyClass)) { + throw Py.TypeError("__bases__ items must be classes"); + } + if (((PyClass)base).isSubClass(this)) { + throw Py.TypeError("a __bases__ item causes an inheritance cycle"); + } + } + __bases__ = value; + } } Modified: trunk/jython/src/org/python/modules/_newmodule.java =================================================================== --- trunk/jython/src/org/python/modules/_newmodule.java 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/src/org/python/modules/_newmodule.java 2009-04-05 01:53:25 UTC (rev 6161) @@ -33,6 +33,6 @@ return base.getType().__call__(Py.newString(name), bases, dict); } } - return new PyClass(name, bases, dict); + return Py.makeClass(name, bases.getArray(), dict); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |