Skip to content

Commit 5935b0f

Browse files
committed
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: 73adefe Change-Id: I2d5c0a58e274c0a60496e29cbd714b9e69bfffbd Pick-to: 6.6 6.5 6.2 Task-number: PYSIDE-2230 Reviewed-by: Friedemann Kleint <[email protected]>
1 parent 9f33028 commit 5935b0f

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

sources/pyside6/libpyside/class_property.cpp

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,46 @@ static int PyClassProperty_descr_set(PyObject *self, PyObject *obj, PyObject *va
3333
return PyProperty_Type.tp_descr_set(self, cls, value);
3434
}
3535

36+
// PYSIDE-2230: Why is this metaclass necessary?
37+
//
38+
// The problem is that the property object already exists as a Python
39+
// object. We derive a subclass for class properties, without
40+
// repeating everything but just by adding something to support
41+
// the class-ness.
42+
//
43+
// But this Python property has as metaclass `type` which is incompatible
44+
// now with SbkObjectType, which generates physically larger types that
45+
// are incompatible with properties by using PEP 697.
46+
// Adding a compatible metaclass that is unrelated to `SbkObjectType`
47+
// is the correct solution. Re-using `SbkObjectType` was actually an abuse,
48+
// since Python properties are in no way PySide objects.
49+
50+
static PyTypeObject *createClassPropertyTypeType()
51+
{
52+
PyType_Slot PyClassPropertyType_Type_slots[] = {
53+
{Py_tp_base, static_cast<void *>(&PyType_Type)},
54+
{Py_tp_alloc, reinterpret_cast<void *>(PyType_GenericAlloc)},
55+
{Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
56+
{0, nullptr}
57+
};
58+
59+
PyType_Spec PyClassPropertyType_Type_spec = {
60+
"1:Shiboken.ClassPropertyType",
61+
0,
62+
0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
63+
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_TYPE_SUBCLASS,
64+
PyClassPropertyType_Type_slots,
65+
};
66+
67+
return SbkType_FromSpec(&PyClassPropertyType_Type_spec);
68+
}
69+
70+
PyTypeObject *PyClassPropertyType_TypeF()
71+
{
72+
static auto *type = createClassPropertyTypeType();
73+
return type;
74+
}
75+
3676
// The property `__doc__` default does not work for class properties
3777
// because PyProperty_Type.tp_init thinks this is a subclass which needs PyObject_SetAttr.
3878
// 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
4888
static PyTypeObject *createPyClassPropertyType()
4989
{
5090
PyType_Slot PyClassProperty_slots[] = {
51-
{Py_tp_getset, nullptr}, // will be set below
91+
{Py_tp_getset, reinterpret_cast<void *>(PyProperty_Type.tp_getset)}, // will be set below
5292
{Py_tp_base, reinterpret_cast<void *>(&PyProperty_Type)},
5393
{Py_tp_descr_get, reinterpret_cast<void *>(PyClassProperty_descr_get)},
5494
{Py_tp_descr_set, reinterpret_cast<void *>(PyClassProperty_descr_set)},
@@ -64,10 +104,9 @@ static PyTypeObject *createPyClassPropertyType()
64104
PyClassProperty_slots,
65105
};
66106

67-
PyClassProperty_slots[0].pfunc = PyProperty_Type.tp_getset;
68107
if (_PepRuntimeVersion() >= 0x030A00)
69108
PyClassProperty_spec.basicsize = sizeof(propertyobject310);
70-
return SbkType_FromSpec(&PyClassProperty_spec);
109+
return SbkType_FromSpecWithMeta(&PyClassProperty_spec, PyClassPropertyType_TypeF());
71110
}
72111

73112
PyTypeObject *PyClassProperty_TypeF()
@@ -126,7 +165,6 @@ void init(PyObject *module)
126165
{
127166
PyTypeObject *type = SbkObjectType_TypeF();
128167
type->tp_setattro = SbkObjectType_meta_setattro;
129-
reinterpret_cast<PyObject *>(type)->ob_type = type;
130168

131169
if (InitSignatureStrings(PyClassProperty_TypeF(), PyClassProperty_SignatureStrings) < 0)
132170
return;

0 commit comments

Comments
 (0)