diff options
author | Guido van Rossum <guido@python.org> | 2002-09-03 20:24:09 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2002-09-03 20:24:09 (GMT) |
commit | 602d45194c94a2e60becfb8aac768367412960c6 (patch) | |
tree | 68eb4eccb6f555a1cf7e387ff550547b0dc2516f | |
parent | 99dba27e9a671693710128c0cfb5ed6686cda79b (diff) | |
download | cpython-602d45194c94a2e60becfb8aac768367412960c6.zip cpython-602d45194c94a2e60becfb8aac768367412960c6.tar.gz cpython-602d45194c94a2e60becfb8aac768367412960c6.tar.bz2 |
Add a custom __str__ method to KeyError that applies repr() to the
missing key. (Also added a guard to SyntaxError__str__ to prevent
calling PyString_Check(NULL).)
-rw-r--r-- | Lib/test/output/test_exceptions | 2 | ||||
-rw-r--r-- | Python/exceptions.c | 42 |
2 files changed, 41 insertions, 3 deletions
diff --git a/Lib/test/output/test_exceptions b/Lib/test/output/test_exceptions index e1e146a..28a7aa8 100644 --- a/Lib/test/output/test_exceptions +++ b/Lib/test/output/test_exceptions @@ -10,7 +10,7 @@ spam ImportError spam IndexError -spam +'spam' KeyError spam KeyboardInterrupt diff --git a/Python/exceptions.c b/Python/exceptions.c index 24ea25d..3f07089 100644 --- a/Python/exceptions.c +++ b/Python/exceptions.c @@ -785,7 +785,7 @@ SyntaxError__str__(PyObject *self, PyObject *args) /* XXX -- do all the additional formatting with filename and lineno here */ - if (PyString_Check(str)) { + if (str != NULL && PyString_Check(str)) { int have_filename = 0; int have_lineno = 0; char *buffer = NULL; @@ -844,6 +844,44 @@ static PyMethodDef SyntaxError_methods[] = { }; +static PyObject * +KeyError__str__(PyObject *self, PyObject *args) +{ + PyObject *argsattr; + PyObject *result; + + if (!PyArg_ParseTuple(args, "O:__str__", &self)) + return NULL; + + if (!(argsattr = PyObject_GetAttrString(self, "args"))) + return NULL; + + /* 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 Exception__str__(). + */ + if (PyTuple_Check(argsattr) && PyTuple_GET_SIZE(argsattr) == 1) { + PyObject *key = PyTuple_GET_ITEM(argsattr, 0); + result = PyObject_Repr(key); + } + else + result = Exception__str__(self, args); + + Py_DECREF(argsattr); + return result; +} + +static PyMethodDef KeyError_methods[] = { + {"__str__", KeyError__str__, METH_VARARGS}, + {NULL, NULL} +}; + + static int get_int(PyObject *exc, const char *name, int *value) { @@ -1617,7 +1655,7 @@ static struct { {"IndexError", &PyExc_IndexError, &PyExc_LookupError, IndexError__doc__}, {"KeyError", &PyExc_KeyError, &PyExc_LookupError, - KeyError__doc__}, + KeyError__doc__, KeyError_methods}, {"ArithmeticError", &PyExc_ArithmeticError, 0, ArithmeticError__doc__}, {"OverflowError", &PyExc_OverflowError, &PyExc_ArithmeticError, OverflowError__doc__}, |