@@ -700,7 +700,7 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, | |||
|
700 | 700 | PythonQtSlotInfo* info = o->m_ml; |
|
701 | 701 | |
|
702 | 702 | while (info) { |
|
703 |
results << info->fullSignature( |
|
|
703 | results << info->fullSignature(); | |
|
704 | 704 | info = info->nextInfo(); |
|
705 | 705 | } |
|
706 | 706 | } else if (object->ob_type == &PythonQtClassWrapper_Type) { |
@@ -708,7 +708,7 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, | |||
|
708 | 708 | PythonQtSlotInfo* info = o->classInfo()->constructors(); |
|
709 | 709 | |
|
710 | 710 | while (info) { |
|
711 |
results << info->fullSignature( |
|
|
711 | results << info->fullSignature(); | |
|
712 | 712 | info = info->nextInfo(); |
|
713 | 713 | } |
|
714 | 714 | } else { |
@@ -537,7 +537,7 QString PythonQtClassInfo::help() | |||
|
537 | 537 | h += "Constructors:\n"; |
|
538 | 538 | PythonQtSlotInfo* constr = constructors(); |
|
539 | 539 | while (constr) { |
|
540 |
h += constr->fullSignature( |
|
|
540 | h += constr->fullSignature() + "\n"; | |
|
541 | 541 | constr = constr->nextInfo(); |
|
542 | 542 | } |
|
543 | 543 | } |
@@ -557,7 +557,7 QString PythonQtClassInfo::help() | |||
|
557 | 557 | if (signa.startsWith("delete_")) continue; |
|
558 | 558 | if (signa.startsWith("static_")) continue; |
|
559 | 559 | PythonQtSlotInfo slot(m, i); |
|
560 |
h += slot.fullSignature( |
|
|
560 | h += slot.fullSignature()+ "\n"; | |
|
561 | 561 | } |
|
562 | 562 | } |
|
563 | 563 | } |
@@ -581,7 +581,7 QString PythonQtClassInfo::help() | |||
|
581 | 581 | QListIterator<PythonQtSlotInfo*> it(PythonQt::priv()->getDecoratorSlots(nameIt.next())); |
|
582 | 582 | while (it.hasNext()) { |
|
583 | 583 | PythonQtSlotInfo* slot = it.next(); |
|
584 |
h += slot->fullSignature( |
|
|
584 | h += slot->fullSignature() + "\n"; | |
|
585 | 585 | } |
|
586 | 586 | } |
|
587 | 587 |
@@ -157,17 +157,26 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) | |||
|
157 | 157 | } |
|
158 | 158 | dict = PyDict_Copy(dict); |
|
159 | 159 | |
|
160 |
QStringList l = wrapper->classInfo()->memberList( |
|
|
160 | QStringList l = wrapper->classInfo()->memberList(false); | |
|
161 | 161 | foreach (QString name, l) { |
|
162 | 162 | PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); |
|
163 | PyDict_SetItemString(dict, name.toLatin1().data(), o); | |
|
164 | Py_DECREF(o); | |
|
163 | if (o) { | |
|
164 | PyDict_SetItemString(dict, name.toLatin1().data(), o); | |
|
165 | Py_DECREF(o); | |
|
166 | } else { | |
|
167 | // it must have been a property or child, which we do not know as a class object... | |
|
168 | } | |
|
165 | 169 | } |
|
166 | 170 | if (wrapper->classInfo()->constructors()) { |
|
167 |
Py |
|
|
171 | PyObject* func = PyCFunction_New(&PythonQtClassWrapper_methods[0], obj); | |
|
172 | PyDict_SetItemString(dict, "__init__", func); | |
|
173 | Py_DECREF(func); | |
|
174 | } | |
|
175 | for (int i = 1;i<3;i++) { | |
|
176 | PyObject* func = PyCFunction_New(&PythonQtClassWrapper_methods[i], obj); | |
|
177 | PyDict_SetItemString(dict, PythonQtClassWrapper_methods[i].ml_name, func); | |
|
178 | Py_DECREF(func); | |
|
168 | 179 | } |
|
169 | PyDict_SetItemString(dict, PythonQtClassWrapper_methods[1].ml_name, PyCFunction_New(&PythonQtClassWrapper_methods[1], obj)); | |
|
170 | PyDict_SetItemString(dict, PythonQtClassWrapper_methods[2].ml_name, PyCFunction_New(&PythonQtClassWrapper_methods[2], obj)); | |
|
171 | 180 | return dict; |
|
172 | 181 | } |
|
173 | 182 | |
@@ -176,7 +185,8 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) | |||
|
176 | 185 | if (member._type == PythonQtMemberInfo::EnumValue) { |
|
177 | 186 | return PyInt_FromLong(member._enumValue); |
|
178 | 187 | } else |
|
179 |
if (member._type == PythonQtMemberInfo::Slot |
|
|
188 | if (member._type == PythonQtMemberInfo::Slot) { | |
|
189 | // we return all slots, even the instance slots, since they are callable as unbound slots with self argument | |
|
180 | 190 | return PythonQtSlotFunction_New(member._slot, obj, NULL); |
|
181 | 191 | } |
|
182 | 192 | } |
@@ -252,7 +252,7 static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) | |||
|
252 | 252 | PyObject* dict = PyDict_New(); |
|
253 | 253 | foreach (QString name, l) { |
|
254 | 254 | PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); |
|
255 |
PyDict_SetItemString(dict, name.toLatin1().data(), |
|
|
255 | PyDict_SetItemString(dict, name.toLatin1().data(), o); | |
|
256 | 256 | Py_DECREF(o); |
|
257 | 257 | } |
|
258 | 258 | // Note: we do not put children into the dict, is would look confusing?! |
@@ -228,8 +228,9 void PythonQtMethodInfo::addParameterTypeAlias(const QByteArray& alias, const QB | |||
|
228 | 228 | |
|
229 | 229 | //------------------------------------------------------------------------------------------------- |
|
230 | 230 | |
|
231 |
QString PythonQtSlotInfo::fullSignature( |
|
|
231 | QString PythonQtSlotInfo::fullSignature() | |
|
232 | 232 | { |
|
233 | bool skipFirstArg = isInstanceDecorator(); | |
|
233 | 234 | QString result = _meta.typeName(); |
|
234 | 235 | QByteArray sig = slotName(); |
|
235 | 236 | QList<QByteArray> names = _meta.parameterNames(); |
@@ -156,7 +156,7 public: | |||
|
156 | 156 | QObject* decorator() { return _decorator; } |
|
157 | 157 | |
|
158 | 158 | //! get the full signature including return type |
|
159 |
QString fullSignature( |
|
|
159 | QString fullSignature(); | |
|
160 | 160 | |
|
161 | 161 | //! get the short slot name |
|
162 | 162 | QByteArray slotName(); |
@@ -148,7 +148,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||
|
148 | 148 | } |
|
149 | 149 | } |
|
150 | 150 | } else { |
|
151 |
QString e = QString("Called ") + info->fullSignature( |
|
|
151 | QString e = QString("Called ") + info->fullSignature() + ", return type is ignored because it is unknown to PythonQt."; | |
|
152 | 152 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
153 | 153 | result = NULL; |
|
154 | 154 | } |
@@ -177,10 +177,40 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||
|
177 | 177 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self; |
|
178 | 178 | return PythonQtSlotFunction_CallImpl(self->_obj, info, args, kw, self->_wrappedPtr); |
|
179 | 179 | } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) { |
|
180 | return PythonQtSlotFunction_CallImpl(NULL, info, args, kw); | |
|
181 | } else { | |
|
182 | return NULL; | |
|
180 | if (info->isClassDecorator()) { | |
|
181 | return PythonQtSlotFunction_CallImpl(NULL, info, args, kw); | |
|
182 | } else { | |
|
183 | // otherwise, it is an unbound call and we have an instanceDecorator or normal slot... | |
|
184 | PythonQtClassWrapper* type = (PythonQtClassWrapper*) f->m_self; | |
|
185 | Py_ssize_t argc = PyTuple_Size(args); | |
|
186 | if (argc>0) { | |
|
187 | PyObject* firstArg = PyTuple_GET_ITEM(args, 0); | |
|
188 | if (PyObject_TypeCheck(firstArg, (PyTypeObject*)&PythonQtInstanceWrapper_Type) | |
|
189 | && ((PythonQtInstanceWrapper*)firstArg)->classInfo()->inherits(type->classInfo()->className())) { | |
|
190 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*)firstArg; | |
|
191 | // strip the first argument... | |
|
192 | PyObject* newargs = PyTuple_New(argc-1); | |
|
193 | for (int i = 0;i<argc-1; i++) { | |
|
194 | PyTuple_SET_ITEM(newargs, i,PyTuple_GET_ITEM(args, i+1)); | |
|
195 | } | |
|
196 | PyObject* result = PythonQtSlotFunction_CallImpl(self->_obj, info, newargs, kw, self->_wrappedPtr); | |
|
197 | Py_DECREF(newargs); | |
|
198 | return result; | |
|
199 | } else { | |
|
200 | // first arg is not of correct type! | |
|
201 | QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument, got " + firstArg->ob_type->tp_name; | |
|
202 | PyErr_SetString(PyExc_ValueError, error.toLatin1().data()); | |
|
203 | return NULL; | |
|
204 | } | |
|
205 | } else { | |
|
206 | // wrong number of args | |
|
207 | QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument."; | |
|
208 | PyErr_SetString(PyExc_ValueError, error.toLatin1().data()); | |
|
209 | return NULL; | |
|
210 | } | |
|
211 | } | |
|
183 | 212 | } |
|
213 | return NULL; | |
|
184 | 214 | } |
|
185 | 215 | |
|
186 | 216 | PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer) |
@@ -196,7 +226,6 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||
|
196 | 226 | if (directReturnValuePointer) { |
|
197 | 227 | *directReturnValuePointer = NULL; |
|
198 | 228 | } |
|
199 | ||
|
200 | 229 | if (info->nextInfo()) { |
|
201 | 230 | // overloaded slot call, try on all slots with strict conversion first |
|
202 | 231 | bool strict = true; |
@@ -221,8 +250,7 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||
|
221 | 250 | QString e = QString("Could not find matching overload for given arguments:\n" + PythonQtConv::PyObjGetString(args) + "\n The following slots are available:\n"); |
|
222 | 251 | PythonQtSlotInfo* i = info; |
|
223 | 252 | while (i) { |
|
224 | bool skipFirst = i->isInstanceDecorator(); | |
|
225 | e += QString(i->fullSignature(skipFirst)) + "\n"; | |
|
253 | e += QString(i->fullSignature()) + "\n"; | |
|
226 | 254 | i = i->nextInfo(); |
|
227 | 255 | } |
|
228 | 256 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
@@ -234,11 +262,11 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||
|
234 | 262 | PyErr_Clear(); |
|
235 | 263 | ok = PythonQtCallSlot(objectToCall, args, false, info, firstArg, &r, directReturnValuePointer); |
|
236 | 264 | if (!ok && !PyErr_Occurred()) { |
|
237 |
QString e = QString("Called ") + info->fullSignature( |
|
|
265 | QString e = QString("Called ") + info->fullSignature() + " with wrong arguments: " + PythonQtConv::PyObjGetString(args); | |
|
238 | 266 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
239 | 267 | } |
|
240 | 268 | } else { |
|
241 |
QString e = QString("Called ") + info->fullSignature( |
|
|
269 | QString e = QString("Called ") + info->fullSignature() + " with wrong number of arguments: " + PythonQtConv::PyObjGetString(args); | |
|
242 | 270 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
243 | 271 | } |
|
244 | 272 | } |
@@ -366,12 +394,20 static PyMemberDef meth_members[] = { | |||
|
366 | 394 | }; |
|
367 | 395 | |
|
368 | 396 | static PyObject * |
|
369 |
meth_repr(PythonQtSlotFunctionObject * |
|
|
397 | meth_repr(PythonQtSlotFunctionObject *f) | |
|
370 | 398 | { |
|
371 | return PyString_FromFormat("<built-in qt slot %s of %s object at %p>", | |
|
372 | m->m_ml->metaMethod()->signature(), | |
|
373 | m->m_self->ob_type->tp_name, | |
|
374 | m->m_self); | |
|
399 | if (PyObject_TypeCheck(f->m_self, &PythonQtInstanceWrapper_Type)) { | |
|
400 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self; | |
|
401 | return PyString_FromFormat("<qt slot %s of %s instance at %p>", | |
|
402 | f->m_ml->metaMethod()->signature(), | |
|
403 | f->m_self->ob_type->tp_name, | |
|
404 | f->m_self); | |
|
405 | } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) { | |
|
406 | PythonQtClassWrapper* self = (PythonQtClassWrapper*) f->m_self; | |
|
407 | return PyString_FromFormat("<unbound qt slot %s of %s type>", | |
|
408 | f->m_ml->metaMethod()->signature(), | |
|
409 | self->classInfo()->className()); | |
|
410 | } | |
|
375 | 411 | } |
|
376 | 412 | |
|
377 | 413 | static int |
General Comments 0
You need to be logged in to leave comments.
Login now