diff options
author | Christian Tismer <tismer@stackless.com> | 2023-10-26 23:32:10 +0200 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2023-12-07 08:02:41 +0000 |
commit | fa45234cc20ad514e89e7124e2aee9a6347ea474 (patch) | |
tree | ab7af5fe13ef19d44f507b2f169abc7ee065bd91 /sources/shiboken6/libshiboken/basewrapper.cpp | |
parent | 2e06e148ff33b66ca64d4cc3acb2aa4f79f89d94 (diff) |
PEP 697: Use the new type extension provision
By Python 3.12, there is now an official way to extend
heap types by custom extra data.
When we supported PyPy, the old type extension of PySide
did no longer work, and we introduced shadow dicts.
With the interface found in Python 3.12, we can use direct
extended data, again.
The supporting structures are not Limited API compatible.
We implemented a patch that enables this anyway, but it
is valid for this version only without a new review.
NOTE: The documentation lists `PyObject_GetTypeData` as
Limited API since Version 3.12, but in fact we had to
write a cheating patch.
[ChangeLog][PySide6] Hidden Type Extensions according to
PEP 697 are now used instead of shadow dictionaries.
Change-Id: I4b724ba7bcc72470b13f55ea5ebf94666061420d
Task-number: PYSIDE-2230
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/shiboken6/libshiboken/basewrapper.cpp')
-rw-r--r-- | sources/shiboken6/libshiboken/basewrapper.cpp | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp index 828c54a89..6244cc395 100644 --- a/sources/shiboken6/libshiboken/basewrapper.cpp +++ b/sources/shiboken6/libshiboken/basewrapper.cpp @@ -152,11 +152,21 @@ static PyTypeObject *createObjectTypeType() "1:Shiboken.ObjectType", static_cast<int>(PyType_Type.tp_basicsize) + 1, // see above 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_TYPE_SUBCLASS, SbkObjectType_Type_slots, }; - return SbkType_FromSpec(&SbkObjectType_Type_spec); + PyType_Spec SbkObjectType_Type_spec_312 = { + "1:Shiboken.ObjectType", + -long(sizeof(SbkObjectTypePrivate)), + 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined + Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_TYPE_SUBCLASS, + SbkObjectType_Type_slots, + }; + + return SbkType_FromSpec(_PepRuntimeVersion() >= 0x030C00 ? + &SbkObjectType_Type_spec_312 : + &SbkObjectType_Type_spec); } PyTypeObject *SbkObjectType_TypeF(void) @@ -249,12 +259,15 @@ static PyTypeObject *createObjectType() // But before 3.12 is the minimum version, we cannot use the new // function, although we would need this for 3.12 :-D // We do a special patching here that is triggered through Py_None. - return SbkType_FromSpec_BMDWB(&SbkObject_Type_spec, - Py_None, // bases, special flag! - SbkObjectType_TypeF(), - offsetof(SbkObject, ob_dict), - offsetof(SbkObject, weakreflist), - nullptr); // bufferprocs + auto *type = SbkType_FromSpec_BMDWB(&SbkObject_Type_spec, + Py_None, // bases, spectial flag! + SbkObjectType_TypeF(), + offsetof(SbkObject, ob_dict), + offsetof(SbkObject, weakreflist), + nullptr); // bufferprocs + // Initialize the hidden data area. + _PepPostInit_SbkObject_Type(type); + return type; } PyTypeObject *SbkObject_TypeF(void) @@ -661,10 +674,8 @@ PyObject *FallbackRichCompare(PyObject *self, PyObject *other, int op) bool SbkObjectType_Check(PyTypeObject *type) { - static auto *obMeta = reinterpret_cast<PyObject *>(SbkObjectType_TypeF()); - auto *obType = reinterpret_cast<PyObject *>(type); - return obMeta == reinterpret_cast<PyObject *>(Py_TYPE(obType)) - || PyObject_IsInstance(obType, obMeta); + static auto *meta = SbkObjectType_TypeF(); + return Py_TYPE(type) == meta || PyType_IsSubtype(Py_TYPE(type), meta); } } //extern "C" @@ -1006,16 +1017,19 @@ introduceWrapperType(PyObject *enclosingObject, void setSubTypeInitHook(PyTypeObject *type, SubTypeInitHook func) { + assert(SbkObjectType_Check(type)); PepType_SOTP(type)->subtype_init = func; } void *getTypeUserData(PyTypeObject *type) { + assert(SbkObjectType_Check(type)); return PepType_SOTP(type)->user_data; } void setTypeUserData(PyTypeObject *type, void *userData, DeleteUserDataFunc d_func) { + assert(SbkObjectType_Check(type)); auto *sotp = PepType_SOTP(type); sotp->user_data = userData; sotp->d_func = d_func; |