diff options
author | Friedemann Kleint <[email protected]> | 2025-02-03 11:47:17 +0100 |
---|---|---|
committer | Friedemann Kleint <[email protected]> | 2025-02-11 15:40:44 +0100 |
commit | c1b62556bffbdd2b5e5eecc790ec4732b93e05a1 (patch) | |
tree | e11589a692706b59a70ebcf41e93df07f2db2573 | |
parent | a7b1ef20fe791ac6bec92d1f05904ff14bc34e5b (diff) |
Fix crash of signals with object-type parameter being passed by const-ref
Add a further indirection in callPythonMetaMethodHelper()
when only a pointer conversion is available for a const-ref parameter.
Task-number: PYSIDE-3004
Change-Id: I6ec7c5a9d4d30c8e4973ec79534d5f3eb3bf8204
Reviewed-by: Shyamnath Premnadh <[email protected]>
4 files changed, 29 insertions, 3 deletions
diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp index 744b77b51..72a427641 100644 --- a/sources/pyside6/libpyside/signalmanager.cpp +++ b/sources/pyside6/libpyside/signalmanager.cpp @@ -464,16 +464,21 @@ static int callPythonMetaMethodHelper(const QByteArrayList ¶mTypes, const char *returnType /* = nullptr */, void **args, PyObject *pyCallable) { + using SpecificConverter = Shiboken::Conversions::SpecificConverter; const qsizetype argsSize = paramTypes.size(); Shiboken::AutoDecRef preparedArgs(PyTuple_New(argsSize)); for (qsizetype i = 0; i < argsSize; ++i) { void *data = args[i + 1]; - auto param = paramTypes.at(i); - Shiboken::Conversions::SpecificConverter converter(param.constData()); + const auto ¶m = paramTypes.at(i); + SpecificConverter converter(param.constData()); if (!converter.isValid()) return CallResult::CallArgumentError + int(i); - PyTuple_SetItem(preparedArgs, i, converter.toPython(data)); + // Only pointer conversion available for const-ref - add indirection + const bool valueToPtr = converter.conversionType() == SpecificConverter::PointerConversion + && !param.endsWith('*') && param != "PyObject"_ba; + auto *src = valueToPtr ? &data : data; + PyTuple_SetItem(preparedArgs, i, converter.toPython(src)); } QScopedPointer<Shiboken::Conversions::SpecificConverter> retConverter; diff --git a/sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py b/sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py index 34b8f7f62..64147e15e 100644 --- a/sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py +++ b/sources/pyside6/tests/pysidetest/signalemissionfrompython_test.py @@ -27,6 +27,11 @@ class Receiver(QObject): def __init__(self, p=None): super().__init__(p) self.received_handle = -1 + self.received_name = '' + + @Slot(QObject) + def slotObjectByConstRef(self, o): + self.received_name = o.objectName() @Slot(Connection) def connectionSlot(self, c): @@ -37,7 +42,9 @@ class SignalEmissionFromPython(unittest.TestCase): def setUp(self): self.obj1 = TestObject(0) + self.obj1.setObjectName('obj1') self.obj2 = TestObject(0) + self.obj2.setObjectName('obj2') self.one_called = 0 self.two_called = 0 @@ -114,6 +121,12 @@ class SignalEmissionFromPython(unittest.TestCase): self.assertEqual(self.one_called, 1) self.assertEqual(self.two_called, 2) + def testSignalObjectByConstRef(self): + receiver = Receiver() + self.obj1.objectByConstRef.connect(receiver.slotObjectByConstRef) + self.obj1.emitObjectByConstRef() + self.assertEqual(receiver.received_name, 'obj1') + if __name__ == '__main__': unittest.main() diff --git a/sources/pyside6/tests/pysidetest/testobject.cpp b/sources/pyside6/tests/pysidetest/testobject.cpp index bcf629bf8..3107be09a 100644 --- a/sources/pyside6/tests/pysidetest/testobject.cpp +++ b/sources/pyside6/tests/pysidetest/testobject.cpp @@ -47,6 +47,11 @@ void TestObject::emitFlagsSignal(Qt::Alignment alignment) emit flagsSignal(alignment); } +void TestObject::emitObjectByConstRef() +{ + emit objectByConstRef(*this); +} + void TestObject::setQLatin1String(QLatin1String v) { m_qLatin1String = v; diff --git a/sources/pyside6/tests/pysidetest/testobject.h b/sources/pyside6/tests/pysidetest/testobject.h index 9689589ad..7c273c891 100644 --- a/sources/pyside6/tests/pysidetest/testobject.h +++ b/sources/pyside6/tests/pysidetest/testobject.h @@ -54,6 +54,8 @@ public: void emitFlagsSignal(Qt::Alignment alignment); + void emitObjectByConstRef(); + static constexpr auto LATIN1_TEST_FIELD = QLatin1StringView("test"); void setQLatin1String(QLatin1String v); @@ -69,6 +71,7 @@ signals: void signalWithTypedefValue(TypedefValue value); void signalWithContainerTypedefValue(const IntList &il); void flagsSignal(Qt::Alignment alignment); + void objectByConstRef(const QObject &qobject); private: int m_idValue; |