|
From: <pj...@us...> - 2011-03-20 19:56:10
|
Revision: 7253
http://jython.svn.sourceforge.net/jython/?rev=7253&view=rev
Author: pjenvey
Date: 2011-03-20 19:56:03 +0000 (Sun, 20 Mar 2011)
Log Message:
-----------
o 2.6 core exception related changes
o fix exceptions.getString allowing unicode
Modified Paths:
--------------
trunk/jython/Lib/test/junit_xml.py
trunk/jython/src/org/python/core/PyBaseException.java
trunk/jython/src/org/python/core/PyException.java
trunk/jython/src/org/python/core/exceptions.java
Modified: trunk/jython/Lib/test/junit_xml.py
===================================================================
--- trunk/jython/Lib/test/junit_xml.py 2011-03-20 19:43:03 UTC (rev 7252)
+++ trunk/jython/Lib/test/junit_xml.py 2011-03-20 19:56:03 UTC (rev 7253)
@@ -248,8 +248,8 @@
exc = exc_info[1]
if exc is None:
return safe_str(exc_info[0])
- if isinstance(exc, BaseException) and isinstance(exc.message, unicode):
- return safe_str(exc.message)
+ if isinstance(exc, BaseException) and isinstance(exc.args[0], unicode):
+ return safe_str(exc.args[0])
try:
return safe_str(str(exc))
except UnicodeEncodeError:
Modified: trunk/jython/src/org/python/core/PyBaseException.java
===================================================================
--- trunk/jython/src/org/python/core/PyBaseException.java 2011-03-20 19:43:03 UTC (rev 7252)
+++ trunk/jython/src/org/python/core/PyBaseException.java 2011-03-20 19:56:03 UTC (rev 7253)
@@ -18,9 +18,7 @@
public static final PyType TYPE = PyType.fromClass(PyBaseException.class);
/** Exception message. */
- @ExposedGet(doc = BuiltinDocs.BaseException_message_doc)
- @ExposedSet
- public PyObject message = Py.EmptyString;
+ private PyObject message = Py.EmptyString;
/** Exception's arguments. */
@ExposedGet(doc = BuiltinDocs.BaseException_args_doc)
@@ -52,25 +50,32 @@
}
}
+ @Override
public PyObject __getitem__(PyObject index) {
return BaseException___getitem__(index);
}
@ExposedMethod(doc = BuiltinDocs.BaseException___getitem___doc)
final PyObject BaseException___getitem__(PyObject index) {
+ Py.warnPy3k("__getitem__ not supported for exception classes in 3.x; use args "
+ + "attribute");
return args.__getitem__(index);
}
+ @Override
public PyObject __getslice__(PyObject start, PyObject stop) {
return BaseException___getslice__(start, stop);
}
@ExposedMethod(doc = BuiltinDocs.BaseException___getslice___doc)
final PyObject BaseException___getslice__(PyObject start, PyObject stop) {
+ Py.warnPy3k("__getslice__ not supported for exception classes in 3.x; use args "
+ + "attribute");
return args.__getslice__(start, stop);
}
+ @Override
public PyObject __reduce__() {
return BaseException___reduce__();
}
@@ -101,6 +106,7 @@
return Py.None;
}
+ @Override
public PyObject __findattr_ex__(String name) {
return BaseException___findattr__(name);
}
@@ -116,6 +122,7 @@
return super.__findattr_ex__(name);
}
+ @Override
public void __setattr__(String name, PyObject value) {
BaseException___setattr__(name, value);
}
@@ -126,16 +133,19 @@
super.__setattr__(name, value);
}
+ @Override
public PyObject fastGetDict() {
return __dict__;
}
+ @Override
@ExposedGet(name = "__dict__", doc = BuiltinDocs.BaseException___dict___doc)
public PyObject getDict() {
ensureDict();
return __dict__;
}
+ @Override
@ExposedSet(name = "__dict__")
public void setDict(PyObject val) {
if (!(val instanceof PyStringMap) && !(val instanceof PyDictionary)) {
@@ -145,12 +155,14 @@
}
private void ensureDict() {
+ // XXX: __dict__ should really be volatile
if (__dict__ == null) {
__dict__ = new PyStringMap();
}
}
- public PyString __str__() {
+ @Override
+ public PyString __str__() {
return BaseException___str__();
}
@@ -167,6 +179,35 @@
}
@Override
+ public PyUnicode __unicode__() {
+ return BaseException___unicode__();
+ }
+
+ @ExposedMethod(doc = BuiltinDocs.BaseException___unicode___doc)
+ final PyUnicode BaseException___unicode__() {
+ // CPython issue6108: if __str__ has been overridden in the subclass, unicode()
+ // should return the message returned by __str__ as used to happen before this
+ // method was implemented
+ PyType type = getType();
+ PyObject[] where = new PyObject[1];
+ PyObject str = type.lookup_where("__str__", where);
+ if (str != null && where[0] != TYPE) {
+ // Unlike str(), __str__ can return unicode (i.e. return the equivalent
+ // of unicode(e.__str__()) instead of unicode(str(e)))
+ return str.__get__(this, type).__call__().__unicode__();
+ }
+
+ switch (args.__len__()) {
+ case 0:
+ return new PyUnicode("");
+ case 1:
+ return args.__getitem__(0).__unicode__();
+ default:
+ return args.__unicode__();
+ }
+ }
+
+ @Override
public String toString() {
return BaseException_toString();
}
@@ -187,8 +228,33 @@
args = PyTuple.fromIterable(val);
}
+ @ExposedGet(name = "message", doc = BuiltinDocs.BaseException_message_doc)
+ public PyObject getMessage() {
+ PyObject message;
+
+ // if "message" is in self->dict, accessing a user-set message attribute
+ if (__dict__ != null && (message = __dict__.__finditem__("message")) != null) {
+ return message;
+ }
+
+ if (this.message == null) {
+ throw Py.AttributeError("message attribute was deleted");
+ }
+
+ Py.DeprecationWarning("BaseException.message has been deprecated as of Python 2.6");
+ return this.message;
+ }
+
+ @ExposedSet(name = "message")
+ public void setMessage(PyObject value) {
+ getDict().__setitem__("message", value);
+ }
+
@ExposedDelete(name = "message")
public void delMessage() {
- message = Py.None;
+ if (__dict__ != null && (message = __dict__.__finditem__("message")) != null) {
+ __dict__.__delitem__("message");
+ message = null;
+ }
}
}
Modified: trunk/jython/src/org/python/core/PyException.java
===================================================================
--- trunk/jython/src/org/python/core/PyException.java 2011-03-20 19:43:03 UTC (rev 7252)
+++ trunk/jython/src/org/python/core/PyException.java 2011-03-20 19:56:03 UTC (rev 7253)
@@ -194,9 +194,7 @@
type = type.__getitem__(0);
}
- if (type.getType() == PyString.TYPE) {
- Py.warning(Py.DeprecationWarning, "raising a string exception is deprecated");
- } else if (isExceptionClass(type)) {
+ if (isExceptionClass(type)) {
PyException pye = new PyException(type, value, (PyTraceback)traceback);
pye.normalize();
return pye;
@@ -212,10 +210,14 @@
} 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());
+ throw Py.TypeError("exceptions must be old-style classes or derived from "
+ + "BaseException, not " + type.getType().fastGetName());
}
+ if (Options.py3kwarning && type instanceof PyClass) {
+ Py.DeprecationWarning("exceptions must derive from BaseException in 3.x");
+ }
+
return new PyException(type, value, (PyTraceback)traceback);
}
@@ -255,7 +257,13 @@
}
if (isExceptionClass(type) && isExceptionClass(exc)) {
- return Py.isSubClass(type, exc);
+ try {
+ return Py.isSubClass(type, exc);
+ } catch (PyException pye) {
+ // This function must not fail, so print the error here
+ Py.writeUnraisable(pye, type);
+ return false;
+ }
}
return type == exc;
Modified: trunk/jython/src/org/python/core/exceptions.java
===================================================================
--- trunk/jython/src/org/python/core/exceptions.java 2011-03-20 19:43:03 UTC (rev 7252)
+++ trunk/jython/src/org/python/core/exceptions.java 2011-03-20 19:56:03 UTC (rev 7253)
@@ -133,10 +133,12 @@
buildClass(dict, "MemoryError", "StandardError", "Out of memory.");
+ buildClass(dict, "BufferError", "StandardError", "Buffer error.");
+
buildClass(dict, "StopIteration", "Exception",
"Signal the end from iterator.next().");
- buildClass(dict, "GeneratorExit", "Exception", "Request that a generator exit.");
+ buildClass(dict, "GeneratorExit", "BaseException", "Request that a generator exit.");
buildClass(dict, "Warning", "Exception", "Base class for warning categories.");
@@ -166,10 +168,10 @@
buildClass(dict, "UnicodeWarning", "Warning",
"Base class for warnings about Unicode related problems, mostly\n"
+ "related to conversion problems.");
-
+
buildClass(dict, "BytesWarning", "Warning",
"Base class for warnings about bytes and buffer related problems, mostly\n"
- + "related to conversion from str or comparing to str.");
+ + "related to conversion from str or comparing to str.");
// Initialize ZipImportError here, where it's safe to; it's
// needed immediately
@@ -373,14 +375,16 @@
public static PyString UnicodeDecodeError__str__(PyObject self, PyObject[] args,
String[] kwargs) {
- int start = getStart(self, false);
- int end = getEnd(self, false);
- PyObject encoding = self.__getattr__("encoding");
- PyObject reason = self.__getattr__("reason");
+ int start = self.__getattr__("start").asInt();
+ int end = self.__getattr__("end").asInt();
+ // Get reason and encoding as strings, which they might not be if they've been
+ // modified after we were contructed
+ PyObject reason = self.__getattr__("reason").__str__();
+ PyObject encoding = self.__getattr__("encoding").__str__();
+ PyObject object = getString(self.__getattr__("object"), "object");
String result;
- if (end == (start + 1)) {
- PyObject object = self.__getattr__("object");
+ if (start < object.__len__() && end == (start + 1)) {
int badByte = (object.toString().charAt(start)) & 0xff;
result = String.format("'%.400s' codec can't decode byte 0x%x in position %d: %.400s",
encoding, badByte, start, reason);
@@ -406,14 +410,16 @@
public static PyString UnicodeEncodeError__str__(PyObject self, PyObject[] args,
String[] kwargs) {
- int start = getStart(self, true);
- int end = getEnd(self, true);
- PyObject encoding = self.__getattr__("encoding");
- PyObject reason = self.__getattr__("reason");
+ int start = self.__getattr__("start").asInt();
+ int end = self.__getattr__("end").asInt();
+ // Get reason and encoding as strings, which they might not be if they've been
+ // modified after we were contructed
+ PyObject reason = self.__getattr__("reason").__str__();
+ PyObject encoding = self.__getattr__("encoding").__str__();
+ PyObject object = getUnicode(self.__getattr__("object"), "object");
String result;
- if (end == (start + 1)) {
- PyObject object = self.__getattr__("object");
+ if (start < object.__len__() && end == (start + 1)) {
int badchar = object.toString().codePointAt(start);
String badcharStr;
if (badchar <= 0xff) {
@@ -455,13 +461,16 @@
public static PyString UnicodeTranslateError__str__(PyObject self, PyObject[] args,
String[] kwargs) {
- int start = getStart(self, true);
- int end = getEnd(self, true);
- PyObject reason = self.__getattr__("reason");
+ int start = self.__getattr__("start").asInt();
+ int end = self.__getattr__("end").asInt();
+ // Get reason as a string, which it might not be if it's been modified after we
+ // were contructed
+ PyObject reason = self.__getattr__("reason").__str__();
+ PyObject object = getUnicode(self.__getattr__("object"), "object");
String result;
- if (end == (start + 1)) {
- int badchar = (self.__getattr__("object").toString().codePointAt(start));
+ if (start < object.__len__() && end == (start + 1)) {
+ int badchar = object.toString().codePointAt(start);
String badCharStr;
if (badchar <= 0xff) {
badCharStr = String.format("x%02x", badchar);
@@ -488,7 +497,7 @@
* @return an the start position
*/
public static int getStart(PyObject self, boolean unicode) {
- int start = getInt(self.__getattr__("start"), "start");
+ int start = self.__getattr__("start").asInt();
PyObject object;
if (unicode) {
object = getUnicode(self.__getattr__("object"), "object");
@@ -513,7 +522,7 @@
* @return an the end position
*/
public static int getEnd(PyObject self, boolean unicode) {
- int end = getInt(self.__getattr__("end"), "end");
+ int end = self.__getattr__("end").asInt();
PyObject object;
if (unicode) {
object = getUnicode(self.__getattr__("object"), "object");
@@ -530,22 +539,6 @@
}
/**
- * Parse an int value for UnicodeErrors
- *
- * @param attr a PyObject
- * @param name of the attribute
- * @return an int value
- */
- public static int getInt(PyObject attr, String name) {
- if (attr instanceof PyInteger) {
- return ((PyInteger)attr).asInt();
- } else if (attr instanceof PyLong) {
- return ((PyLong)attr).asInt();
- }
- throw Py.TypeError(String.format("%.200s attribute must be int", name));
- }
-
- /**
* Ensure a PyString value for UnicodeErrors
*
* @param attr a PyObject
@@ -553,7 +546,7 @@
* @return an PyString
*/
public static PyString getString(PyObject attr, String name) {
- if (!(attr instanceof PyString)) {
+ if (!Py.isInstance(attr, PyString.TYPE)) {
throw Py.TypeError(String.format("%.200s attribute must be str", name));
}
return (PyString)attr;
@@ -663,10 +656,12 @@
this.javaMethod = javaMethod;
}
+ @Override
public PyBuiltinCallable bind(PyObject self) {
return new BoundStaticJavaMethod(getType(), self, info, javaMethod);
}
+ @Override
public PyObject __get__(PyObject obj, PyObject type) {
if (obj != null) {
return bind(obj);
@@ -674,6 +669,7 @@
return makeDescriptor((PyType)type);
}
+ @Override
public PyObject __call__(PyObject[] args, String kwargs[]) {
try {
return Py.java2py(javaMethod.invoke(null, self, args, kwargs));
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|