correct the fix for #20637; allow slot descriptor inheritance to take place before...
authorBenjamin Peterson <benjamin@python.org>
Mon, 17 Mar 2014 20:57:17 +0000 (15:57 -0500)
committerBenjamin Peterson <benjamin@python.org>
Mon, 17 Mar 2014 20:57:17 +0000 (15:57 -0500)
Lib/test/test_descr.py
Objects/typeobject.c

index 2a9e329633ed1ef8932b500bc0f88642948dd376..71d8609ab8c0a167f36d2a7d5620537439411985 100644 (file)
@@ -4414,6 +4414,14 @@ order (MRO) for bases """
             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):
index df8f3512383a6c3cb96c0ec9d83f2c3c88ea90fd..c21b397c04e9c7422e8b6fedb7b8a0ba686cc7df 100644 (file)
@@ -2472,12 +2472,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
             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 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
     /* 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 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
             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 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
     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)