PyQt 6.11.0 / Qt 6.11.2: QMetaMethodBuilder layout mismatch breaks slot return types with Clang
Phil Thompson
phil at riverbankcomputing.com
Mon Sep 28 13:01:33 BST 2026
On 16/09/2026 09:11, pyqt-user.folic415 at passinbox.com wrote:
> 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?
Yes, thanks.
Phil
More information about the PyQt
mailing list