diff options
Diffstat (limited to 'Objects/dictobject.c')
-rw-r--r-- | Objects/dictobject.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 3a1dbc9..7f1d38d 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3324,19 +3324,16 @@ static PyNumberMethods dict_as_number = { static PyObject * dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *self; - PyDictObject *d; + assert(type != NULL); + assert(type->tp_alloc != NULL); + // dict subclasses must implement the GC protocol + assert(_PyType_IS_GC(type)); - assert(type != NULL && type->tp_alloc != NULL); - self = type->tp_alloc(type, 0); - if (self == NULL) + PyObject *self = type->tp_alloc(type, 0); + if (self == NULL) { return NULL; - d = (PyDictObject *)self; - - /* The object has been implicitly tracked by tp_alloc */ - if (type == &PyDict_Type) { - _PyObject_GC_UNTRACK(d); } + PyDictObject *d = (PyDictObject *)self; d->ma_used = 0; d->ma_version_tag = DICT_NEXT_VERSION(); @@ -3344,6 +3341,17 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) d->ma_keys = Py_EMPTY_KEYS; d->ma_values = empty_values; ASSERT_CONSISTENT(d); + + if (type != &PyDict_Type) { + // Don't track if a subclass tp_alloc is PyType_GenericAlloc() + if (!_PyObject_GC_IS_TRACKED(d)) { + _PyObject_GC_TRACK(d); + } + } + else { + // _PyType_AllocNoTrack() does not track the created object + assert(!_PyObject_GC_IS_TRACKED(d)); + } return self; } @@ -3441,7 +3449,7 @@ PyTypeObject PyDict_Type = { 0, /* tp_descr_set */ 0, /* tp_dictoffset */ dict_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ + _PyType_AllocNoTrack, /* tp_alloc */ dict_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ .tp_vectorcall = dict_vectorcall, |