diff options
author | Christian Tismer <tismer@stackless.com> | 2022-10-20 09:06:43 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-10-20 14:52:53 +0000 |
commit | 5ed3e6f5ddf8f2323d596f04f119b350e6475d5c (patch) | |
tree | 1228e59ddfbde88fd19ad14c1bb1443748966b00 | |
parent | 7fa7922e0bc2e92d2601636afc4d307bc27b2c43 (diff) |
Finally implement the __slots__ feature in PySide
The __slots__ feature never worked for PySide at all.
It was forgotten that __slots__ are implemented as descriptors
which are living at the end of the type instance.
This was solved for normal SbkObjects and for QApplication
as well. Some slight rearrangement of type casts was necessary.
[ChangeLog][PySide6] The long missing support for __slots__
was finally added.
Change-Id: Ieddb92104ab10e80e564b38e053f280f90d7a6a7
Fixes: PYSIDE-1970
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit d58e262b11c278764a390eb863ca6402cdbe60cd)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | sources/shiboken6/libshiboken/basewrapper.cpp | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp index 1fec305a6..14aed3606 100644 --- a/sources/shiboken6/libshiboken/basewrapper.cpp +++ b/sources/shiboken6/libshiboken/basewrapper.cpp @@ -390,6 +390,17 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete) } } +static inline PyObject *_Sbk_NewVarObject(PyTypeObject *type) +{ + // PYSIDE-1970: Support __slots__, implemented by PyVarObject + auto const baseSize = sizeof(SbkObject); + auto varCount = Py_SIZE(type); + auto *self = PyObject_GC_NewVar(PyObject, type, varCount); + if (varCount) + std::memset(reinterpret_cast<char *>(self) + baseSize, 0, varCount * sizeof(void *)); + return self; +} + void SbkDeallocWrapper(PyObject *pyObj) { SbkDeallocWrapperCommon(pyObj, true); @@ -469,7 +480,7 @@ PyObject *MakeQAppWrapper(PyTypeObject *type) } // monitoring the last application state - PyObject *qApp_curr = type != nullptr ? PyObject_GC_New(PyObject, type) : Py_None; + PyObject *qApp_curr = type != nullptr ? _Sbk_NewVarObject(type) : Py_None; static PyObject *builtins = PyEval_GetBuiltins(); if (PyDict_SetItem(builtins, Shiboken::PyName::qApp(), qApp_curr) < 0) return nullptr; @@ -574,11 +585,11 @@ static PyTypeObject *SbkObjectType_tp_new(PyTypeObject *metatype, PyObject *args return newType; } -static PyObject *_setupNew(SbkObject *self, PyTypeObject *subtype) +static PyObject *_setupNew(PyObject *obSelf, PyTypeObject *subtype) { auto *obSubtype = reinterpret_cast<PyObject *>(subtype); auto *sbkSubtype = subtype; - auto *obSelf = reinterpret_cast<PyObject *>(self); + auto *self = reinterpret_cast<SbkObject *>(obSelf); Py_INCREF(obSubtype); auto d = new SbkObjectPrivate; @@ -602,18 +613,19 @@ static PyObject *_setupNew(SbkObject *self, PyTypeObject *subtype) return obSelf; } -PyObject *SbkObject_tp_new(PyTypeObject *subtype, PyObject *, PyObject *) +PyObject *SbkObject_tp_new(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */) { - SbkObject *self = PyObject_GC_New(SbkObject, subtype); + PyObject *self = _Sbk_NewVarObject(subtype); return _setupNew(self, subtype); } PyObject *SbkQApp_tp_new(PyTypeObject *subtype, PyObject *, PyObject *) { - auto self = reinterpret_cast<SbkObject *>(MakeQAppWrapper(subtype)); + auto *obSelf = MakeQAppWrapper(subtype); + auto *self = reinterpret_cast<SbkObject *>(obSelf); if (self == nullptr) return nullptr; - auto ret = _setupNew(self, subtype); + auto ret = _setupNew(obSelf, subtype); auto priv = self->d; priv->isQAppSingleton = 1; return ret; |