static PyObject* PythonQtInstanceWrapper_binaryfunc(PyObject* self, PyObject* other, const QByteArray& opName, const QByteArray& fallbackOpName = QByteArray()) { // since we disabled type checking, we can receive any object as self, but we currently only support // different objects on the right. Otherwise we would need to generate __radd__ etc. methods. if (!PyObject_TypeCheck(self, &PythonQtInstanceWrapper_Type)) { QString error = "Unsupported operation " + opName + "(" + self->ob_type->tp_name + ", " + other->ob_type->tp_name + ")"; PyErr_SetString(PyExc_ArithmeticError, error.toLatin1().data()); return NULL; } PythonQtInstanceWrapper* wrapper = (PythonQtInstanceWrapper*)self; PyObject* result = NULL; PythonQtMemberInfo opSlot = wrapper->classInfo()->member(opName); if (opSlot._type == PythonQtMemberInfo::Slot) { // TODO get rid of tuple PyObject* args = PyTuple_New(1); Py_INCREF(other); PyTuple_SET_ITEM(args, 0, other); result = PythonQtSlotFunction_CallImpl(wrapper->classInfo(), wrapper->_obj, opSlot._slot, args, NULL, wrapper->_wrappedPtr); Py_DECREF(args); if (!result && !fallbackOpName.isEmpty()) { // try fallback if we did not get a result result = PythonQtInstanceWrapper_binaryfunc(self, other, fallbackOpName); } } return result; }
PyObject *PythonQtMemberFunction_Call(PythonQtSlotInfo* info, PyObject* m_self, PyObject *args, PyObject *kw) { if (PyObject_TypeCheck(m_self, &PythonQtInstanceWrapper_Type)) { PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*) m_self; if (!info->isClassDecorator() && (self->_obj==NULL && self->_wrappedPtr==NULL)) { QString error = QString("Trying to call '") + info->slotName() + "' on a destroyed " + self->classInfo()->className() + " object"; PyErr_SetString(PyExc_ValueError, error.toLatin1().data()); return NULL; } else { return PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, args, kw, self->_wrappedPtr); } } else if (m_self->ob_type == &PythonQtClassWrapper_Type) { PythonQtClassWrapper* type = (PythonQtClassWrapper*) m_self; if (info->isClassDecorator()) { return PythonQtSlotFunction_CallImpl(type->classInfo(), NULL, info, args, kw); } else { // otherwise, it is an unbound call and we have an instanceDecorator or normal slot... Py_ssize_t argc = PyTuple_Size(args); if (argc>0) { PyObject* firstArg = PyTuple_GET_ITEM(args, 0); if (PyObject_TypeCheck(firstArg, (PyTypeObject*)&PythonQtInstanceWrapper_Type) && ((PythonQtInstanceWrapper*)firstArg)->classInfo()->inherits(type->classInfo())) { PythonQtInstanceWrapper* self = (PythonQtInstanceWrapper*)firstArg; if (!info->isClassDecorator() && (self->_obj==NULL && self->_wrappedPtr==NULL)) { QString error = QString("Trying to call '") + info->slotName() + "' on a destroyed " + self->classInfo()->className() + " object"; PyErr_SetString(PyExc_ValueError, error.toLatin1().data()); return NULL; } // strip the first argument... PyObject* newargs = PyTuple_GetSlice(args, 1, argc); PyObject* result = PythonQtSlotFunction_CallImpl(self->classInfo(), self->_obj, info, newargs, kw, self->_wrappedPtr); Py_DECREF(newargs); return result; } else { // first arg is not of correct type! QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument, got " + firstArg->ob_type->tp_name; PyErr_SetString(PyExc_ValueError, error.toLatin1().data()); return NULL; } } else { // wrong number of args QString error = "slot " + info->fullSignature() + " requires " + type->classInfo()->className() + " instance as first argument."; PyErr_SetString(PyExc_ValueError, error.toLatin1().data()); return NULL; } } } return NULL; }
static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) { const char *attributeName; PythonQtInstanceWrapper *wrapper = (PythonQtInstanceWrapper *)obj; if ((attributeName = PyString_AsString(name)) == NULL) { return NULL; } if (qstrcmp(attributeName, "__dict__")==0) { PyObject* dict = PyBaseObject_Type.tp_getattro(obj, name); dict = PyDict_Copy(dict); if (wrapper->_obj) { // we need to replace the properties with their real values... QStringList l = wrapper->classInfo()->propertyList(); Q_FOREACH (QString name, l) { PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); if (o) { PyDict_SetItemString(dict, name.toLatin1().data(), o); Py_DECREF(o); } else { std::cerr << "PythonQtInstanceWrapper: something is wrong, could not get attribute " << name.toLatin1().data(); } }
static PyObject *PythonQtInstanceWrapper_getattro(PyObject *obj,PyObject *name) { const char *attributeName; PythonQtInstanceWrapper *wrapper = (PythonQtInstanceWrapper *)obj; if ((attributeName = PyString_AsString(name)) == NULL) { return NULL; } if (qstrcmp(attributeName, "__dict__")==0) { PyObject* dict = PyBaseObject_Type.tp_getattro(obj, name); dict = PyDict_Copy(dict); if (wrapper->_obj) { // only the properties are missing, the rest is already available from // PythonQtClassWrapper... QStringList l = wrapper->classInfo()->propertyList(); foreach (QString name, l) { PyObject* o = PyObject_GetAttrString(obj, name.toLatin1().data()); if (o) { PyDict_SetItemString(dict, name.toLatin1().data(), o); Py_DECREF(o); } else { std::cerr << "PythonQtInstanceWrapper: something is wrong, could not get attribute " << name.toLatin1().data(); } }
PyObject *PythonQtClassWrapper_inherits(PythonQtClassWrapper *type, PyObject *args) { Q_UNUSED(type); PythonQtInstanceWrapper* wrapper = NULL; char *name = NULL; if (!PyArg_ParseTuple(args, "O!s:PythonQtClassWrapper.inherits",&PythonQtInstanceWrapper_Type, &wrapper, &name)) { return NULL; } return PythonQtConv::GetPyBool(wrapper->classInfo()->inherits(name)); }