homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author nanjekyejoannah
Recipients Robin.Schreiber, elemental, eric.snow, loewis, nanjekyejoannah, serhiy.storchaka
Date 2019年09月16日.00:55:26
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1568595326.86.0.954829443504.issue15729@roundup.psfhosted.org>
In-reply-to
Content
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.
History
Date User Action Args
2019年09月16日 00:55:26nanjekyejoannahsetrecipients: + nanjekyejoannah, loewis, eric.snow, serhiy.storchaka, Robin.Schreiber, elemental
2019年09月16日 00:55:26nanjekyejoannahsetmessageid: <1568595326.86.0.954829443504.issue15729@roundup.psfhosted.org>
2019年09月16日 00:55:26nanjekyejoannahlinkissue15729 messages
2019年09月16日 00:55:26nanjekyejoannahcreate

AltStyle によって変換されたページ (->オリジナル) /