aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2024-01-12 12:11:20 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2024-01-16 11:20:58 +0100
commit15fe017be6eb8b3aaf32d06eb21c61bd7eb3907e (patch)
tree7208cfd73e38ce3cc78e67eb88fa3d301719c79d
parenta136723223b06169321296cd6cbc4c4c694e5153 (diff)
Use PyType_GetSlot() instead of accessing PyTypeObject's slots in library code
Using PepType_GetSlot() as is requires adding ugly casts. To work around, add a new file with convenience helper functions in C++ linkage. This also allows for using templates for tp_alloc. Task-number: PYSIDE-560 Change-Id: Ia50a226f5b545861f885d600445b91b4e11713c5 Reviewed-by: Christian Tismer <tismer@stackless.com>
-rw-r--r--sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp4
-rw-r--r--sources/pyside6/libpyside/class_property.cpp11
-rw-r--r--sources/pyside6/libpyside/dynamicqmetaobject.cpp2
-rw-r--r--sources/pyside6/libpyside/globalreceiverv2.cpp3
-rw-r--r--sources/pyside6/libpyside/pysideclassdecorator_p.h5
-rw-r--r--sources/pyside6/libpyside/pysideproperty.cpp5
-rw-r--r--sources/pyside6/libpyside/pysidesignal.cpp17
-rw-r--r--sources/pyside6/libpysideqml/pysideqmllistproperty.cpp3
-rw-r--r--sources/shiboken6/libshiboken/CMakeLists.txt1
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.cpp7
-rw-r--r--sources/shiboken6/libshiboken/pep384ext.h89
-rw-r--r--sources/shiboken6/libshiboken/sbkcontainer.h7
-rw-r--r--sources/shiboken6/libshiboken/sbkfeature_base.cpp3
-rw-r--r--sources/shiboken6/libshiboken/voidptr.cpp4
14 files changed, 130 insertions, 31 deletions
diff --git a/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp b/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp
index e92e13aaf..6e403ab72 100644
--- a/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp
+++ b/sources/pyside6/PySide6/QtQml/pysideqmlvolatilebool.cpp
@@ -3,6 +3,7 @@
#include "pysideqmlvolatilebool.h"
+#include <pep384ext.h>
#include <signature.h>
#include <QtCore/QDebug>
@@ -30,8 +31,7 @@ QtQml_VolatileBoolObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (ok < 0)
return nullptr;
- QtQml_VolatileBoolObject *self
- = reinterpret_cast<QtQml_VolatileBoolObject *>(type->tp_alloc(type, 0));
+ auto *self = PepExt_TypeCallAlloc<QtQml_VolatileBoolObject>(type, 0);
if (self != nullptr)
self->flag = new AtomicBool(ok);
diff --git a/sources/pyside6/libpyside/class_property.cpp b/sources/pyside6/libpyside/class_property.cpp
index 99104445c..2bed97ef5 100644
--- a/sources/pyside6/libpyside/class_property.cpp
+++ b/sources/pyside6/libpyside/class_property.cpp
@@ -5,6 +5,7 @@
#include "pysidestaticstrings.h"
#include "feature_select.h"
+#include <pep384ext.h>
#include <shiboken.h>
#include <sbkstaticstrings.h>
@@ -23,14 +24,14 @@ extern "C" {
// `class_property.__get__()`: Always pass the class instead of the instance.
static PyObject *PyClassProperty_descr_get(PyObject *self, PyObject * /*ob*/, PyObject *cls)
{
- return PyProperty_Type.tp_descr_get(self, cls, cls);
+ return PepExt_Type_GetDescrGetSlot(&PyProperty_Type)(self, cls, cls);
}
// `class_property.__set__()`: Just like the above `__get__()`.
static int PyClassProperty_descr_set(PyObject *self, PyObject *obj, PyObject *value)
{
PyObject *cls = PyType_Check(obj) ? obj : reinterpret_cast<PyObject *>(Py_TYPE(obj));
- return PyProperty_Type.tp_descr_set(self, cls, value);
+ return PepExt_Type_GetDescrSetSlot(&PyProperty_Type)(self, cls, value);
}
// PYSIDE-2230: Why is this metaclass necessary?
@@ -80,7 +81,7 @@ static int PyClassProperty_tp_init(PyObject *self, PyObject *args, PyObject *kwa
{
auto hold = Py_TYPE(self);
self->ob_type = &PyProperty_Type;
- auto ret = PyProperty_Type.tp_init(self, args, kwargs);
+ auto ret = PepExt_Type_GetInitSlot(&PyProperty_Type)(self, args, kwargs);
self->ob_type = hold;
return ret;
}
@@ -138,9 +139,9 @@ static int SbkObjectType_meta_setattro(PyObject *obj, PyObject *name, PyObject *
&& !PyObject_IsInstance(value, class_prop);
if (call_descr_set) {
// Call `class_property.__set__()` instead of replacing the `class_property`.
- return Py_TYPE(descr)->tp_descr_set(descr, obj, value);
+ return PepExt_Type_GetDescrSetSlot(Py_TYPE(descr))(descr, obj, value);
} // Replace existing attribute.
- return PyType_Type.tp_setattro(obj, name, value);
+ return PepExt_Type_GetSetAttroSlot(&PyType_Type)(obj, name, value);
}
} // extern "C"
diff --git a/sources/pyside6/libpyside/dynamicqmetaobject.cpp b/sources/pyside6/libpyside/dynamicqmetaobject.cpp
index b41dbc275..048001f81 100644
--- a/sources/pyside6/libpyside/dynamicqmetaobject.cpp
+++ b/sources/pyside6/libpyside/dynamicqmetaobject.cpp
@@ -634,7 +634,7 @@ void MetaObjectBuilderPrivate::parsePythonType(PyTypeObject *type)
const int index = m_baseObject->indexOfProperty(name);
if (index == -1)
addProperty(name, value);
- } else if (Py_TYPE(value)->tp_call != nullptr) {
+ } else if (PepType_GetSlot(Py_TYPE(value), Py_tp_call) != nullptr) {
// PYSIDE-198: PyFunction_Check does not work with Nuitka.
// Register slots.
if (PyObject_HasAttr(value, slotAttrName)) {
diff --git a/sources/pyside6/libpyside/globalreceiverv2.cpp b/sources/pyside6/libpyside/globalreceiverv2.cpp
index 09385645d..5fcf224ea 100644
--- a/sources/pyside6/libpyside/globalreceiverv2.cpp
+++ b/sources/pyside6/libpyside/globalreceiverv2.cpp
@@ -9,6 +9,7 @@
#include <autodecref.h>
#include <gilstate.h>
+#include <pep384ext.h>
#include <QtCore/QMetaMethod>
#include <QtCore/QSet>
@@ -135,7 +136,7 @@ PyObject *DynamicSlotDataV2::callback()
//create a callback based on method data
if (m_isMethod)
- callback = Py_TYPE(m_callback)->tp_descr_get(m_callback, m_pythonSelf, nullptr);
+ callback = PepExt_Type_CallDescrGet(m_callback, m_pythonSelf, nullptr);
else
Py_INCREF(callback);
diff --git a/sources/pyside6/libpyside/pysideclassdecorator_p.h b/sources/pyside6/libpyside/pysideclassdecorator_p.h
index d4e21a5b4..6068f6a2e 100644
--- a/sources/pyside6/libpyside/pysideclassdecorator_p.h
+++ b/sources/pyside6/libpyside/pysideclassdecorator_p.h
@@ -7,6 +7,7 @@
#include <pysidemacros.h>
#include <sbkpython.h>
+#include <pep384ext.h>
#include <QtCore/QByteArray>
@@ -119,7 +120,7 @@ struct Methods
{
static PyObject *tp_new(PyTypeObject *subtype)
{
- auto *result = reinterpret_cast<PySideClassDecorator *>(subtype->tp_alloc(subtype, 0));
+ auto *result = PepExt_TypeCallAlloc<PySideClassDecorator>(subtype, 0);
result->d = new DecoratorPrivate;
return reinterpret_cast<PyObject *>(result);
}
@@ -129,7 +130,7 @@ struct Methods
auto pySelf = reinterpret_cast<PyObject *>(self);
auto decorator = reinterpret_cast<PySideClassDecorator *>(self);
delete decorator->d;
- Py_TYPE(pySelf)->tp_base->tp_free(self);
+ PepExt_TypeCallFree(Py_TYPE(pySelf)->tp_base, self);
}
static PyObject *tp_call(PyObject *self, PyObject *args, PyObject *kwds)
diff --git a/sources/pyside6/libpyside/pysideproperty.cpp b/sources/pyside6/libpyside/pysideproperty.cpp
index 2648ca43c..457415479 100644
--- a/sources/pyside6/libpyside/pysideproperty.cpp
+++ b/sources/pyside6/libpyside/pysideproperty.cpp
@@ -8,6 +8,7 @@
#include "pysidesignal_p.h"
#include <shiboken.h>
+#include <pep384ext.h>
#include <signature.h>
using namespace Shiboken;
@@ -179,7 +180,7 @@ void PySidePropertyPrivate::metaCall(PyObject *source, QMetaObject::Call call, v
static PyObject *qpropertyTpNew(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */)
{
- auto *me = reinterpret_cast<PySideProperty *>(subtype->tp_alloc(subtype, 0));
+ auto *me = PepExt_TypeCallAlloc<PySideProperty>(subtype, 0);
me->d = new PySidePropertyPrivate;
return reinterpret_cast<PyObject *>(me);
}
@@ -258,7 +259,7 @@ static void qpropertyDeAlloc(PyObject *self)
Py_DECREF(Py_TYPE(self));
}
PyObject_GC_UnTrack(self);
- Py_TYPE(self)->tp_free(self);
+ PepExt_TypeCallFree(self);
}
// Create a copy of the property to prevent the @property.setter from modifying
diff --git a/sources/pyside6/libpyside/pysidesignal.cpp b/sources/pyside6/libpyside/pysidesignal.cpp
index 0c6a23245..150dd500e 100644
--- a/sources/pyside6/libpyside/pysidesignal.cpp
+++ b/sources/pyside6/libpyside/pysidesignal.cpp
@@ -18,6 +18,7 @@
#include <QtCore/QObject>
#include <QtCore/QMetaMethod>
#include <QtCore/QMetaObject>
+#include <pep384ext.h>
#include <signature.h>
#include <algorithm>
@@ -298,7 +299,7 @@ static void signalFree(void *vself)
Py_XDECREF(self->homonymousMethod);
self->homonymousMethod = nullptr;
- Py_TYPE(pySelf)->tp_base->tp_free(self);
+ PepExt_TypeCallFree(Py_TYPE(pySelf)->tp_base, self);
}
static PyObject *signalGetItem(PyObject *obSelf, PyObject *key)
@@ -368,7 +369,7 @@ static void signalInstanceFree(void *vself)
self->d = nullptr;
}
self->deleted = true;
- Py_TYPE(pySelf)->tp_base->tp_free(self);
+ PepExt_TypeCallFree(Py_TYPE(pySelf)->tp_base, self);
}
// PYSIDE-1523: PyFunction_Check is not accepting compiled functions and
@@ -754,18 +755,16 @@ static PyObject *signalCall(PyObject *self, PyObject *args, PyObject *kw)
return nullptr;
}
- descrgetfunc getDescriptor = Py_TYPE(signal->homonymousMethod)->tp_descr_get;
-
// Check if there exists a method with the same name as the signal, which is also a static
// method in C++ land.
- Shiboken::AutoDecRef homonymousMethod(getDescriptor(signal->homonymousMethod,
- nullptr, nullptr));
+ Shiboken::AutoDecRef homonymousMethod(PepExt_Type_CallDescrGet(signal->homonymousMethod,
+ nullptr, nullptr));
if (PyCFunction_Check(homonymousMethod.object())
&& (PyCFunction_GET_FLAGS(homonymousMethod.object()) & METH_STATIC))
return PyObject_Call(homonymousMethod, args, kw);
// Assumes homonymousMethod is not a static method.
- ternaryfunc callFunc = Py_TYPE(signal->homonymousMethod)->tp_call;
+ ternaryfunc callFunc = PepExt_Type_GetCallSlot(Py_TYPE(signal->homonymousMethod));
return callFunc(homonymousMethod, args, kw);
}
@@ -822,8 +821,8 @@ static PyObject *signalInstanceCall(PyObject *self, PyObject *args, PyObject *kw
return nullptr;
}
- descrgetfunc getDescriptor = Py_TYPE(hom)->tp_descr_get;
- Shiboken::AutoDecRef homonymousMethod(getDescriptor(hom, PySideSignal->d->source, nullptr));
+ Shiboken::AutoDecRef homonymousMethod(PepExt_Type_CallDescrGet(hom, PySideSignal->d->source,
+ nullptr));
return PyObject_Call(homonymousMethod, args, kw);
}
diff --git a/sources/pyside6/libpysideqml/pysideqmllistproperty.cpp b/sources/pyside6/libpysideqml/pysideqmllistproperty.cpp
index a6f9f0193..97d6ce91b 100644
--- a/sources/pyside6/libpysideqml/pysideqmllistproperty.cpp
+++ b/sources/pyside6/libpysideqml/pysideqmllistproperty.cpp
@@ -5,6 +5,7 @@
#include "pysideqmlregistertype_p.h"
#include <shiboken.h>
+#include <pep384ext.h>
#include <signature.h>
#include <pysideproperty.h>
@@ -33,7 +34,7 @@ extern "C"
static PyObject *propList_tp_new(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */)
{
- PySideProperty *me = reinterpret_cast<PySideProperty *>(subtype->tp_alloc(subtype, 0));
+ auto *me = PepExt_TypeCallAlloc<PySideProperty>(subtype, 0);
me->d = new QmlListPropertyPrivate;
return reinterpret_cast<PyObject *>(me);
}
diff --git a/sources/shiboken6/libshiboken/CMakeLists.txt b/sources/shiboken6/libshiboken/CMakeLists.txt
index 4638ca6f9..7a3c7d633 100644
--- a/sources/shiboken6/libshiboken/CMakeLists.txt
+++ b/sources/shiboken6/libshiboken/CMakeLists.txt
@@ -180,6 +180,7 @@ install(FILES
sbkpython.h
sbkwindows.h
pep384impl.h
+ pep384ext.h
voidptr.h
bufferprocs_py37.h
"${CMAKE_CURRENT_BINARY_DIR}/sbkversion.h"
diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp
index 9a7d1d62d..bef687e41 100644
--- a/sources/shiboken6/libshiboken/basewrapper.cpp
+++ b/sources/shiboken6/libshiboken/basewrapper.cpp
@@ -5,6 +5,7 @@
#include "basewrapper_p.h"
#include "bindingmanager.h"
#include "helper.h"
+#include "pep384ext.h"
#include "sbkconverter.h"
#include "sbkenum.h"
#include "sbkerrors.h"
@@ -55,7 +56,7 @@ void Sbk_object_dealloc(PyObject *self)
// This was not needed before Python 3.8 (Python issue 35810)
Py_DECREF(Py_TYPE(self));
}
- Py_TYPE(self)->tp_free(self);
+ PepExt_TypeCallFree(self);
}
static void SbkObjectType_tp_dealloc(PyTypeObject *pyType);
@@ -522,7 +523,7 @@ static PyTypeObject *SbkObjectType_tp_new(PyTypeObject *metatype, PyObject *args
for (int i=0, i_max=PyTuple_GET_SIZE(pyBases); i < i_max; i++) {
PyObject *baseType = PyTuple_GET_ITEM(pyBases, i);
- if (reinterpret_cast<PyTypeObject *>(baseType)->tp_new == SbkDummyNew) {
+ if (PepExt_Type_GetNewSlot(reinterpret_cast<PyTypeObject *>(baseType)) == SbkDummyNew) {
// PYSIDE-595: A base class does not allow inheritance.
return reinterpret_cast<PyTypeObject *>(SbkDummyNew(metatype, args, kwds));
}
@@ -1645,7 +1646,7 @@ void deallocData(SbkObject *self, bool cleanup)
}
delete self->d; // PYSIDE-205: always delete d.
Py_XDECREF(self->ob_dict);
- Py_TYPE(self)->tp_free(self);
+ PepExt_TypeCallFree(reinterpret_cast<PyObject *>(self));
}
void setTypeUserData(SbkObject *wrapper, void *userData, DeleteUserDataFunc d_func)
diff --git a/sources/shiboken6/libshiboken/pep384ext.h b/sources/shiboken6/libshiboken/pep384ext.h
new file mode 100644
index 000000000..021c53d16
--- /dev/null
+++ b/sources/shiboken6/libshiboken/pep384ext.h
@@ -0,0 +1,89 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PEP384EXT_H
+#define PEP384EXT_H
+
+#include "pep384impl.h"
+
+/// Returns the allocator slot of the PyTypeObject.
+inline allocfunc PepExt_Type_GetAllocSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<allocfunc>(PepType_GetSlot(t, Py_tp_alloc));
+}
+
+/// Invokes the allocator slot of the PyTypeObject.
+template <class Type>
+inline Type *PepExt_TypeCallAlloc(PyTypeObject *t, Py_ssize_t nitems)
+{
+ PyObject *result = PepExt_Type_GetAllocSlot(t)(t, nitems);
+ return reinterpret_cast<Type *>(result);
+}
+
+/// Returns the getattro slot of the PyTypeObject.
+inline getattrofunc PepExt_Type_GetGetAttroSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<getattrofunc>(PepType_GetSlot(t, Py_tp_getattro));
+}
+
+/// Returns the setattro slot of the PyTypeObject.
+inline setattrofunc PepExt_Type_GetSetAttroSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<setattrofunc>(PepType_GetSlot(t, Py_tp_setattro));
+}
+
+/// Returns the descr_get slot of the PyTypeObject.
+inline descrgetfunc PepExt_Type_GetDescrGetSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<descrgetfunc>(PepType_GetSlot(t, Py_tp_descr_get));
+}
+
+/// Invokes the descr_get slot of the PyTypeObject.
+inline PyObject *PepExt_Type_CallDescrGet(PyObject *self, PyObject *obj, PyObject *type)
+{
+ return PepExt_Type_GetDescrGetSlot(Py_TYPE(self))(self, obj, type);
+}
+
+/// Returns the descr_set slot of the PyTypeObject.
+inline descrsetfunc PepExt_Type_GetDescrSetSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<descrsetfunc>(PepType_GetSlot(t, Py_tp_descr_set));
+}
+
+/// Returns the call slot of the PyTypeObject.
+inline ternaryfunc PepExt_Type_GetCallSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<ternaryfunc>(PepType_GetSlot(t, Py_tp_call));
+}
+
+/// Returns the new slot of the PyTypeObject.
+inline newfunc PepExt_Type_GetNewSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<newfunc>(PepType_GetSlot(t, Py_tp_new));
+}
+
+/// Returns the init slot of the PyTypeObject.
+inline initproc PepExt_Type_GetInitSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<initproc>(PepType_GetSlot(t, Py_tp_init));
+}
+
+/// Returns the free slot of the PyTypeObject.
+inline freefunc PepExt_Type_GetFreeSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<freefunc>(PepType_GetSlot(t, Py_tp_free));
+}
+
+/// Invokes the free slot of the PyTypeObject.
+inline void PepExt_TypeCallFree(PyTypeObject *t, void *object)
+{
+ PepExt_Type_GetFreeSlot(t)(object);
+}
+
+/// Invokes the free slot of the PyTypeObject.
+inline void PepExt_TypeCallFree(PyObject *object)
+{
+ PepExt_Type_GetFreeSlot(Py_TYPE(object))(object);
+}
+
+#endif // PEP384EXT_H
diff --git a/sources/shiboken6/libshiboken/sbkcontainer.h b/sources/shiboken6/libshiboken/sbkcontainer.h
index 96faf95ee..240c772a9 100644
--- a/sources/shiboken6/libshiboken/sbkcontainer.h
+++ b/sources/shiboken6/libshiboken/sbkcontainer.h
@@ -63,7 +63,8 @@ public:
static PyObject *tpNew(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */)
{
- auto *me = reinterpret_cast<ShibokenContainer *>(subtype->tp_alloc(subtype, 0));
+ allocfunc allocFunc = reinterpret_cast<allocfunc>(PepType_GetSlot(subtype, Py_tp_alloc));
+ auto *me = reinterpret_cast<ShibokenContainer *>(allocFunc(subtype, 0));
auto *d = new ShibokenSequenceContainerPrivate;
d->m_list = new SequenceContainer;
d->m_ownsList = true;
@@ -91,7 +92,9 @@ public:
if (d->m_ownsList)
delete d->m_list;
delete d;
- Py_TYPE(pySelf)->tp_base->tp_free(self);
+ auto freeFunc = reinterpret_cast<freefunc>(PepType_GetSlot(Py_TYPE(pySelf)->tp_base,
+ Py_tp_free));
+ freeFunc(self);
}
static Py_ssize_t sqLen(PyObject *self)
diff --git a/sources/shiboken6/libshiboken/sbkfeature_base.cpp b/sources/shiboken6/libshiboken/sbkfeature_base.cpp
index 906df8e19..1bd4d6851 100644
--- a/sources/shiboken6/libshiboken/sbkfeature_base.cpp
+++ b/sources/shiboken6/libshiboken/sbkfeature_base.cpp
@@ -4,6 +4,7 @@
#include "basewrapper.h"
#include "basewrapper_p.h"
#include "autodecref.h"
+#include "pep384ext.h"
#include "sbkenum.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
@@ -300,7 +301,7 @@ PyObject *mangled_type_getattro(PyTypeObject *type, PyObject *name)
* with the complex `tp_getattro` of `QObject` and other instances.
* What we change here is the meta class of `QObject`.
*/
- static getattrofunc const type_getattro = PyType_Type.tp_getattro;
+ static getattrofunc const type_getattro = PepExt_Type_GetGetAttroSlot(&PyType_Type);
static PyObject *const ignAttr1 = PyName::qtStaticMetaObject();
static PyObject *const ignAttr2 = PyMagicName::get();
static PyTypeObject *const EnumMeta = getPyEnumMeta();
diff --git a/sources/shiboken6/libshiboken/voidptr.cpp b/sources/shiboken6/libshiboken/voidptr.cpp
index ed4f88ad1..7045b08b1 100644
--- a/sources/shiboken6/libshiboken/voidptr.cpp
+++ b/sources/shiboken6/libshiboken/voidptr.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "voidptr.h"
+#include "pep384ext.h"
#include "sbkconverter.h"
#include "basewrapper.h"
#include "basewrapper_p.h"
@@ -24,8 +25,7 @@ PyObject *SbkVoidPtrObject_new(PyTypeObject *type, PyObject * /* args */, PyObje
// like this, actual call forgotten:
// SbkVoidPtrObject *self =
// reinterpret_cast<SbkVoidPtrObject *>(type->tp_alloc);
- PyObject *ob = type->tp_alloc(type, 0);
- auto *self = reinterpret_cast<SbkVoidPtrObject *>(ob);
+ auto *self = PepExt_TypeCallAlloc<SbkVoidPtrObject>(type, 0);
if (self != nullptr) {
self->cptr = nullptr;