summaryrefslogtreecommitdiff
path: root/Objects/typeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/typeobject.c')
-rw-r--r--Objects/typeobject.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 682d44696e..4d599bf516 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2846,15 +2846,28 @@ static const short slotoffsets[] = {
PyObject *
PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
{
- PyHeapTypeObject *res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, 0);
- PyTypeObject *type, *base;
+ PyHeapTypeObject *res;
+ PyMemberDef *memb;
PyObject *modname;
- char *s;
- char *res_start = (char*)res;
+ PyTypeObject *type, *base;
+
PyType_Slot *slot;
+ Py_ssize_t nmembers;
+ char *s, *res_start;
+
+ nmembers = 0;
+ for (slot = spec->slots; slot->slot; slot++) {
+ if (slot->slot == Py_tp_members) {
+ for (memb = slot->pfunc; memb->name != NULL; memb++) {
+ nmembers++;
+ }
+ }
+ }
+ res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, nmembers);
if (res == NULL)
return NULL;
+ res_start = (char*)res;
if (spec->name == NULL) {
PyErr_SetString(PyExc_SystemError,
@@ -2950,6 +2963,13 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
memcpy(tp_doc, old_doc, len);
type->tp_doc = tp_doc;
}
+
+ /* Move the slots to the heap type itself */
+ if (slot->slot == Py_tp_members) {
+ size_t len = Py_TYPE(type)->tp_itemsize * nmembers;
+ memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len);
+ type->tp_members = PyHeapType_GET_MEMBERS(res);
+ }
}
if (type->tp_dealloc == NULL) {
/* It's a heap type, so needs the heap types' dealloc.