Bug #1576657: when setting a KeyError for a tuple key, make sure that

the tuple isn't used as the "exception arguments tuple".
This commit is contained in:
Georg Brandl 2006-10-29 18:31:42 +00:00
parent f733a013b2
commit b9f4ad3a9a
3 changed files with 29 additions and 3 deletions

View File

@ -444,6 +444,16 @@ class DictTest(unittest.TestCase):
else: else:
self.fail_("g[42] didn't raise KeyError") self.fail_("g[42] didn't raise KeyError")
def test_tuple_keyerror(self):
# SF #1576657
d = {}
try:
d[(1,)]
except KeyError, e:
self.assertEqual(e.args, ((1,),))
else:
self.fail("missing KeyError")
from test import mapping_tests from test import mapping_tests

View File

@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
Core and builtins Core and builtins
----------------- -----------------
- Bug #1576657: when setting a KeyError for a tuple key, make sure that
the tuple isn't used as the "exception arguments tuple".
- Bug #1565514, SystemError not raised on too many nested blocks. - Bug #1565514, SystemError not raised on too many nested blocks.
- Bug #1576174: WindowsError now displays the windows error code - Bug #1576174: WindowsError now displays the windows error code

View File

@ -12,6 +12,19 @@
typedef PyDictEntry dictentry; typedef PyDictEntry dictentry;
typedef PyDictObject dictobject; typedef PyDictObject dictobject;
/* Set a key error with the specified argument, wrapping it in a
* tuple automatically so that tuple keys are not unpacked as the
* exception arguments. */
static void
set_key_error(PyObject *arg)
{
PyObject *tup;
tup = PyTuple_Pack(1, arg);
if (!tup)
return; /* caller will expect error to be set anyway */
PyErr_SetObject(PyExc_KeyError, tup);
}
/* Define this out if you don't want conversion statistics on exit. */ /* Define this out if you don't want conversion statistics on exit. */
#undef SHOW_CONVERSION_COUNTS #undef SHOW_CONVERSION_COUNTS
@ -665,7 +678,7 @@ PyDict_DelItem(PyObject *op, PyObject *key)
if (ep == NULL) if (ep == NULL)
return -1; return -1;
if (ep->me_value == NULL) { if (ep->me_value == NULL) {
PyErr_SetObject(PyExc_KeyError, key); set_key_error(key);
return -1; return -1;
} }
old_key = ep->me_key; old_key = ep->me_key;
@ -974,7 +987,7 @@ dict_subscript(dictobject *mp, register PyObject *key)
return PyObject_CallFunctionObjArgs(missing, return PyObject_CallFunctionObjArgs(missing,
(PyObject *)mp, key, NULL); (PyObject *)mp, key, NULL);
} }
PyErr_SetObject(PyExc_KeyError, key); set_key_error(key);
return NULL; return NULL;
} }
else else
@ -1746,7 +1759,7 @@ dict_pop(dictobject *mp, PyObject *args)
Py_INCREF(deflt); Py_INCREF(deflt);
return deflt; return deflt;
} }
PyErr_SetObject(PyExc_KeyError, key); set_key_error(key);
return NULL; return NULL;
} }
old_key = ep->me_key; old_key = ep->me_key;