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