aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2023-10-26 23:32:10 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-11-20 21:39:10 +0000
commit366925c6bc08b130954ccfa1123a883253fe49fc (patch)
tree68380e3819ce431cdac40f21bbdfccbc0a680854
parentd650a09764defb1cf206827485e0be24b34c6075 (diff)
Shiboken: Fix an oversight when removing ob_type
SbkObjectType's meta type was changed due to a wrong fix. This has strange side effects when applying PEP 697 because a wrong action is taken. The meta class for class property was also rewritten to have its own meta class for PEP 697 compatibility. Amends: 73adefe22ffbfabe0ef213e9c2fe2c56efdd7488 Change-Id: I2d5c0a58e274c0a60496e29cbd714b9e69bfffbd Pick-to: 6.5 6.2 Task-number: PYSIDE-2230 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> (cherry picked from commit 5935b0f45503eabbd24c7379701b48bb2874a8ac) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--sources/pyside6/libpyside/class_property.cpp46
1 files changed, 42 insertions, 4 deletions
diff --git a/sources/pyside6/libpyside/class_property.cpp b/sources/pyside6/libpyside/class_property.cpp
index 140956035..99104445c 100644
--- a/sources/pyside6/libpyside/class_property.cpp
+++ b/sources/pyside6/libpyside/class_property.cpp
@@ -33,6 +33,46 @@ static int PyClassProperty_descr_set(PyObject *self, PyObject *obj, PyObject *va
return PyProperty_Type.tp_descr_set(self, cls, value);
}
+// PYSIDE-2230: Why is this metaclass necessary?
+//
+// The problem is that the property object already exists as a Python
+// object. We derive a subclass for class properties, without
+// repeating everything but just by adding something to support
+// the class-ness.
+//
+// But this Python property has as metaclass `type` which is incompatible
+// now with SbkObjectType, which generates physically larger types that
+// are incompatible with properties by using PEP 697.
+// Adding a compatible metaclass that is unrelated to `SbkObjectType`
+// is the correct solution. Re-using `SbkObjectType` was actually an abuse,
+// since Python properties are in no way PySide objects.
+
+static PyTypeObject *createClassPropertyTypeType()
+{
+ PyType_Slot PyClassPropertyType_Type_slots[] = {
+ {Py_tp_base, static_cast<void *>(&PyType_Type)},
+ {Py_tp_alloc, reinterpret_cast<void *>(PyType_GenericAlloc)},
+ {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
+ {0, nullptr}
+ };
+
+ PyType_Spec PyClassPropertyType_Type_spec = {
+ "1:Shiboken.ClassPropertyType",
+ 0,
+ 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_TYPE_SUBCLASS,
+ PyClassPropertyType_Type_slots,
+ };
+
+ return SbkType_FromSpec(&PyClassPropertyType_Type_spec);
+}
+
+PyTypeObject *PyClassPropertyType_TypeF()
+{
+ static auto *type = createClassPropertyTypeType();
+ return type;
+}
+
// The property `__doc__` default does not work for class properties
// because PyProperty_Type.tp_init thinks this is a subclass which needs PyObject_SetAttr.
// We call `__init__` while pretending to be a PyProperty_Type instance.
@@ -48,7 +88,7 @@ static int PyClassProperty_tp_init(PyObject *self, PyObject *args, PyObject *kwa
static PyTypeObject *createPyClassPropertyType()
{
PyType_Slot PyClassProperty_slots[] = {
- {Py_tp_getset, nullptr}, // will be set below
+ {Py_tp_getset, reinterpret_cast<void *>(PyProperty_Type.tp_getset)}, // will be set below
{Py_tp_base, reinterpret_cast<void *>(&PyProperty_Type)},
{Py_tp_descr_get, reinterpret_cast<void *>(PyClassProperty_descr_get)},
{Py_tp_descr_set, reinterpret_cast<void *>(PyClassProperty_descr_set)},
@@ -64,10 +104,9 @@ static PyTypeObject *createPyClassPropertyType()
PyClassProperty_slots,
};
- PyClassProperty_slots[0].pfunc = PyProperty_Type.tp_getset;
if (_PepRuntimeVersion() >= 0x030A00)
PyClassProperty_spec.basicsize = sizeof(propertyobject310);
- return SbkType_FromSpec(&PyClassProperty_spec);
+ return SbkType_FromSpecWithMeta(&PyClassProperty_spec, PyClassPropertyType_TypeF());
}
PyTypeObject *PyClassProperty_TypeF()
@@ -126,7 +165,6 @@ void init(PyObject *module)
{
PyTypeObject *type = SbkObjectType_TypeF();
type->tp_setattro = SbkObjectType_meta_setattro;
- reinterpret_cast<PyObject *>(type)->ob_type = type;
if (InitSignatureStrings(PyClassProperty_TypeF(), PyClassProperty_SignatureStrings) < 0)
return;