diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-03-12 14:16:57 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2024-03-13 13:58:45 +0100 |
commit | 3793031ed13bbb7f1857a349caa3d87d79056e06 (patch) | |
tree | 4d673409612a252fe489bb3cd4241bed8a1657ca | |
parent | 722cba9af5143222e726a113718d4a32c97d6cae (diff) |
libpyside: Improve type conversion error messages of metafunction invocation
Refactor and streamline the code a bit.
Pick-to: 6.6
Task-number: PYSIDE-2633
Change-Id: I433b136ac036a9a297d2c22ad8dfa6af45ad46b0
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
-rw-r--r-- | sources/pyside6/libpyside/signalmanager.cpp | 57 |
1 files changed, 36 insertions, 21 deletions
diff --git a/sources/pyside6/libpyside/signalmanager.cpp b/sources/pyside6/libpyside/signalmanager.cpp index 1738fa926..c38fc2764 100644 --- a/sources/pyside6/libpyside/signalmanager.cpp +++ b/sources/pyside6/libpyside/signalmanager.cpp @@ -40,7 +40,7 @@ using namespace Qt::StringLiterals; #include "globalreceiverv2.h" static PyObject *metaObjectAttr = nullptr; -static PyObject *parseArguments(const QList< QByteArray >& paramTypes, void **args); +static PyObject *parseArguments(const QMetaMethod &method, void **args); static bool emitShortCircuitSignal(QObject *source, int signalIndex, PyObject *args); static void destroyMetaObject(PyObject *obj) { @@ -70,6 +70,29 @@ static const char *metaCallName(QMetaObject::Call call) return it != mapping.constEnd() ? it.value() : "<Unknown>"; } +static QByteArray methodSignature(const QMetaMethod &method) +{ + QByteArray result; + if (auto *t = method.typeName()) { + result += t; + result += ' '; + } + result += method.methodSignature(); + return result; +} + +static QByteArray msgCannotConvertParameter(const QMetaMethod &method, qsizetype p) +{ + return "Cannot call meta function \""_ba + methodSignature(method) + + "\" because parameter " + QByteArray::number(p) + " of type \""_ba + + method.parameterTypeName(p) + "\" cannot be converted."_ba; +} + +static QByteArray msgCannotConvertReturn(const QMetaMethod &method) +{ + return "The return value of \""_ba + methodSignature(method) + "\" cannot be converted."_ba; +} + namespace PySide { PyObjectWrapper::PyObjectWrapper() @@ -539,34 +562,27 @@ int SignalManager::callPythonMetaMethod(const QMetaMethod &method, void **args, Q_ASSERT(pyMethod); Shiboken::GilState gil; - PyObject *pyArguments = nullptr; - - if (isShortCuit){ - pyArguments = reinterpret_cast<PyObject *>(args[1]); - } else { - pyArguments = parseArguments(method.parameterTypes(), args); - } + PyObject *pyArguments = isShortCuit + ? reinterpret_cast<PyObject *>(args[1]) : parseArguments(method, args); if (pyArguments) { QScopedPointer<Shiboken::Conversions::SpecificConverter> retConverter; const char *returnType = method.typeName(); - if (returnType && std::strcmp("", returnType) && std::strcmp("void", returnType)) { + if (returnType != nullptr && returnType[0] != 0 && std::strcmp("void", returnType) != 0) { retConverter.reset(new Shiboken::Conversions::SpecificConverter(returnType)); if (!retConverter->isValid()) { - PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s' to call Python meta method.", returnType); + PyErr_SetString(PyExc_RuntimeError, msgCannotConvertReturn(method).constData()); return -1; } } Shiboken::AutoDecRef retval(PyObject_CallObject(pyMethod, pyArguments)); - if (!isShortCuit && pyArguments){ + if (!isShortCuit && pyArguments) Py_DECREF(pyArguments); - } - if (!retval.isNull() && retval != Py_None && !PyErr_Occurred() && retConverter) { + if (!retval.isNull() && retval != Py_None && !PyErr_Occurred() && retConverter) retConverter->toCpp(retval, args[0]); - } } return -1; @@ -710,8 +726,9 @@ const QMetaObject *SignalManager::retrieveMetaObject(PyObject *self) return builder->update(); } -static PyObject *parseArguments(const QList<QByteArray>& paramTypes, void **args) +static PyObject *parseArguments(const QMetaMethod &method, void **args) { + const auto ¶mTypes = method.parameterTypes(); const qsizetype argsSize = paramTypes.size(); PyObject *preparedArgs = PyTuple_New(argsSize); @@ -723,15 +740,13 @@ static PyObject *parseArguments(const QList<QByteArray>& paramTypes, void **args if (param.startsWith("QAudio::"_ba)) param.insert(1, 't'); #endif - const char *dataType = param.constData(); - Shiboken::Conversions::SpecificConverter converter(dataType); - if (converter) { - PyTuple_SET_ITEM(preparedArgs, i, converter.toPython(data)); - } else { - PyErr_Format(PyExc_TypeError, "Can't call meta function because I have no idea how to handle %s", dataType); + Shiboken::Conversions::SpecificConverter converter(param.constData()); + if (!converter) { + PyErr_SetString(PyExc_TypeError, msgCannotConvertParameter(method, i).constData()); Py_DECREF(preparedArgs); return nullptr; } + PyTuple_SET_ITEM(preparedArgs, i, converter.toPython(data)); } return preparedArgs; } |