@@ -700,7 +700,7 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, | |||||
700 | PythonQtSlotInfo* info = o->m_ml; |
|
700 | PythonQtSlotInfo* info = o->m_ml; | |
701 |
|
701 | |||
702 | while (info) { |
|
702 | while (info) { | |
703 |
results << info->fullSignature( |
|
703 | results << info->fullSignature(); | |
704 | info = info->nextInfo(); |
|
704 | info = info->nextInfo(); | |
705 | } |
|
705 | } | |
706 | } else if (object->ob_type == &PythonQtClassWrapper_Type) { |
|
706 | } else if (object->ob_type == &PythonQtClassWrapper_Type) { | |
@@ -708,7 +708,7 QStringList PythonQt::introspection(PyObject* module, const QString& objectname, | |||||
708 | PythonQtSlotInfo* info = o->classInfo()->constructors(); |
|
708 | PythonQtSlotInfo* info = o->classInfo()->constructors(); | |
709 |
|
709 | |||
710 | while (info) { |
|
710 | while (info) { | |
711 |
results << info->fullSignature( |
|
711 | results << info->fullSignature(); | |
712 | info = info->nextInfo(); |
|
712 | info = info->nextInfo(); | |
713 | } |
|
713 | } | |
714 | } else { |
|
714 | } else { |
@@ -537,7 +537,7 QString PythonQtClassInfo::help() | |||||
537 | h += "Constructors:\n"; |
|
537 | h += "Constructors:\n"; | |
538 | PythonQtSlotInfo* constr = constructors(); |
|
538 | PythonQtSlotInfo* constr = constructors(); | |
539 | while (constr) { |
|
539 | while (constr) { | |
540 |
h += constr->fullSignature( |
|
540 | h += constr->fullSignature() + "\n"; | |
541 | constr = constr->nextInfo(); |
|
541 | constr = constr->nextInfo(); | |
542 | } |
|
542 | } | |
543 | } |
|
543 | } | |
@@ -557,7 +557,7 QString PythonQtClassInfo::help() | |||||
557 | if (signa.startsWith("delete_")) continue; |
|
557 | if (signa.startsWith("delete_")) continue; | |
558 | if (signa.startsWith("static_")) continue; |
|
558 | if (signa.startsWith("static_")) continue; | |
559 | PythonQtSlotInfo slot(m, i); |
|
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 | QListIterator<PythonQtSlotInfo*> it(PythonQt::priv()->getDecoratorSlots(nameIt.next())); |
|
581 | QListIterator<PythonQtSlotInfo*> it(PythonQt::priv()->getDecoratorSlots(nameIt.next())); | |
582 | while (it.hasNext()) { |
|
582 | while (it.hasNext()) { | |
583 | PythonQtSlotInfo* slot = it.next(); |
|
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 | dict = PyDict_Copy(dict); |
|
158 | dict = PyDict_Copy(dict); | |
159 |
|
159 | |||
160 |
QStringList l = wrapper->classInfo()->memberList( |
|
160 | QStringList l = wrapper->classInfo()->memberList(false); | |
161 | foreach (QString name, l) { |
|
161 | foreach (QString name, l) { | |
162 | PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); |
|
162 | PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); | |
|
163 | if (o) { | |||
163 | PyDict_SetItemString(dict, name.toLatin1().data(), o); |
|
164 | PyDict_SetItemString(dict, name.toLatin1().data(), o); | |
164 | Py_DECREF(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 | if (wrapper->classInfo()->constructors()) { |
|
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 | return dict; |
|
180 | return dict; | |
172 | } |
|
181 | } | |
173 |
|
182 | |||
@@ -176,7 +185,8 static PyObject *PythonQtClassWrapper_getattro(PyObject *obj, PyObject *name) | |||||
176 | if (member._type == PythonQtMemberInfo::EnumValue) { |
|
185 | if (member._type == PythonQtMemberInfo::EnumValue) { | |
177 | return PyInt_FromLong(member._enumValue); |
|
186 | return PyInt_FromLong(member._enumValue); | |
178 | } else |
|
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 | return PythonQtSlotFunction_New(member._slot, obj, NULL); |
|
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 | PyObject* dict = PyDict_New(); |
|
252 | PyObject* dict = PyDict_New(); | |
253 | foreach (QString name, l) { |
|
253 | foreach (QString name, l) { | |
254 | PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); |
|
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 | Py_DECREF(o); |
|
256 | Py_DECREF(o); | |
257 | } |
|
257 | } | |
258 | // Note: we do not put children into the dict, is would look confusing?! |
|
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 | QString result = _meta.typeName(); |
|
234 | QString result = _meta.typeName(); | |
234 | QByteArray sig = slotName(); |
|
235 | QByteArray sig = slotName(); | |
235 | QList<QByteArray> names = _meta.parameterNames(); |
|
236 | QList<QByteArray> names = _meta.parameterNames(); |
@@ -156,7 +156,7 public: | |||||
156 | QObject* decorator() { return _decorator; } |
|
156 | QObject* decorator() { return _decorator; } | |
157 |
|
157 | |||
158 | //! get the full signature including return type |
|
158 | //! get the full signature including return type | |
159 |
QString fullSignature( |
|
159 | QString fullSignature(); | |
160 |
|
160 | |||
161 | //! get the short slot name |
|
161 | //! get the short slot name | |
162 | QByteArray slotName(); |
|
162 | QByteArray slotName(); |
@@ -148,7 +148,7 bool PythonQtCallSlot(QObject* objectToCall, PyObject* args, bool strict, Python | |||||
148 | } |
|
148 | } | |
149 | } |
|
149 | } | |
150 | } else { |
|
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 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
152 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); | |
153 | result = NULL; |
|
153 | result = NULL; | |
154 | } |
|
154 | } | |
@@ -177,11 +177,41 PyObject *PythonQtSlotFunction_Call(PyObject *func, PyObject *args, PyObject *kw | |||||
177 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self; |
|
177 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self; | |
178 | return PythonQtSlotFunction_CallImpl(self->_obj, info, args, kw, self->_wrappedPtr); |
|
178 | return PythonQtSlotFunction_CallImpl(self->_obj, info, args, kw, self->_wrappedPtr); | |
179 | } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) { |
|
179 | } else if (f->m_self->ob_type == &PythonQtClassWrapper_Type) { | |
|
180 | if (info->isClassDecorator()) { | |||
180 | return PythonQtSlotFunction_CallImpl(NULL, info, args, kw); |
|
181 | return PythonQtSlotFunction_CallImpl(NULL, info, args, kw); | |
181 | } else { |
|
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()); | |||
182 | return NULL; |
|
209 | return NULL; | |
183 | } |
|
210 | } | |
184 | } |
|
211 | } | |
|
212 | } | |||
|
213 | return NULL; | |||
|
214 | } | |||
185 |
|
215 | |||
186 | PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer) |
|
216 | PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* info, PyObject *args, PyObject * /*kw*/, void* firstArg, void** directReturnValuePointer) | |
187 | { |
|
217 | { | |
@@ -196,7 +226,6 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||||
196 | if (directReturnValuePointer) { |
|
226 | if (directReturnValuePointer) { | |
197 | *directReturnValuePointer = NULL; |
|
227 | *directReturnValuePointer = NULL; | |
198 | } |
|
228 | } | |
199 |
|
||||
200 | if (info->nextInfo()) { |
|
229 | if (info->nextInfo()) { | |
201 | // overloaded slot call, try on all slots with strict conversion first |
|
230 | // overloaded slot call, try on all slots with strict conversion first | |
202 | bool strict = true; |
|
231 | bool strict = true; | |
@@ -221,8 +250,7 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||||
221 | QString e = QString("Could not find matching overload for given arguments:\n" + PythonQtConv::PyObjGetString(args) + "\n The following slots are available:\n"); |
|
250 | QString e = QString("Could not find matching overload for given arguments:\n" + PythonQtConv::PyObjGetString(args) + "\n The following slots are available:\n"); | |
222 | PythonQtSlotInfo* i = info; |
|
251 | PythonQtSlotInfo* i = info; | |
223 | while (i) { |
|
252 | while (i) { | |
224 | bool skipFirst = i->isInstanceDecorator(); |
|
253 | e += QString(i->fullSignature()) + "\n"; | |
225 | e += QString(i->fullSignature(skipFirst)) + "\n"; |
|
|||
226 | i = i->nextInfo(); |
|
254 | i = i->nextInfo(); | |
227 | } |
|
255 | } | |
228 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
256 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); | |
@@ -234,11 +262,11 PyObject *PythonQtSlotFunction_CallImpl(QObject* objectToCall, PythonQtSlotInfo* | |||||
234 | PyErr_Clear(); |
|
262 | PyErr_Clear(); | |
235 | ok = PythonQtCallSlot(objectToCall, args, false, info, firstArg, &r, directReturnValuePointer); |
|
263 | ok = PythonQtCallSlot(objectToCall, args, false, info, firstArg, &r, directReturnValuePointer); | |
236 | if (!ok && !PyErr_Occurred()) { |
|
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 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
266 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); | |
239 | } |
|
267 | } | |
240 | } else { |
|
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 | PyErr_SetString(PyExc_ValueError, e.toLatin1().data()); |
|
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 | static PyObject * |
|
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>", |
|
399 | if (PyObject_TypeCheck(f->m_self, &PythonQtInstanceWrapper_Type)) { | |
372 | m->m_ml->metaMethod()->signature(), |
|
400 | PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) f->m_self; | |
373 | m->m_self->ob_type->tp_name, |
|
401 | return PyString_FromFormat("<qt slot %s of %s instance at %p>", | |
374 | m->m_self); |
|
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 | static int |
|
413 | static int |
General Comments 0
You need to be logged in to leave comments.
Login now