diff options
author | Christian Tismer <tismer@stackless.com> | 2022-11-16 14:58:28 +0100 |
---|---|---|
committer | Christian Tismer <tismer@stackless.com> | 2022-11-23 15:15:21 +0100 |
commit | 2b14cba81265bbeb31b35dc4e04ccd3f6e29c4ee (patch) | |
tree | a7d4fc1b8c48250cca7d555b074b44469b21e2a6 /sources/pyside6/libpyside/feature_select.cpp | |
parent | 8ce76143247f99b25e8da5ace81df6882a17db30 (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.cpp | 30 |
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); |