summaryrefslogtreecommitdiffstats
path: root/Objects/dictobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/dictobject.c')
-rw-r--r--Objects/dictobject.c30
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,