aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libpyside/signalmanager.cpp28
-rw-r--r--tests/signals/signal_emission_test.py7
2 files changed, 25 insertions, 10 deletions
diff --git a/libpyside/signalmanager.cpp b/libpyside/signalmanager.cpp
index 7d10f77f4..3e5e3c07c 100644
--- a/libpyside/signalmanager.cpp
+++ b/libpyside/signalmanager.cpp
@@ -260,28 +260,38 @@ static bool emitShortCircuitSignal(QObject* source, int signalIndex, PyObject* a
static bool emitNormalSignal(QObject* source, int signalIndex, const char* signal, PyObject* args, const QStringList& argTypes)
{
- int argsGiven = PySequence_Size(args);
+ Shiboken::AutoDecRef sequence(PySequence_Fast(args, 0));
+ int argsGiven = PySequence_Fast_GET_SIZE(sequence.object());
if (argsGiven > argTypes.count()) {
- QString msg = QString("%1 only accepts %2 arguments, %3 given!").arg(signal).arg(argTypes.count()).arg(argsGiven);
- PyErr_SetString(PyExc_TypeError, msg.toLocal8Bit().constData());
+ PyErr_Format(PyExc_TypeError, "%s only accepts %d arguments, %d given!", signal, argTypes.count(), argsGiven);
return false;
}
void** signalArgs = new void*[argsGiven+1];
signalArgs[0] = 0;
- for (int i = 0; i < argsGiven; ++i)
- signalArgs[i+1] = Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->toCpp(PySequence_GetItem(args, i));
+ int i;
+ for (i = 0; i < argsGiven; ++i) {
+ Shiboken::TypeResolver* typeResolver = Shiboken::TypeResolver::get(qPrintable(argTypes[i]));
+ if (typeResolver) {
+ signalArgs[i+1] = typeResolver->toCpp(PySequence_Fast_GET_ITEM(sequence.object(), i));
+ } else {
+ PyErr_Format(PyExc_TypeError, "Unknown type used to emit a signal: %s", qPrintable(argTypes[i]));
+ break;
+ }
+ }
- QMetaObject::activate(source, signalIndex, signalArgs);
+ bool ok = i == argsGiven;
+ if (ok)
+ QMetaObject::activate(source, signalIndex, signalArgs);
// FIXME: This will cause troubles with non-direct connections.
- for (int i = 0; i < argsGiven; ++i)
- Shiboken::TypeResolver::get(qPrintable(argTypes[i]))->deleteObject(signalArgs[i+1]);
+ for (int j = 0; j < i; ++j)
+ Shiboken::TypeResolver::get(qPrintable(argTypes[j]))->deleteObject(signalArgs[j+1]);
delete[] signalArgs;
- return true;
+ return ok;
}
bool SignalManager::emitSignal(QObject* source, const char* signal, PyObject* args)
diff --git a/tests/signals/signal_emission_test.py b/tests/signals/signal_emission_test.py
index 5692b073c..a8dd4fdc0 100644
--- a/tests/signals/signal_emission_test.py
+++ b/tests/signals/signal_emission_test.py
@@ -32,7 +32,6 @@ class Dummy(QObject):
'''Dummy class'''
pass
-
class PythonSignalToCppSlots(UsesQCoreApplication):
'''Connect python signals to C++ slots'''
@@ -102,5 +101,11 @@ class DynamicSignalsToFuncPartial(UsesQCoreApplication):
o.emit(SIGNAL("ASignal"))
self.assertTrue(called)
+class EmitUnknownType(UsesQCoreApplication):
+ def testIt(self):
+ a = QObject()
+ a.connect(SIGNAL('foobar(Dummy)'), lambda x: 42) # Just connect with an unknown type
+ self.assertRaises(TypeError, a.emit, SIGNAL('foobar(Dummy)'), 22)
+
if __name__ == '__main__':
unittest.main()