diff options
-rw-r--r-- | Doc/c-api/type.rst | 6 | ||||
-rw-r--r-- | Objects/typeobject.c | 23 |
2 files changed, 22 insertions, 7 deletions
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 84c0a02..a822b67 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -157,7 +157,8 @@ The following functions and structs are used to create If *bases* is a tuple, the created heap type contains all types contained in it as base types. - If *bases* is ``NULL``, the *Py_tp_base* slot is used instead. + If *bases* is ``NULL``, the *Py_tp_bases* slot is used instead. + If that also is ``NULL``, the *Py_tp_base* slot is used instead. If that also is ``NULL``, the new type derives from :class:`object`. The *module* argument can be used to record the module in which the new @@ -253,7 +254,8 @@ The following functions and structs are used to create * :c:member:`~PyBufferProcs.bf_getbuffer` * :c:member:`~PyBufferProcs.bf_releasebuffer` - Setting :c:data:`Py_tp_bases` may be problematic on some platforms. + Setting :c:data:`Py_tp_bases` or :c:data:`Py_tp_base` may be + problematic on some platforms. To avoid issues, use the *bases* argument of :py:func:`PyType_FromSpecWithBases` instead. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index fd018b8..9ebeeeb 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2977,26 +2977,40 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) base = slot->pfunc; else if (slot->slot == Py_tp_bases) { bases = slot->pfunc; - Py_INCREF(bases); } } - if (!bases) + if (!bases) { bases = PyTuple_Pack(1, base); - if (!bases) + if (!bases) + goto fail; + } + else if (!PyTuple_Check(bases)) { + PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); goto fail; + } + else { + Py_INCREF(bases); + } } - else + else if (!PyTuple_Check(bases)) { + PyErr_SetString(PyExc_SystemError, "bases is not a tuple"); + goto fail; + } + else { Py_INCREF(bases); + } /* Calculate best base, and check that all bases are type objects */ base = best_base(bases); if (base == NULL) { + Py_DECREF(bases); goto fail; } if (!_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { PyErr_Format(PyExc_TypeError, "type '%.100s' is not an acceptable base type", base->tp_name); + Py_DECREF(bases); goto fail; } @@ -3008,7 +3022,6 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) 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; |