diff -r 0f3ebeb389fe Objects/dictobject.c --- a/Objects/dictobject.c Thu Feb 02 19:26:48 2017 +0000 +++ b/Objects/dictobject.c Sat Feb 04 19:10:49 2017 +0900 @@ -4373,21 +4373,18 @@ if (dict == NULL) return -1; *dictptr = dict; } if (value == NULL) { res = PyDict_DelItem(dict, key); - if (cached != ((PyDictObject *)dict)->ma_keys) { - CACHED_KEYS(tp) = NULL; - DK_DECREF(cached); - } } else { int was_shared = cached == ((PyDictObject *)dict)->ma_keys; res = PyDict_SetItem(dict, key, value); - if (was_shared && cached != ((PyDictObject *)dict)->ma_keys) { + if (was_shared && cached != ((PyDictObject *)dict)->ma_keys + && cached == CACHED_KEYS(tp)) { /* 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: @@ -4400,16 +4397,19 @@ * a = C() */ if (cached->dk_refcnt == 1) { CACHED_KEYS(tp) = make_keys_shared(dict); } else { - CACHED_KEYS(tp) = NULL; + // CACHED_KEYS(tp) = NULL allows further attemt to + // use new shared key. Use Py_EMPTY_KEYS to prevent it. + DK_INCREF(Py_EMPTY_KEYS); + CACHED_KEYS(tp) = Py_EMPTY_KEYS; } DK_DECREF(cached); - if (CACHED_KEYS(tp) == NULL && PyErr_Occurred()) + if (CACHED_KEYS(tp) == NULL && PyErr_Occurred()) return -1; } } } else { dict = *dictptr; if (dict == NULL) {