summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_dict.py10
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/dictobject.c19
3 files changed, 29 insertions, 3 deletions
diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py
index bbca798..218f7cc 100644
--- a/Lib/test/test_dict.py
+++ b/Lib/test/test_dict.py
@@ -444,6 +444,16 @@ class DictTest(unittest.TestCase):
else:
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
diff --git a/Misc/NEWS b/Misc/NEWS
index d754849..4d1396c 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
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 #1576174: WindowsError now displays the windows error code
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index e127d96..1fcfe1c 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -12,6 +12,19 @@
typedef PyDictEntry dictentry;
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. */
#undef SHOW_CONVERSION_COUNTS
@@ -665,7 +678,7 @@ PyDict_DelItem(PyObject *op, PyObject *key)
if (ep == NULL)
return -1;
if (ep->me_value == NULL) {
- PyErr_SetObject(PyExc_KeyError, key);
+ set_key_error(key);
return -1;
}
old_key = ep->me_key;
@@ -974,7 +987,7 @@ dict_subscript(dictobject *mp, register PyObject *key)
return PyObject_CallFunctionObjArgs(missing,
(PyObject *)mp, key, NULL);
}
- PyErr_SetObject(PyExc_KeyError, key);
+ set_key_error(key);
return NULL;
}
else
@@ -1746,7 +1759,7 @@ dict_pop(dictobject *mp, PyObject *args)
Py_INCREF(deflt);
return deflt;
}
- PyErr_SetObject(PyExc_KeyError, key);
+ set_key_error(key);
return NULL;
}
old_key = ep->me_key;