From: <pj...@us...> - 2008-04-04 23:37:44
|
Revision: 4294 http://jython.svn.sourceforge.net/jython/?rev=4294&view=rev Author: pjenvey Date: 2008-04-04 16:37:43 -0700 (Fri, 04 Apr 2008) Log Message: ----------- o add PyBaseException, as a real java class (as it's easier that way) o make exceptions new style classes (subclass BaseException). we still generate the other exceptions in exceptions.java as its easier (they're simpler) o make all the various Exception variables slots -- so 2.5 Exceptions' __dict__ can be lazily created o cleanup the exceptions.java Exception methods to take self -- mainly so args doesn't include it, which fixes ArgParser reporting incorrect indices o ensure UnicodeEncodeError's object is unicode o rename PyException.initialize to normalize to more closely match CPython Modified Paths: -------------- branches/pep352/CoreExposed.includes branches/pep352/src/org/python/core/Py.java branches/pep352/src/org/python/core/PyException.java branches/pep352/src/org/python/core/codecs.java branches/pep352/src/org/python/core/exceptions.java branches/pep352/src/templates/mappings Added Paths: ----------- branches/pep352/src/org/python/core/PyBaseException.java branches/pep352/src/org/python/core/PyBaseExceptionDerived.java branches/pep352/src/templates/BaseException.derived Modified: branches/pep352/CoreExposed.includes =================================================================== --- branches/pep352/CoreExposed.includes 2008-04-04 23:24:29 UTC (rev 4293) +++ branches/pep352/CoreExposed.includes 2008-04-04 23:37:43 UTC (rev 4294) @@ -1,5 +1,6 @@ org/python/core/PyArray.class org/python/core/PyBaseString.class +org/python/core/PyBaseException.class org/python/core/PyBoolean.class org/python/core/PyBuiltinFunction.class org/python/core/PyClassMethod.class Modified: branches/pep352/src/org/python/core/Py.java =================================================================== --- branches/pep352/src/org/python/core/Py.java 2008-04-04 23:24:29 UTC (rev 4293) +++ branches/pep352/src/org/python/core/Py.java 2008-04-04 23:37:43 UTC (rev 4294) @@ -225,14 +225,10 @@ return new PyException(Py.SystemExit, message); }*/ static void maybeSystemExit(PyException exc) { - //System.err.println("maybeSystemExit: " + exc.type.toString()); if (Py.matchException(exc, Py.SystemExit)) { PyObject value = exc.value; - //System.err.println("exiting: "+value.getClass().getName()); - if (value instanceof PyInstance) { - PyObject tmp = value.__findattr__("code"); - if (tmp != null) - value = tmp; + if (isExceptionInstance(exc.value)) { + value = value.__findattr__("code"); } Py.getSystemState().callExitFunc(); if (value instanceof PyInteger) { @@ -242,8 +238,9 @@ try { Py.println(value); System.exit(1); + } catch (Throwable t) { + // continue } - catch (Throwable t0) { } } System.exit(0); } @@ -307,7 +304,7 @@ int end, String reason) { return new PyException(Py.UnicodeEncodeError, new PyTuple(new PyString(encoding), - new PyString(object), + new PyUnicode(object), new PyInteger(start), new PyInteger(end), new PyString(reason))); @@ -343,6 +340,7 @@ public static PyObject LookupError; public static PyObject StandardError; public static PyObject Exception; + public static PyObject BaseException; public static PyObject Warning; public static void Warning(String message) { @@ -665,6 +663,7 @@ static void initClassExceptions(PyObject dict) { PyObject exc = imp.load("exceptions"); + BaseException = initExc("BaseException", exc, dict); Exception = initExc("Exception", exc, dict); SystemExit = initExc("SystemExit", exc, dict); StopIteration = initExc("StopIteration", exc, dict); @@ -956,6 +955,7 @@ try { exceptHook.__call__(exc.type, exc.value, exc.traceback); } catch (PyException exc2) { + // XXX: normalize is done here, Python/pythonrun.c PyErr_PrintEx stderr.println("Error in sys.excepthook:"); displayException(exc2.type, exc2.value, exc2.traceback, file); stderr.println(); @@ -1007,8 +1007,23 @@ static String formatException(PyObject type, PyObject value, PyObject tb) { StringBuffer buf = new StringBuffer(); - if (type instanceof PyClass) { - buf.append(((PyClass) type).__name__); + if (isExceptionClass(type)) { + String className = exceptionClassName(type); + int lastDot = className.lastIndexOf('.'); + if (lastDot != -1) { + className = className.substring(lastDot + 1); + } + PyObject moduleName = type.__findattr__("__module__"); + if (moduleName == null) { + buf.append("<unknown>"); + } else { + String moduleStr = moduleName.toString(); + if (!moduleStr.equals("exceptions")) { + buf.append(moduleStr); + buf.append("."); + } + } + buf.append(className); } else { buf.append(type.__str__()); } @@ -1048,7 +1063,7 @@ /* Helpers to implement except clauses */ public static PyException setException(Throwable t, PyFrame frame) { PyException pye = Py.JavaError(t); - pye.instantiate(); + pye.normalize(); // attach catching frame if (frame != null && pye.traceback.tb_frame != frame && pye.traceback.tb_frame.f_back != null) { @@ -1063,7 +1078,7 @@ } public static boolean matchException(PyException pye, PyObject e) { - pye.instantiate(); + pye.normalize(); // FIXME, see bug 737978 // // A special case for IOError's to allow them to also match @@ -1082,8 +1097,28 @@ return true; } } - if(e instanceof PyClass) { - return __builtin__.isinstance(pye.value, e); + if (e instanceof PyClass) { + try { + return __builtin__.issubclass(pye.type, e); + } catch (PyException subclassE) { + if (!matchException(subclassE, TypeError)) { + throw subclassE; + } + return false; + } + } else if (e instanceof PyType) { + if (pye.type == e) { + return true; + } else { + try { + return __builtin__.issubclass(pye.type, e); + } catch (PyException subclassE) { + if (!matchException(subclassE, TypeError)) { + throw subclassE; + } + return false; + } + } } else { if(e == pye.type) return true; @@ -1098,55 +1133,110 @@ } } - /* Implement the raise statement */ - // reraise the current exception - public static PyException makeException() { - ThreadState ts = getThreadState(); - if (ts.exception == null) { - throw Py.ValueError("no exception to reraise"); - } - return ts.exception; + + // XXX: the following 4 are backwards compat. for the + // oldcompiler. newcompiler should just call doRaise instead + public static PyException makeException(PyObject type, PyObject value, + PyObject traceback) { + return doRaise(type, value, traceback); } + public static PyException makeException(PyObject type, PyObject value) { + return makeException(type, value, null); + } + public static PyException makeException(PyObject type) { - if (type instanceof PyInstance) { - return new PyException(type.fastGetClass(), type); - } else { - return makeException(type, Py.None); - } + return makeException(type, null); } - public static PyException makeException(PyObject type, PyObject value) { - if (type instanceof PyInstance) { - if (value != Py.None) { - throw TypeError("instance exceptions may not have " + - "a separate value"); - } else { - return new PyException(type.fastGetClass(), type); - } - } - PyException exc = new PyException(type, value); - exc.instantiate(); - return exc; + public static PyException makeException() { + return makeException(null); } - public static PyException makeException(PyObject type, PyObject value, - PyObject traceback) - { - if (type instanceof PyInstance) { + /** + * Determine whether obj is a Python Exception class + * + * @param obj a PyObject + * @return true if an exception + */ + public static boolean isExceptionClass(PyObject obj) { + return obj instanceof PyClass + || (obj instanceof PyType && ((PyType)obj).isSubType((PyType)Py.BaseException)); + } + + /** + * Determine whether obj is an Exception instance + * + * @param obj a PyObject + * @return true if an exception instance + */ + public static boolean isExceptionInstance(PyObject obj) { + return obj instanceof PyInstance || obj.getType().isSubType((PyType)Py.BaseException); + } + + /** + * Get the name of the exception's class + * + * @param obj a PyObject exception + * @return String exception name + */ + public static String exceptionClassName(PyObject obj) { + return obj instanceof PyClass ? ((PyClass)obj).__name__ : ((PyType)obj).fastGetName(); + } + + /** + * Logic for the raise statement + * + * @param type the first arg to raise, a type or an instance + * @param value the second arg, the instance of the class or + * arguments to its constructor + * @param tb a traceback object + * @return a PyException wrapper + */ + public static PyException doRaise(PyObject type, PyObject value, PyObject traceback) { + if (type == null) { + ThreadState state = getThreadState(); + type = state.exception.type; + value = state.exception.value; + traceback = state.exception.traceback; + } + + if (traceback == Py.None) { + traceback = null; + } else if (traceback != null && !(traceback instanceof PyTraceback)) { + throw Py.TypeError("raise: arg 3 must be a traceback or None"); + } + + if (value == null) { + value = Py.None; + } + + // Repeatedly, replace a tuple exception with its first item + while (type instanceof PyTuple && ((PyTuple)type).size() > 0) { + type = type.__getitem__(0); + } + + if (type.getClass() == PyString.class) { + Py.warning(Py.DeprecationWarning, "raising a string exception is deprecated"); + } else if (isExceptionClass(type)) { + PyException pye = new PyException(type, value, (PyTraceback)traceback); + pye.normalize(); + return pye; + } else if (isExceptionInstance(type)) { + // Raising an instance. The value should be a dummy. if (value != Py.None) { - throw TypeError("instance exceptions may not have " + - "a separate value"); + throw Py.TypeError("instance exception may not have a separate value"); } else { + // Normalize to raise <class>, <instance> + value = type; type = type.fastGetClass(); } + } else { + // Not something you can raise. You get an exception + // anyway, just not what you specified :-) + throw Py.TypeError("exceptions must be classes, instances, or strings (deprecated), " + + "not " + type.getType().fastGetName()); } - - if (traceback == None) - return new PyException(type, value); - if (!(traceback instanceof PyTraceback)) - throw TypeError("raise 3rd arg must be traceback or None"); - return new PyException(type, value, (PyTraceback)traceback); } Added: branches/pep352/src/org/python/core/PyBaseException.java =================================================================== --- branches/pep352/src/org/python/core/PyBaseException.java (rev 0) +++ branches/pep352/src/org/python/core/PyBaseException.java 2008-04-04 23:37:43 UTC (rev 4294) @@ -0,0 +1,202 @@ +/* Copyright (c) 2008 Jython Developers */ +package org.python.core; + +import org.python.expose.ExposedDelete; +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; + +/** + * The base class for all standard Python exceptions. + * + */ +@ExposedType(name = "exceptions.BaseException") +public class PyBaseException extends PyObject { + + public static final PyType TYPE = PyType.fromClass(PyBaseException.class); + + /** Exception message. */ + @ExposedGet + @ExposedSet + public PyObject message = Py.newString(""); + + /** Exception's arguments. */ + @ExposedGet + public PyObject args = Py.EmptyTuple; + + /** Exception's underlying dictionary, lazily created. */ + public PyObject __dict__; + + public PyBaseException() { + super(); + } + + public PyBaseException(PyType subType) { + super(subType); + } + + public void __init__(PyObject[] args, String[] keywords) { + BaseException___init__(args, keywords); + } + + @ExposedNew + @ExposedMethod + final void BaseException___init__(PyObject[] args, String[] keywords) { + ArgParser ap = new ArgParser(getType().getName(), args, keywords, "args"); + ap.noKeywords(); + this.args = ap.getList(0); + if (args.length == 1) { + message = args[0]; + } + } + + public PyObject __getitem__(PyObject index) { + return BaseException___getitem__(index); + } + + @ExposedMethod + final PyObject BaseException___getitem__(PyObject index) { + return args.__getitem__(index); + } + + public PyObject __getslice__(PyObject start, PyObject stop) { + return BaseException___getslice__(start, stop); + } + + @ExposedMethod + final PyObject BaseException___getslice__(PyObject start, PyObject stop) { + return args.__getslice__(start, stop); + } + + + public PyObject __reduce__() { + return BaseException___reduce__(); + } + + @ExposedMethod + final PyObject BaseException___reduce__() { + if (__dict__ != null) { + return new PyTuple(getType(), args, __dict__); + } else { + return new PyTuple(getType(), args); + } + } + + public PyObject __setstate__(PyObject state) { + return BaseException___setstate__(state); + } + + @ExposedMethod + final PyObject BaseException___setstate__(PyObject state) { + if (state != Py.None) { + if (!(state instanceof PyStringMap)) { + throw Py.TypeError("state is not a dictionary"); + } + for (PyObject key : state.asIterable()) { + __setattr__((PyString)key, state.__finditem__(key)); + } + } + return Py.None; + } + + public PyObject __findattr__(String name) { + return BaseException___findattr__(name); + } + + final PyObject BaseException___findattr__(String name) { + if (__dict__ != null) { + PyObject attr = __dict__.__finditem__(name); + if (attr != null) { + return attr; + } + } + + return super.__findattr__(name); + } + + public void __setattr__(String name, PyObject value) { + BaseException___setattr__(name, value); + } + + @ExposedMethod + final void BaseException___setattr__(String name, PyObject value) { + ensureDict(); + super.__setattr__(name, value); + } + + public PyObject fastGetDict() { + return __dict__; + } + + @ExposedGet(name = "__dict__") + public PyObject getDict() { + ensureDict(); + return __dict__; + } + + @ExposedSet(name = "__dict__") + public void setDict(PyObject val) { + if (!(val instanceof PyStringMap)) { + throw Py.TypeError("__dict__ must be a dictionary"); + } + __dict__ = val; + } + + private void ensureDict() { + if (__dict__ == null) { + __dict__ = new PyStringMap(); + } + } + + public PyString __str__() { + return BaseException___str__(); + } + + @ExposedMethod + final PyString BaseException___str__() { + switch (args.__len__()) { + case 0: + return Py.newString(""); + case 1: + return args.__getitem__(0).__str__(); + default: + return args.__str__(); + } + } + + public String toString() { + return __repr__().toString(); + } + + public PyString __repr__() { + return BaseException___repr__(); + } + + @ExposedMethod + final PyString BaseException___repr__() { + PyObject reprSuffix = args.__repr__(); + String name = getType().fastGetName(); + int lastDot = name.lastIndexOf('.'); + if (lastDot != -1) { + name = name.substring(lastDot + 1); + } + return Py.newString(name + reprSuffix.toString()); + } + + @ExposedSet(name = "args") + public void setArgs(PyObject val) { + args = PyTuple.fromIterable(val); + } + + @ExposedDelete(name = "message") + public void delMessage() { + message = Py.None; + } + + @ExposedDelete(name = "args") + public void delArgs() { + args = Py.None; + } +} Added: branches/pep352/src/org/python/core/PyBaseExceptionDerived.java =================================================================== --- branches/pep352/src/org/python/core/PyBaseExceptionDerived.java (rev 0) +++ branches/pep352/src/org/python/core/PyBaseExceptionDerived.java 2008-04-04 23:37:43 UTC (rev 4294) @@ -0,0 +1,930 @@ +package org.python.core; + +public class PyBaseExceptionDerived extends PyBaseException implements Slotted { + + public PyObject getSlot(int index) { + return slots[index]; + } + + public void setSlot(int index,PyObject value) { + slots[index]=value; + } + + private PyObject[]slots; + + public PyBaseExceptionDerived(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__"+" should return a "+"string"); + } + 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__"+" should return a "+"string"); + } + 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__"+" should return a "+"string"); + } + 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__"+" should return a "+"string"); + } + 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__"+" should return a "+"float"); + } + return super.__float__(); + } + + public PyLong __long__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__long__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyLong) + return(PyLong)res; + throw Py.TypeError("__long__"+" should return a "+"long"); + } + return super.__long__(); + } + + 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__"+" should return a "+"complex"); + } + 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 __pow__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__pow__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } + return super.__pow__(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) + return impl.__get__(this,self_type).__call__(other); + return super.__iadd__(other); + } + + public PyObject __isub__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__isub__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__isub__(other); + } + + public PyObject __imul__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__imul__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__imul__(other); + } + + public PyObject __idiv__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__idiv__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__idiv__(other); + } + + public PyObject __ifloordiv__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__ifloordiv__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__ifloordiv__(other); + } + + public PyObject __itruediv__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__itruediv__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__itruediv__(other); + } + + public PyObject __imod__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__imod__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__imod__(other); + } + + public PyObject __ipow__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__ipow__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__ipow__(other); + } + + public PyObject __ilshift__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__ilshift__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__ilshift__(other); + } + + public PyObject __irshift__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__irshift__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__irshift__(other); + } + + public PyObject __iand__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__iand__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__iand__(other); + } + + public PyObject __ior__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__ior__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__ior__(other); + } + + public PyObject __ixor__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__ixor__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(other); + return super.__ixor__(other); + } + + public PyObject __int__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__int__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyInteger||res instanceof PyLong) + return(PyObject)res; + throw Py.TypeError("__int__"+" should return an integer"); + } + return super.__int__(); + } + + public String toString() { + 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)) + throw Py.TypeError("__repr__ should return a string"); + return((PyString)res).toString(); + } + return super.toString(); + } + + public int hashCode() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__hash__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyInteger) + return((PyInteger)res).getValue(); + throw Py.TypeError("__hash__ should return a int"); + } + if (self_type.lookup("__eq__")!=null||self_type.lookup("__cmp__")!=null) + throw Py.TypeError("unhashable type"); + return super.hashCode(); + } + + public PyUnicode __unicode__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__unicode__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyUnicode) + return(PyUnicode)res; + if (res instanceof PyString) + return new PyUnicode((PyString)res); + throw Py.TypeError("__unicode__"+" should return a "+"unicode"); + } + return super.__unicode__(); + } + + public int __cmp__(PyObject other) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__cmp__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res instanceof PyInteger) { + int v=((PyInteger)res).getValue(); + return v<0?-1:v>0?1:0; + } + throw Py.TypeError("__cmp__ should return a int"); + } + return super.__cmp__(other); + } + + public boolean __nonzero__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__nonzero__"); + if (impl==null) { + impl=self_type.lookup("__len__"); + if (impl==null) + return super.__nonzero__(); + } + return impl.__get__(this,self_type).__call__().__nonzero__(); + } + + public boolean __contains__(PyObject o) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__contains__"); + if (impl==null) + return super.__contains__(o); + return impl.__get__(this,self_type).__call__(o).__nonzero__(); + } + + public int __len__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__len__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyInteger) + return((PyInteger)res).getValue(); + throw Py.TypeError("__len__ should return a int"); + } + return super.__len__(); + } + + public PyObject __iter__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__iter__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(); + impl=self_type.lookup("__getitem__"); + if (impl==null) + return super.__iter__(); + return new PySequenceIter(this); + } + + public PyObject __iternext__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("next"); + if (impl!=null) { + try { + return impl.__get__(this,self_type).__call__(); + } catch (PyException exc) { + if (Py.matchException(exc,Py.StopIteration)) + return null; + throw exc; + } + } + return super.__iternext__(); // ??? + } + + public PyObject __finditem__(PyObject key) { // ??? + PyType self_type=getType(); + PyObject impl=self_type.lookup("__getitem__"); + if (impl!=null) + try { + return impl.__get__(this,self_type).__call__(key); + } catch (PyException exc) { + if (Py.matchException(exc,Py.LookupError)) + return null; + throw exc; + } + return super.__finditem__(key); + } + + public void __setitem__(PyObject key,PyObject value) { // ??? + PyType self_type=getType(); + PyObject impl=self_type.lookup("__setitem__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(key,value); + return; + } + super.__setitem__(key,value); + } + + public PyObject __getslice__(PyObject start,PyObject stop,PyObject step) { // ??? + PyType self_type=getType(); + PyObject impl=self_type.lookup("__getslice__"); + if (impl!=null) + try { + return impl.__get__(this,self_type).__call__(start,stop); + } catch (PyException exc) { + if (Py.matchException(exc,Py.LookupError)) + return null; + throw exc; + } + return super.__getslice__(start,stop,step); + } + + public void __delitem__(PyObject key) { // ??? + PyType self_type=getType(); + PyObject impl=self_type.lookup("__delitem__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(key); + return; + } + super.__delitem__(key); + } + + public PyObject __call__(PyObject args[],String keywords[]) { + ThreadState ts=Py.getThreadState(); + if (ts.recursion_depth++>ts.systemState.getrecursionlimit()) + throw Py.RuntimeError("maximum __call__ recursion depth exceeded"); + try { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__call__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(args,keywords); + return super.__call__(args,keywords); + } finally { + --ts.recursion_depth; + } + } + + public PyObject __findattr__(String name) { + PyType self_type=getType(); + PyObject getattribute=self_type.lookup("__getattribute__"); + PyString py_name=null; + try { + if (getattribute!=null) { + return getattribute.__get__(this,self_type).__call__(py_name=PyString.fromInterned(name)); + } else { + return super.__findattr__(name); + } + } catch (PyException e) { + if (Py.matchException(e,Py.AttributeError)) { + PyObject getattr=self_type.lookup("__getattr__"); + if (getattr!=null) + try { + return getattr.__get__(this,self_type).__call__(py_name!=null?py_name:PyString.fromInterned(name)); + } catch (PyException e1) { + if (!Py.matchException(e1,Py.AttributeError)) + throw e1; + } + return null; + } + throw e; + } + } + + public void __setattr__(String name,PyObject value) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__setattr__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(PyString.fromInterned(name),value); + return; + } + super.__setattr__(name,value); + } + + public void __delattr__(String name) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__delattr__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(PyString.fromInterned(name)); + return; + } + super.__delattr__(name); + } + + public PyObject __get__(PyObject obj,PyObject type) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__get__"); + if (impl!=null) { + if (obj==null) + obj=Py.None; + if (type==null) + type=Py.None; + return impl.__get__(this,self_type).__call__(obj,type); + } + return super.__get__(obj,type); + } + + public void __set__(PyObject obj,PyObject value) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__set__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(obj,value); + return; + } + super.__set__(obj,value); + } + + public void __delete__(PyObject obj) { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__delete__"); + if (impl!=null) { + impl.__get__(this,self_type).__call__(obj); + return; + } + super.__delete__(obj); + } + + public void dispatch__init__(PyType type,PyObject[]args,String[]keywords) { + PyType self_type=getType(); + if (self_type.isSubType(type)) { + PyObject impl=self_type.lookup("__init__"); + if (impl!=null) + impl.__get__(this,self_type).__call__(args,keywords); + } + } + +} Modified: branches/pep352/src/org/python/core/PyException.java =================================================================== --- branches/pep352/src/org/python/core/PyException.java 2008-04-04 23:24:29 UTC (rev 4293) +++ branches/pep352/src/org/python/core/PyException.java 2008-04-04 23:37:43 UTC (rev 4294) @@ -25,33 +25,8 @@ public PyObject value = Py.None; public PyTraceback traceback; - private boolean instantiated=false; - public void instantiate() { - if (!instantiated) { - // repeatedly, replace a tuple exception with its first item - while (type instanceof PyTuple && type.__len__() > 0) { - type = type.__getitem__(0); - } - if(type instanceof PyClass - && (!(value instanceof PyInstance && __builtin__.isinstance(value, type)))) { - if (value instanceof PyTuple) { - if (type == Py.KeyError) { - value = ((PyClass)type).__call__(new PyObject[] {value}); - } else { - value = ((PyClass)type).__call__(((PyTuple)value).getArray()); - } - } else { - if (value == Py.None) { - value = ((PyClass)type).__call__(Py.EmptyObjects); - } else { - value = ((PyClass)type).__call__(new PyObject[] {value}); - } - } - } - instantiated = true; - } - } + private boolean normalized = false; public PyException() { //System.out.println("PyException"); @@ -64,26 +39,27 @@ } public PyException(PyObject type, PyObject value) { + this(type, value, null); + } + + public PyException(PyObject type, PyObject value, PyTraceback traceback) { this.type = type; this.value = value; - PyFrame frame = Py.getFrame(); - traceback = new PyTraceback(frame); - if (frame != null && frame.tracefunc != null) { - frame.tracefunc = frame.tracefunc.traceException(frame, this); + if (traceback == null) { + PyFrame frame = Py.getFrame(); + traceback = new PyTraceback(frame); + if (frame != null && frame.tracefunc != null) { + frame.tracefunc = frame.tracefunc.traceException(frame, this); + } } + this.traceback = traceback; } public PyException(PyObject type, String value) { this(type, new PyString(value)); } - public PyException(PyObject type, PyObject value, PyTraceback traceback) { - this.type = type; - this.value = value; - this.traceback = traceback; - } - private boolean printingStackTrace = false; public void printStackTrace() { Py.printException(this); @@ -120,4 +96,40 @@ } return buf.toString(); } + + /** + * Instantiates the exception value if it is not already an + * instance. + * + */ + public void normalize() { + if (normalized) { + return; + } + PyObject inClass = null; + if (Py.isExceptionInstance(value)) { + inClass = value.fastGetClass(); + } + + if (Py.isExceptionClass(type)) { + if (inClass == null || !__builtin__.issubclass(inClass, type)) { + PyObject[] args; + + // Don't decouple a tuple into args when it's a + // KeyError, pass it on through below + if (value == Py.None) { + args = Py.EmptyObjects; + } else if (value instanceof PyTuple && type != Py.KeyError) { + args = ((PyTuple)value).getArray(); + } else { + args = new PyObject[] {value}; + } + + value = type.__call__(args); + } else if (inClass != type) { + type = inClass; + } + } + normalized = true; + } } Modified: branches/pep352/src/org/python/core/codecs.java =================================================================== --- branches/pep352/src/org/python/core/codecs.java 2008-04-04 23:24:29 UTC (rev 4293) +++ branches/pep352/src/org/python/core/codecs.java 2008-04-04 23:37:43 UTC (rev 4294) @@ -1060,7 +1060,7 @@ start, end, reason); - exc.instantiate(); + exc.normalize(); PyObject replacement = errorHandler.__call__(new PyObject[] {exc.value}); checkErrorHandlerReturn(errors, replacement); return replacement; @@ -1107,7 +1107,7 @@ start, end, reason); - exc.instantiate(); + exc.normalize(); return errorHandler.__call__(new PyObject[] {exc.value}); } Modified: branches/pep352/src/org/python/core/exceptions.java =================================================================== --- branches/pep352/src/org/python/core/exceptions.java 2008-04-04 23:24:29 UTC (rev 4293) +++ branches/pep352/src/org/python/core/exceptions.java 2008-04-04 23:37:43 UTC (rev 4294) @@ -1,91 +1,23 @@ // Copyright 2001 Finn Bock - package org.python.core; + +import java.io.File; +import java.lang.reflect.Method; + import org.python.modules.zipimport.zipimport; /** * The builtin exceptions module. The entire module should be imported from * python. None of the methods defined here should be called from java. */ - public class exceptions implements ClassDictInit { - public static String __doc__ = "Python's standard exception class hierarchy.\n" - + "\n" - + "Here is a rundown of the class hierarchy. The classes found here are\n" - + "inserted into both the exceptions module and the `built-in' module. " - + "It is\n" - + "recommended that user defined class based exceptions be derived from the\n" - + "`Exception' class, although this is currently not enforced.\n" - + "\n" - + "Exception\n" - + " |\n" - + " +-- GeneratorExit\n" - + " +-- SystemExit\n" - + " +-- StopIteration\n" - + " +-- StandardError\n" - + " | |\n" - + " | +-- KeyboardInterrupt\n" - + " | +-- ImportError\n" - + " | +-- EnvironmentError\n" - + " | | |\n" - + " | | +-- IOError\n" - + " | | +-- OSError\n" - + " | | |\n" - + " | | +-- WindowsError\n" - + " | |\n" - + " | +-- EOFError\n" - + " | +-- RuntimeError\n" - + " | | |\n" - + " | | +-- NotImplementedError\n" - + " | |\n" - + " | +-- NameError\n" - + " | | |\n" - + " | | +-- UnboundLocalError\n" - + " | |\n" - + " | +-- AttributeError\n" - + " | +-- SyntaxError\n" - + " | | |\n" - + " | | +-- IndentationError\n" - + " | | |\n" - + " | | +-- TabError\n" - + " | |\n" - + " | +-- TypeError\n" - + " | +-- AssertionError\n" - + " | +-- LookupError\n" - + " | | |\n" - + " | | +-- IndexError\n" - + " | | +-- KeyError\n" - + " | |\n" - + " | +-- ArithmeticError\n" - + " | | |\n" - + " | | +-- OverflowError\n" - + " | | +-- ZeroDivisionError\n" - + " | | +-- FloatingPointError\n" - + " | |\n" - + " | +-- ValueError\n" - + " | | |\n" - + " | | +-- UnicodeError\n" - + " | | |\n" - + " | | +-- UnicodeEncodeError\n" - + " | | +-- UnicodeDecodeError\n" - + " | | +-- UnicodeTranslateError\n" - + " | |\n" - + " | +-- ReferenceError\n" - + " | +-- SystemError\n" - + " | +-- MemoryError\n" - + " |\n" - + " +---Warning\n" - + " |\n" - + " +-- UserWarning\n" - + " +-- DeprecationWarning\n" - + " +-- SyntaxWarning\n" - + " +-- OverflowWarning\n" + " +-- RuntimeWarning"; + public static String __doc__ = + "Exceptions found here are defined both in the exceptions module and the " + + "built-in namespace. It is recommended that user-defined exceptions " + + "inherit from Exception. See the documentation for the exception " + + "inheritance hierarchy."; - private exceptions() { - ; - } - /** <i>Internal use only. Do not call this method explicit.</i> */ public static void classDictInit(PyObject dict) { dict.invoke("clear"); @@ -108,9 +40,17 @@ } ts.frame = frame; - buildClass(dict, "Exception", null, "Exception", - "Proposed base class for all exceptions."); + dict.__setitem__("BaseException", PyBaseException.TYPE); + buildClass(dict, "KeyboardInterrupt", "BaseException", "empty__init__", + "Program interrupted by user."); + + buildClass(dict, "SystemExit", "BaseException", "SystemExit", + "Request to exit from the interpreter.");... [truncated message content] |