aboutsummaryrefslogtreecommitdiffstats
path: root/sources/pyside6/libpyside/feature_select.cpp
diff options
context:
space:
mode:
authorChristian Tismer <tismer@stackless.com>2022-11-16 14:58:28 +0100
committerChristian Tismer <tismer@stackless.com>2022-11-23 15:15:21 +0100
commit2b14cba81265bbeb31b35dc4e04ccd3f6e29c4ee (patch)
treea7d4fc1b8c48250cca7d555b074b44469b21e2a6 /sources/pyside6/libpyside/feature_select.cpp
parent8ce76143247f99b25e8da5ace81df6882a17db30 (diff)
__feature__: Fix true_property inheritance
The wrapping process creates wrapper functions for all C functions, also for those which are meant as virtual functions promoting an inherited function. Because properties appear as such additional functions, we need to convert not only according to the property strings, but also use the mro to reach the extra functions indirectly. [ChangeLog][PySide6] true_property was fixed to work with inherited properties as well. Change-Id: I176a30df77f550504f3aaf71e0c20de3e0707792 Fixes: PYSIDE-2042 Pick-to: 6.4 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'sources/pyside6/libpyside/feature_select.cpp')
-rw-r--r--sources/pyside6/libpyside/feature_select.cpp30
1 files changed, 26 insertions, 4 deletions
diff --git a/sources/pyside6/libpyside/feature_select.cpp b/sources/pyside6/libpyside/feature_select.cpp
index 567ae79e0..cf55ae7cf 100644
--- a/sources/pyside6/libpyside/feature_select.cpp
+++ b/sources/pyside6/libpyside/feature_select.cpp
@@ -614,6 +614,28 @@ PyObject *adjustPropertyName(PyObject *dict, PyObject *name)
return name;
}
+static QByteArrayList GetPropertyStringsMro(PyTypeObject *type)
+{
+ /*
+ * PYSIDE-2042: There are possibly more methods which should become properties,
+ * because the wrapping process does not obey inheritance.
+ * Therefore, we need to walk the mro to find property strings.
+ */
+ auto res = QByteArrayList();
+
+ PyObject *mro = type->tp_mro;
+ Py_ssize_t idx, n = PyTuple_GET_SIZE(mro);
+ // We leave 'Shiboken.Object' and 'object' alone, therefore "n - 2".
+ for (idx = 0; idx < n - 2; idx++) {
+ auto *subType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ auto props = SbkObjectType_GetPropertyStrings(subType);
+ if (props != nullptr)
+ for (; *props != nullptr; ++props)
+ res << QByteArray(*props);
+ }
+ return res;
+}
+
static bool feature_02_true_property(PyTypeObject *type, PyObject *prev_dict, int id)
{
/*
@@ -643,12 +665,12 @@ static bool feature_02_true_property(PyTypeObject *type, PyObject *prev_dict, in
}
// We then replace methods by properties.
bool lower = (id & 0x01) != 0;
- auto props = SbkObjectType_GetPropertyStrings(type);
- if (props == nullptr || *props == nullptr)
+ auto props = GetPropertyStringsMro(type);
+ if (props.isEmpty())
return true;
- for (; *props != nullptr; ++props) {
+
+ for (const auto &propStr : std::as_const(props)) {
bool isStdWrite;
- auto propStr = *props;
auto fields = parseFields(propStr, &isStdWrite);
bool haveWrite = fields.size() == 3;
PyObject *name = make_snake_case(fields[0], lower);