Skip to content

Commit 53e6a9a

Browse files
authored
gh-96046: Initialize ht_cached_keys in PyType_Ready() (GH-96047)
1 parent d8c7a11 commit 53e6a9a

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:c:func:`PyType_Ready` now initializes ``ht_cached_keys`` and performs
2+
additional checks to ensure that type objects are properly configured. This
3+
avoids crashes in 3rd party packages that don't use regular API to create
4+
new types.

Objects/typeobject.c

+26-9
Original file line numberDiff line numberDiff line change
@@ -3287,11 +3287,6 @@ type_new_impl(type_new_ctx *ctx)
32873287
// Put the proper slots in place
32883288
fixup_slot_dispatchers(type);
32893289

3290-
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
3291-
PyHeapTypeObject *et = (PyHeapTypeObject*)type;
3292-
et->ht_cached_keys = _PyDict_NewKeysForClass();
3293-
}
3294-
32953290
if (type_new_set_names(type) < 0) {
32963291
goto error;
32973292
}
@@ -3836,10 +3831,6 @@ PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module,
38363831
goto finally;
38373832
}
38383833

3839-
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
3840-
res->ht_cached_keys = _PyDict_NewKeysForClass();
3841-
}
3842-
38433834
if (type->tp_doc) {
38443835
PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc));
38453836
if (!__doc__) {
@@ -6774,6 +6765,29 @@ type_ready_set_new(PyTypeObject *type)
67746765
return 0;
67756766
}
67766767

6768+
static int
6769+
type_ready_managed_dict(PyTypeObject *type)
6770+
{
6771+
if (!(type->tp_flags & Py_TPFLAGS_MANAGED_DICT)) {
6772+
return 0;
6773+
}
6774+
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
6775+
PyErr_Format(PyExc_SystemError,
6776+
"type %s has the Py_TPFLAGS_MANAGED_DICT flag "
6777+
"but not Py_TPFLAGS_HEAPTYPE flag",
6778+
type->tp_name);
6779+
return -1;
6780+
}
6781+
PyHeapTypeObject* et = (PyHeapTypeObject*)type;
6782+
if (et->ht_cached_keys == NULL) {
6783+
et->ht_cached_keys = _PyDict_NewKeysForClass();
6784+
if (et->ht_cached_keys == NULL) {
6785+
PyErr_NoMemory();
6786+
return -1;
6787+
}
6788+
}
6789+
return 0;
6790+
}
67776791

67786792
static int
67796793
type_ready_post_checks(PyTypeObject *type)
@@ -6852,6 +6866,9 @@ type_ready(PyTypeObject *type)
68526866
if (type_ready_add_subclasses(type) < 0) {
68536867
return -1;
68546868
}
6869+
if (type_ready_managed_dict(type) < 0) {
6870+
return -1;
6871+
}
68556872
if (type_ready_post_checks(type) < 0) {
68566873
return -1;
68576874
}

0 commit comments

Comments
 (0)