diff -r 9381e368b1ae Lib/test/test_dict.py --- a/Lib/test/test_dict.py Tue Apr 24 13:55:35 2012 +0200 +++ b/Lib/test/test_dict.py Tue Apr 24 16:30:05 2012 +0100 @@ -889,6 +889,13 @@ self.assertEqual(f.msg, getattr(f, _str('msg'))) self.assertEqual(f.msg, f.__dict__[_str('msg')]) + def test_object_set_item_single_instance_non_str_key(self): + class Foo: pass + f = Foo() + f.__dict__[1] = 1 + f.a = 'a' + self.assertEqual(f.__dict__, {1:1, 'a':'a'}) + from test import mapping_tests class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): diff -r 9381e368b1ae Objects/dictobject.c --- a/Objects/dictobject.c Tue Apr 24 13:55:35 2012 +0200 +++ b/Objects/dictobject.c Tue Apr 24 16:30:05 2012 +0100 @@ -966,6 +966,8 @@ return 0; } +/* Returns NULL if unable to split table. + * A NULL return does not necessarily indicate an error */ static PyDictKeysObject * make_keys_shared(PyObject *op) { @@ -973,7 +975,8 @@ Py_ssize_t size; PyDictObject *mp = (PyDictObject *)op; - assert(PyDict_CheckExact(op)); + if (!PyDict_CheckExact(op)) + return NULL; if (!_PyDict_HasSplitTable(mp)) { PyDictKeyEntry *ep0; PyObject **values; @@ -3690,14 +3693,14 @@ res = PyDict_SetItem(dict, key, value); if (cached != ((PyDictObject *)dict)->ma_keys) { /* Either update tp->ht_cached_keys or delete it */ - if (cached->dk_refcnt == 1 && PyDict_CheckExact(dict)) { + if (cached->dk_refcnt == 1) { CACHED_KEYS(tp) = make_keys_shared(dict); - if (CACHED_KEYS(tp) == NULL) - return -1; } else { CACHED_KEYS(tp) = NULL; } DK_DECREF(cached); + if (CACHED_KEYS(tp) == NULL && PyErr_Occurred()) + return -1; } } } else {