diff -r 975e03b0aea6 Objects/dictobject.c --- a/Objects/dictobject.c Tue Feb 07 11:27:48 2017 +0300 +++ b/Objects/dictobject.c Wed Feb 08 15:20:46 2017 +0900 @@ -4373,21 +4373,24 @@ if (dict == NULL) return -1; *dictptr = dict; } if (value == NULL) { res = PyDict_DelItem(dict, key); - if (cached != ((PyDictObject *)dict)->ma_keys) { + // key sharing dict doesn't allow deletion. + if ((cached = CACHED_KEYS(tp)) != NULL) { CACHED_KEYS(tp) = NULL; DK_DECREF(cached); } } else { - int was_shared = cached == ((PyDictObject *)dict)->ma_keys; + int was_shared = (cached == ((PyDictObject *)dict)->ma_keys); res = PyDict_SetItem(dict, key, value); - if (was_shared && cached != ((PyDictObject *)dict)->ma_keys) { + if (res == 0 && was_shared && + (cached = CACHED_KEYS(tp)) != NULL && + cached != ((PyDictObject *)dict)->ma_keys) { /* PyDict_SetItem() may call dictresize and convert split table * into combined table. In such case, convert it to split * table again and update type's shared key only when this is * the only dict sharing key with the type. * * This is to allow using shared key in class like this: