changeset: 89824:afae24cb81d9 branch: 3.4 parent: 89821:e725de5a2760 user: Benjamin Peterson date: Mon Mar 17 15:57:17 2014 -0500 files: Lib/test/test_descr.py Objects/typeobject.c description: correct the fix for #20637; allow slot descriptor inheritance to take place before creating cached keys diff -r e725de5a2760 -r afae24cb81d9 Lib/test/test_descr.py --- a/Lib/test/test_descr.py Mon Mar 17 16:48:13 2014 -0400 +++ b/Lib/test/test_descr.py Mon Mar 17 15:57:17 2014 -0500 @@ -4414,6 +4414,14 @@ self.assertRaises(TypeError, case, 1, 2, 3) self.assertRaises(TypeError, case, 1, 2, foo=3) + def test_subclassing_does_not_duplicate_dict_descriptors(self): + class Base: + pass + class Sub(Base): + pass + self.assertIn("__dict__", Base.__dict__) + self.assertNotIn("__dict__", Sub.__dict__) + class DictProxyTests(unittest.TestCase): def setUp(self): diff -r e725de5a2760 -r afae24cb81d9 Objects/typeobject.c --- a/Objects/typeobject.c Mon Mar 17 16:48:13 2014 -0400 +++ b/Objects/typeobject.c Mon Mar 17 15:57:17 2014 -0500 @@ -2472,12 +2472,6 @@ type->tp_dictoffset = slotoffset; slotoffset += sizeof(PyObject *); } - else if (!type->tp_dictoffset) { - type->tp_dictoffset = base->tp_dictoffset; - } - if (type->tp_dictoffset) { - et->ht_cached_keys = _PyDict_NewKeysForClass(); - } if (add_weak) { assert(!base->tp_itemsize); type->tp_weaklistoffset = slotoffset; @@ -2527,6 +2521,10 @@ /* Put the proper slots in place */ fixup_slot_dispatchers(type); + if (type->tp_dictoffset) { + et->ht_cached_keys = _PyDict_NewKeysForClass(); + } + Py_DECREF(dict); return (PyObject *)type; @@ -2643,9 +2641,6 @@ type->tp_doc = tp_doc; } } - if (type->tp_dictoffset) { - res->ht_cached_keys = _PyDict_NewKeysForClass(); - } if (type->tp_dealloc == NULL) { /* It's a heap type, so needs the heap types' dealloc. subtype_dealloc will call the base type's tp_dealloc, if @@ -2656,6 +2651,10 @@ if (PyType_Ready(type) < 0) goto fail; + if (type->tp_dictoffset) { + res->ht_cached_keys = _PyDict_NewKeysForClass(); + } + /* Set type.__module__ */ s = strrchr(spec->name, '.'); if (s != NULL)