PyQt 6.11.0 / Qt 6.11.2: QMetaMethodBuilder layout mismatch breaks slot return types with Clang
pyqt-user.folic415 at passinbox.com
pyqt-user.folic415 at passinbox.com
Wed Sep 16 09:11:21 BST 2026
Hello,
I encountered a compatibility issue when building PyQt 6.11.0 against Qt
6.11.2 for Android using python-for-android.
I then let my coding harness analyze the issue and it came up with a
patch and the issue description below. I don't fully understand but it
might be helpful for you to fix a bug:
Environment
- PyQt 6.11.0
- Qt 6.11.2
- Python 3.11.15
- Android NDK r28c, Clang 19
- x86_64 APK running on an Android 9 emulator
A Python slot declared with @pyqtSlot(result=str) returns undefined when
invoked from QML. In my application, passing that result to another slot
accepting a string produces an empty string and subsequently a
KeyError.
### Apparent cause
Qt 6.11.2 added a QMetaMethod::MethodType _type member to
QMetaMethodBuilder:
https://github.com/qt/qtbase/commit/a598cc13db785acc6fe85ee5f54735557d878bcc
<https://github.com/qt/qtbase/commit/a598cc13db785acc6fe85ee5f54735557d878bcc>
However, PyQt’s copied declaration in:
qpy/QtCore/qpycore_qmetaobjectbuilder.h
still contains only:
const QMetaObjectBuilder *_mobj;
int _index;
On x86_64, the new field occupies bytes previously considered padding.
Clang can discard those bytes when receiving a builder returned by Qt.
Qt subsequently reads an invalid _type, causing setReturnType() to
silently do nothing. The generated slot metadata therefore remains void,
and QML receives undefined.
### Independent reproduction
A focused C++ test using PyQt’s copied header and the actual Qt 6.11.2
library calls:
auto slot = builder.addSlot("startWizard()");
slot.setReturnType("QString");
It then inspects the method produced by builder.toMetaObject().
With deliberately nonzero backing storage to expose the missing field
deterministically:
Compiler Original declaration Corrected declaration
━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━━━━
Clang 19, -O2 Return type void Return type QString
─────────────── ────────────────────── ───────────────────────
GCC, -O2 Return type QString Return type QString
GCC happens to preserve the relevant bytes in this reproduction. Clang
also exhibits the failure with optimizations disabled.
### Proposed correction
Include and add the following member immediately after _index in PyQt’s
QMetaMethodBuilder declaration:
#if <#if> QT_VERSION >= QT_VERSION_CHECK(6, 11, 2)
QMetaMethod::MethodType _type = QMetaMethod::Method;
#endif <#endif>
This restores the correct return metadata in the focused Clang
reproduction. Verification of the patched Android APK is still pending.
I also checked the official 6.11.1.dev2609111110 source snapshot; its
copied header is unchanged and still lacks this member.
Could this declaration be updated in an upcoming PyQt release?
Thank you.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20260916/5972636b/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 583 bytes
Desc: OpenPGP digital signature
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20260916/5972636b/attachment.sig>
More information about the PyQt
mailing list