Joannah Nanjekye <nanjekyejoan...@gmail.com> added the comment:
All enhancements specified in this issue have since been done. PyStructSequence_NewType() calls PyType_FromSpecWithBases() which sets the needed flags and even the qualname: PyObject * PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) { PyHeapTypeObject *res; PyMemberDef *memb; PyObject *modname; 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) { nmembers = 0; 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, "Type spec does not define the name field."); goto fail; } /* Set the type name and qualname */ s = strrchr(spec->name, '.'); if (s == NULL) s = (char*)spec->name; else s++; type = &res->ht_type; /* The flags must be initialized early, before the GC traverses us */ type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; res->ht_name = PyUnicode_FromString(s); if (!res->ht_name) goto fail; res->ht_qualname = res->ht_name; Py_INCREF(res->ht_qualname); type->tp_name = spec->name; /* Adjust for empty tuple bases */ if (!bases) { base = &PyBaseObject_Type; /* See whether Py_tp_base(s) was specified */ for (slot = spec->slots; slot->slot; slot++) { if (slot->slot == Py_tp_base) base = slot->pfunc; else if (slot->slot == Py_tp_bases) { bases = slot->pfunc; Py_INCREF(bases); } } if (!bases) bases = PyTuple_Pack(1, base); if (!bases) goto fail; } else Py_INCREF(bases); /* Calculate best base, and check that all bases are type objects */ base = best_base(bases); if (base == NULL) { goto fail; } if (!PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { PyErr_Format(PyExc_TypeError, "type '%.100s' is not an acceptable base type", base->tp_name); goto fail; } /* Initialize essential fields */ type->tp_as_async = &res->as_async; type->tp_as_number = &res->as_number; type->tp_as_sequence = &res->as_sequence; type->tp_as_mapping = &res->as_mapping; type->tp_as_buffer = &res->as_buffer; /* Set tp_base and tp_bases */ type->tp_bases = bases; bases = NULL; Py_INCREF(base); type->tp_base = base; type->tp_basicsize = spec->basicsize; type->tp_itemsize = spec->itemsize; for (slot = spec->slots; slot->slot; slot++) { if (slot->slot < 0 || (size_t)slot->slot >= Py_ARRAY_LENGTH(slotoffsets)) { PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); goto fail; } else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) { /* Processed above */ continue; } else if (slot->slot == Py_tp_doc) { /* For the docstring slot, which usually points to a static string literal, we need to make a copy */ const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); size_t len = strlen(old_doc)+1; char *tp_doc = PyObject_MALLOC(len); if (tp_doc == NULL) { type->tp_doc = NULL; PyErr_NoMemory(); goto fail; } memcpy(tp_doc, old_doc, len); type->tp_doc = tp_doc; } else if (slot->slot == Py_tp_members) { /* Move the slots to the heap type itself */ size_t len = Py_TYPE(type)->tp_itemsize * nmembers; memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len); type->tp_members = PyHeapType_GET_MEMBERS(res); } else { /* Copy other slots directly */ *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; } } if (type->tp_dealloc == NULL) { /* It's a heap type, so needs the heap types' dealloc. subtype_dealloc will call the base type's tp_dealloc, if necessary. */ type->tp_dealloc = subtype_dealloc; } if (PyType_Ready(type) < 0) goto fail; if (type->tp_dictoffset) { res->ht_cached_keys = _PyDict_NewKeysForClass(); } /* Set type.__module__ */ s = strrchr(spec->name, '.'); if (s != NULL) { int err; modname = PyUnicode_FromStringAndSize( spec->name, (Py_ssize_t)(s - spec->name)); if (modname == NULL) { goto fail; } err = _PyDict_SetItemId(type->tp_dict, &PyId___module__, modname); Py_DECREF(modname); if (err != 0) goto fail; } else { if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "builtin type %.200s has no __module__ attribute", spec->name)) goto fail; } return (PyObject*)res; fail: Py_DECREF(res); return NULL; } So I think this should be closed. I think issue2006 should also be closed as the Py_TPFLAGS_HEAPTYPE flag is set. ---------- nosy: +nanjekyejoannah _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue15729> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com