diff options
-rw-r--r-- | PySide/QtSql/typesystem_sql.xml | 3 | ||||
-rw-r--r-- | libpyside/dynamicqmetaobject.cpp | 2 | ||||
-rw-r--r-- | libpyside/signalmanager.cpp | 49 | ||||
-rw-r--r-- | tests/QtSql/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/QtSql/bug_1013.py | 30 |
5 files changed, 61 insertions, 24 deletions
diff --git a/PySide/QtSql/typesystem_sql.xml b/PySide/QtSql/typesystem_sql.xml index 2efe4290f..d6007ef21 100644 --- a/PySide/QtSql/typesystem_sql.xml +++ b/PySide/QtSql/typesystem_sql.xml @@ -81,6 +81,9 @@ <include file-name="QSqlField" location="global"/> </extra-includes> <modify-function signature="append(QSqlField)" access="non-final"/> + <inject-code position="end"> + Shiboken::TypeResolver::createReferenceTypeResolver< ::QSqlRecord >("QSqlRecord&"); + </inject-code> </value-type> <value-type name="QSqlError"> diff --git a/libpyside/dynamicqmetaobject.cpp b/libpyside/dynamicqmetaobject.cpp index 996ba3ae8..4dfd80f1c 100644 --- a/libpyside/dynamicqmetaobject.cpp +++ b/libpyside/dynamicqmetaobject.cpp @@ -456,7 +456,7 @@ void DynamicQMetaObject::DynamicQMetaObjectPrivate::writeMethodsData(const QList (*data)[index++] = m_emptyMethod; // func name (*data)[index++] = nullIndex; // arguments - (*data)[index++] = (it->type().size() > 0 ? registerString(it->type(), strings) : nullIndex); // normalized type + (*data)[index++] = !it->type().isEmpty() ? registerString(it->type(), strings) : nullIndex; // normalized type (*data)[index++] = nullIndex; // tags (*data)[index++] = flags | (it->methodType() == QMetaMethod::Signal ? MethodSignal : MethodSlot); } diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp index a95f5f130..54fce07bb 100644 --- a/libpyside/signalmanager.cpp +++ b/libpyside/signalmanager.cpp @@ -54,7 +54,7 @@ namespace { static PyObject *metaObjectAttr = 0; static int callMethod(QObject* object, int id, void** args); - static PyObject* parseArguments(QList<QByteArray> paramTypese, void** args); + static PyObject* parseArguments(const QList< QByteArray >& paramTypes, void** args); static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* args); #ifdef IS_PY3K @@ -420,27 +420,33 @@ int SignalManager::callPythonMetaMethod(const QMetaMethod& method, void** args, Q_ASSERT(pyMethod); Shiboken::GilState gil; - PyObject* pyArguments = NULL; + PyObject* pyArguments = 0; if (isShortCuit) pyArguments = reinterpret_cast<PyObject*>(args[1]); else pyArguments = parseArguments(method.parameterTypes(), args); - //keep the returnType this call be destroyed after method call - QByteArray returnType = method.typeName(); + if (pyArguments) { + Shiboken::AutoDecRef retval(PyObject_CallObject(pyMethod, pyArguments)); - Shiboken::AutoDecRef retval(PyObject_CallObject(pyMethod, pyArguments)); + if (!isShortCuit && pyArguments) + Py_DECREF(pyArguments); - if (!isShortCuit) - Py_XDECREF(pyArguments); + if (!retval.isNull() && retval != Py_None && !PyErr_Occurred()) { + const char* returnType = method.typeName(); + if (returnType && std::strcmp("", returnType)) { + Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(returnType); + if (typeResolver) + typeResolver->toCpp(retval, &args[0]); + else + PyErr_Format(PyExc_RuntimeError, "Can't fidn type resolver \"%s\" to call Python meta method.", returnType); + } + } + } - if (retval.isNull()) { + if (PyErr_Occurred()) PyErr_Print(); - } else { - if (returnType.size() > 0) - Shiboken::TypeResolver::get(returnType)->toCpp(retval, &args[0]); - } return -1; } @@ -471,9 +477,9 @@ int SignalManager::registerMetaMethodGetIndex(QObject* source, const char* signa if (!dict || !PyDict_Contains(dict, metaObjectAttr)) { dmo = new DynamicQMetaObject(pySelf->ob_type, metaObject); #ifdef IS_PY3K - PyObject *pyDmo = PyCapsule_New(dmo, 0, destroyMetaObject); + PyObject* pyDmo = PyCapsule_New(dmo, 0, destroyMetaObject); #else - PyObject *pyDmo = PyCObject_FromVoidPtr(dmo, destroyMetaObject); + PyObject* pyDmo = PyCObject_FromVoidPtr(dmo, destroyMetaObject); #endif PyObject_SetAttr(pySelf, metaObjectAttr, pyDmo); @@ -541,15 +547,12 @@ static int callMethod(QObject* object, int id, void** args) } -static PyObject* parseArguments(QList<QByteArray> paramTypes, void** args) +static PyObject* parseArguments(const QList<QByteArray>& paramTypes, void** args) { - PyObject* preparedArgs = NULL; - Py_ssize_t argsSize = paramTypes.count(); - - if (argsSize) - preparedArgs = PyTuple_New(argsSize); + int argsSize = paramTypes.count(); + PyObject* preparedArgs = PyTuple_New(argsSize); - for (int i = 0, max = paramTypes.count(); i < max; ++i) { + for (int i = 0, max = argsSize; i < max; ++i) { void* data = args[i+1]; const char* dataType = paramTypes[i].constData(); @@ -558,12 +561,12 @@ static PyObject* parseArguments(QList<QByteArray> paramTypes, void** args) PyObject* arg = tr->toPython(data); PyTuple_SET_ITEM(preparedArgs, i, arg); } else { + PyErr_Format(PyExc_TypeError, "Can't call meta function because I have no idea how to handle %s", dataType); Py_DECREF(preparedArgs); - return NULL; + return 0; } } - return preparedArgs; } diff --git a/tests/QtSql/CMakeLists.txt b/tests/QtSql/CMakeLists.txt index 25fba44a0..8db3a9813 100644 --- a/tests/QtSql/CMakeLists.txt +++ b/tests/QtSql/CMakeLists.txt @@ -1,2 +1,3 @@ +PYSIDE_TEST(bug_1013.py) PYSIDE_TEST(qsqldatabaseandqueries_test.py) PYSIDE_TEST(qvarianttype_test.py) diff --git a/tests/QtSql/bug_1013.py b/tests/QtSql/bug_1013.py new file mode 100644 index 000000000..f0cee701f --- /dev/null +++ b/tests/QtSql/bug_1013.py @@ -0,0 +1,30 @@ +from PySide.QtCore import * +from PySide.QtSql import * +import unittest + +class TestBug1013 (unittest.TestCase): + + def someSlot(self, row, record): + record.setValue(0, 2) + self._wasCalled = True + + def testIt(self): + app = QCoreApplication([]) + db = QSqlDatabase.addDatabase('QSQLITE') + db.setDatabaseName(':memory:') + db.open() + query = QSqlQuery() + query.exec_('CREATE TABLE "foo" (id INT);') + model = QSqlTableModel() + model.setTable('foo') + + self._wasCalled = False + model.primeInsert.connect(self.someSlot) + model.select() + QTimer.singleShot(0,lambda: model.insertRow(0) and app.quit()) + app.exec_() + self.assertTrue(self._wasCalled) + self.assertEqual(model.data(model.index(0, 0)), 2) + +if __name__ == "__main__": + unittest.main() |