# HG changeset patch # User Leonardo Soto # Date 1211694981 14400 # Branch doj # Node ID a24632e9fcd9cc6f1ba0113edca527136334db6b # Parent f782e0688bd38c537ce890327ba93d19475ed29d KeyError.__str__() uses repr() instead of str(). See #1040 diff -r f782e0688bd3 -r a24632e9fcd9 jython/Lib/test/test_exceptions_jy.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jython/Lib/test/test_exceptions_jy.py Sun May 25 01:56:21 2008 -0400 @@ -0,0 +1,15 @@ +import test_support +import unittest + +class TypeErrorTest(unittest.TestCase): + def test_str(self): + # Checks that KeyError uses repr() instead of str() on its argument + # See jython issue 1040 + self.assertEquals("''", str(KeyError(''))) + self.assertEquals("'foo'", str(KeyError('foo'))) + +def test_main(): + test_support.run_unittest(TypeErrorTest) + +if __name__ == '__main__': + test_main() diff -r f782e0688bd3 -r a24632e9fcd9 jython/src/org/python/core/exceptions.java --- a/jython/src/org/python/core/exceptions.java Sat May 24 21:48:03 2008 -0400 +++ b/jython/src/org/python/core/exceptions.java Sun May 25 01:56:21 2008 -0400 @@ -199,7 +199,7 @@ public class exceptions implements Class buildClass(dict, "IndexError", "LookupError", "empty__init__", "Sequence index out of range."); - buildClass(dict, "KeyError", "LookupError", "empty__init__", + buildClass(dict, "KeyError", "LookupError", "KeyError", "Mapping key not found."); buildClass(dict, "AttributeError", "StandardError", "empty__init__", @@ -613,6 +613,41 @@ public class exceptions implements Class return dict; } + + /* + KeyError has a slightly different __str__ which uses repr() instead of + str() on the exception argument. Here is the reason, copied from CPython + 2.5 (exceptions.c): + + If args is a tuple of exactly one item, apply repr to args[0]. + This is done so that e.g. the exception raised by {}[''] prints + KeyError: '' + rather than the confusing + KeyError + alone. The downside is that if KeyError is raised with an explanatory + string, that string will be displayed in quotes. Too bad. + If args is anything else, use the default BaseException__str__(). + */ + public static PyObject KeyError__str__(PyObject[] arg, String[] kws) { + ArgParser ap = new ArgParser("__str__", arg, kws, "self"); + PyObject self = ap.getPyObject(0); + + PyObject args = self.__getattr__("args"); + if (args.__len__() == 1) { + return args.__getitem__(0).__repr__(); + } else { + return Exception__str__(arg, kws); // XXX: This should call + // BaseException, once we add it + } + } + + public static PyObject KeyError(PyObject[] arg, String[] kws) { + PyObject dict = empty__init__(arg, kws); + dict.__setitem__("__str__", getJavaFunc("KeyError__str__")); + return dict; + + } + private static PyObject getJavaFunc(String name) { return Py.newJavaFunc(exceptions.class, name); }