Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit df81379

Browse files
committed
correct the fix for #20637; allow slot descriptor inheritance to take place before creating cached keys
1 parent 0b1be1a commit df81379

2 files changed

Lines changed: 16 additions & 9 deletions

File tree

Lib/test/test_descr.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4414,6 +4414,14 @@ class OverrideBoth(OverrideNew, OverrideInit):
44144414
self.assertRaises(TypeError, case, 1, 2, 3)
44154415
self.assertRaises(TypeError, case, 1, 2, foo=3)
44164416

4417+
def test_subclassing_does_not_duplicate_dict_descriptors(self):
4418+
class Base:
4419+
pass
4420+
class Sub(Base):
4421+
pass
4422+
self.assertIn("__dict__", Base.__dict__)
4423+
self.assertNotIn("__dict__", Sub.__dict__)
4424+
44174425

44184426
class DictProxyTests(unittest.TestCase):
44194427
def setUp(self):

Objects/typeobject.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2472,12 +2472,6 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
24722472
type->tp_dictoffset = slotoffset;
24732473
slotoffset += sizeof(PyObject *);
24742474
}
2475-
else if (!type->tp_dictoffset) {
2476-
type->tp_dictoffset = base->tp_dictoffset;
2477-
}
2478-
if (type->tp_dictoffset) {
2479-
et->ht_cached_keys = _PyDict_NewKeysForClass();
2480-
}
24812475
if (add_weak) {
24822476
assert(!base->tp_itemsize);
24832477
type->tp_weaklistoffset = slotoffset;
@@ -2527,6 +2521,10 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
25272521
/* Put the proper slots in place */
25282522
fixup_slot_dispatchers(type);
25292523

2524+
if (type->tp_dictoffset) {
2525+
et->ht_cached_keys = _PyDict_NewKeysForClass();
2526+
}
2527+
25302528
Py_DECREF(dict);
25312529
return (PyObject *)type;
25322530

@@ -2643,9 +2641,6 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
26432641
type->tp_doc = tp_doc;
26442642
}
26452643
}
2646-
if (type->tp_dictoffset) {
2647-
res->ht_cached_keys = _PyDict_NewKeysForClass();
2648-
}
26492644
if (type->tp_dealloc == NULL) {
26502645
/* It's a heap type, so needs the heap types' dealloc.
26512646
subtype_dealloc will call the base type's tp_dealloc, if
@@ -2656,6 +2651,10 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
26562651
if (PyType_Ready(type) < 0)
26572652
goto fail;
26582653

2654+
if (type->tp_dictoffset) {
2655+
res->ht_cached_keys = _PyDict_NewKeysForClass();
2656+
}
2657+
26592658
/* Set type.__module__ */
26602659
s = strrchr(spec->name, '.');
26612660
if (s != NULL)

0 commit comments

Comments
 (0)