SlotConnectorBase::SlotConnectorBase(PyObject* slot, int n_sig_args) { function = 0; klass = 0; PyObject* instance = 0; cfunction = 0; if (PyMethod_Check(slot)) { instance = PyMethod_GET_SELF(slot); klass = PyMethod_GET_CLASS(slot); function = PyMethod_GET_FUNCTION(slot); Py_INCREF(klass); Py_INCREF(function); PyObject* func_code = PyObject_GetAttrString(function, "func_code"); PyObject* co_argcount = PyObject_GetAttrString(func_code, "co_argcount"); n_slot_args = PyInt_AsLong(co_argcount)-1; if (n_slot_args == -1) { PyErr_SetString(PyExc_TypeError, "Slot method should at least have a 'self' argument"); return; } core = ((Wt::WObject*)(((PyCPPClassInstance*)instance)->proxy->getCoreAsVoid())); Py_DECREF(func_code); Py_DECREF(co_argcount); } else if PyCFunction_Check(slot) { instance = PyCFunction_GET_SELF(slot); cfunction = PyCFunction_GET_FUNCTION(slot); flags = PyCFunction_GET_FLAGS(slot); n_slot_args = PyCFunction_GET_NARGS(slot); core = ((Wt::WObject*)(((PyCPPClassInstance*)instance)->proxy->getCoreAsVoid())); } else {
static PyObject * method_call(PyObject *func, PyObject *arg, PyObject *kw) { PyObject *self = PyMethod_GET_SELF(func); PyObject *result; func = PyMethod_GET_FUNCTION(func); if (self == NULL) { PyErr_BadInternalCall(); return NULL; } else { Py_ssize_t argcount = PyTuple_Size(arg); PyObject *newarg = PyTuple_New(argcount + 1); int i; if (newarg == NULL) return NULL; Py_INCREF(self); PyTuple_SET_ITEM(newarg, 0, self); for (i = 0; i < argcount; i++) { PyObject *v = PyTuple_GET_ITEM(arg, i); Py_XINCREF(v); PyTuple_SET_ITEM(newarg, i+1, v); } arg = newarg; } result = PyObject_Call((PyObject *)func, arg, kw); Py_DECREF(arg); return result; }
static int EC_init(PyTypeObject *self, PyObject *args, PyObject *kw) { PyObject *__class_init__, *r; if (PyType_Type.tp_init(OBJECT(self), args, kw) < 0) return -1; if (self->tp_dict != NULL) { r = PyDict_GetItemString(self->tp_dict, "__doc__"); if ((r == Py_None) && (PyDict_DelItemString(self->tp_dict, "__doc__") < 0) ) return -1; } if (EC_init_of(self) < 0) return -1; /* Call __class_init__ */ __class_init__ = PyObject_GetAttr(OBJECT(self), str__class_init__); if (__class_init__ == NULL) { PyErr_Clear(); return 0; } if (! (PyMethod_Check(__class_init__) && PyMethod_GET_FUNCTION(__class_init__) ) ) { Py_DECREF(__class_init__); PyErr_SetString(PyExc_TypeError, "Invalid type for __class_init__"); return -1; } r = PyObject_CallFunctionObjArgs(PyMethod_GET_FUNCTION(__class_init__), OBJECT(self), NULL); Py_DECREF(__class_init__); if (! r) return -1; Py_DECREF(r); return 0; }
PyObject * as_function(PyObject *o) { if (PyMethod_Check(o)) { return PyMethod_GET_FUNCTION(o); } else { return o; } }
PyObject* PyObject_CallAsPyString(PyObject* object) { PyObject *result, *module, *module_tmp, *self; PyObject *function, *function_tmp, *class; if (PyFunction_Check(object)) { module = ModuleAsPyString(((PyFunctionObject*)object)->func_module); function = ((PyFunctionObject*)object)->func_name; result = PyString_JoinWithDots(module, function); //Py_XDECREF(module); return result; } else if (PyCFunction_Check(object)) { module = ModuleAsPyString(((PyCFunctionObject*)object)->m_module); self = PyObject_AsPyString(((PyCFunctionObject*)object)->m_self); function = PyString_FromString(((PyCFunctionObject*)object)->m_ml->ml_name); result = PyString_JoinWithDots(module, self, function); //Py_XDECREF(module); Py_XDECREF(self); Py_DECREF(function); return result; } else if (PyMethod_Check(object)) { // See the implementation of instancemethod_repr class = NULL; if (PyMethod_GET_CLASS(object) != NULL) { class = PyObject_CallAsPyString(PyMethod_GET_CLASS(object)); } if (PyFunction_Check(PyMethod_GET_FUNCTION(object))) { function = ((PyFunctionObject*)PyMethod_GET_FUNCTION(object))->func_name; Py_XINCREF(function); } else { function = PyString_InternFromString("???"); } if (PyMethod_GET_SELF(object) == NULL) { // Unbounded method function_tmp = function; function = PyString_FromFormat("%s<U>", PyString_AsString(function_tmp)); Py_DECREF(function_tmp); } result = PyString_JoinWithDots(class, function); Py_XDECREF(class); Py_XDECREF(function); return result; } else if (PyType_Check(object)) {
static PyObject * method_descr_get(PyObject *meth, PyObject *obj, PyObject *cls) { /* Don't rebind an already bound method of a class that's not a base class of cls. */ if (PyMethod_GET_SELF(meth) != NULL) { /* Already bound */ Py_INCREF(meth); return meth; } /* Bind it to obj */ return PyMethod_New(PyMethod_GET_FUNCTION(meth), obj); }
static PyObject * method_reduce(PyMethodObject *im) { PyObject *self = PyMethod_GET_SELF(im); PyObject *func = PyMethod_GET_FUNCTION(im); PyObject *funcname; _Py_IDENTIFIER(getattr); funcname = _PyObject_GetAttrId(func, &PyId___name__); if (funcname == NULL) { return NULL; } return Py_BuildValue("N(ON)", _PyEval_GetBuiltinId(&PyId_getattr), self, funcname); }
static PyObject * method_call(PyObject *method, PyObject *args, PyObject *kwargs) { PyObject *self, *func; self = PyMethod_GET_SELF(method); if (self == NULL) { PyErr_BadInternalCall(); return NULL; } func = PyMethod_GET_FUNCTION(method); return _PyObject_Call_Prepend(func, self, args, kwargs); }
static PyObject * method_reduce(PyMethodObject *im) { PyObject *self = PyMethod_GET_SELF(im); PyObject *func = PyMethod_GET_FUNCTION(im); PyObject *builtins; PyObject *getattr; PyObject *funcname; _Py_IDENTIFIER(getattr); funcname = _PyObject_GetAttrId(func, &PyId___name__); if (funcname == NULL) { return NULL; } builtins = PyEval_GetBuiltins(); getattr = _PyDict_GetItemId(builtins, &PyId_getattr); return Py_BuildValue("O(ON)", getattr, self, funcname); }
/* * Compare two slots to see if they are the same. */ int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot) { assert(sipQtSupport); assert(sipQtSupport->qt_same_name); /* See if they are signals or Qt slots, ie. they have a name. */ if (slot != NULL) { if (sp->name == NULL || sp->name[0] == '\0') return 0; return (sipQtSupport->qt_same_name(sp->name, slot) && sp->pyobj == rxObj); } /* See if they are pure Python methods. */ if (PyMethod_Check(rxObj)) { if (sp->pyobj != NULL) return 0; return (sp->meth.mfunc == PyMethod_GET_FUNCTION(rxObj) && sp->meth.mself == PyMethod_GET_SELF(rxObj) #if PY_MAJOR_VERSION < 3 && sp->meth.mclass == PyMethod_GET_CLASS(rxObj) #endif ); } /* See if they are wrapped C++ methods. */ if (PyCFunction_Check(rxObj)) { if (sp->name == NULL || sp->name[0] != '\0') return 0; return (sp->pyobj == PyCFunction_GET_SELF(rxObj) && strcmp(&sp->name[1], ((PyCFunctionObject *)rxObj)->m_ml->ml_name) == 0); } /* The objects must be the same. */ return (sp->pyobj == rxObj); }
static char const *GET_CALLABLE_NAME( PyObject *object ) { if ( Nuitka_Function_Check( object ) ) { return Nuitka_String_AsString( Nuitka_Function_GetName( object ) ); } else if ( Nuitka_Generator_Check( object ) ) { return Nuitka_String_AsString( Nuitka_Generator_GetName( object ) ); } else if ( PyMethod_Check( object ) ) { return PyEval_GetFuncName( PyMethod_GET_FUNCTION( object ) ); } else if ( PyFunction_Check( object ) ) { return Nuitka_String_AsString( ((PyFunctionObject*)object)->func_name ); } #if PYTHON_VERSION < 300 else if ( PyInstance_Check( object ) ) { return Nuitka_String_AsString( ((PyInstanceObject*)object)->in_class->cl_name ); } else if ( PyClass_Check( object ) ) { return Nuitka_String_AsString( ((PyClassObject*)object)->cl_name ); } #endif else if ( PyCFunction_Check( object ) ) { return ((PyCFunctionObject*)object)->m_ml->ml_name; } else { return Py_TYPE( object )->tp_name; } }
static PyObject * instancemethod_call(PyObject *self, PyObject *arg, PyObject *kw) { return PyObject_Call(PyMethod_GET_FUNCTION(self), arg, kw); }
static PyObject* copyrec(PyObject* o) { PyTypeObject* t; PyObject* n; PyObject* key; KeyObject* fkey; if (o == Py_None || o->ob_type == &PyInt_Type || o->ob_type == &PyString_Type) { Py_INCREF(o); return o; } if (ss_next_in_block < 0) { struct key_block* b = (struct key_block*) malloc(sizeof(struct key_block)); if (!b) { PyErr_NoMemory(); goto fail1; } b->next = ss_block; ss_block = b; ss_next_in_block = KEYS_BY_BLOCK - 1; } fkey = ss_block->keys + ss_next_in_block; fkey->ob_refcnt = 1; fkey->ob_type = &keytype; fkey->o = o; key = (PyObject*) fkey; n = PyDict_GetItem(ss_memo, key); if (n) { Py_INCREF(n); return n; } ss_next_in_block--; Py_INCREF(o); /* reference stored in 'fkey->o' */ t = o->ob_type; if (t == &PyTuple_Type) { int i, count = PyTuple_GET_SIZE(o); n = PyTuple_New(count); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; for (i=0; i<count; i++) PyTuple_SET_ITEM(n, i, copyrec(PyTuple_GET_ITEM(o, i))); return n; } if (t == &PyList_Type) { int i, count = PyList_GET_SIZE(o); n = PyList_New(count); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; for (i=0; i<count; i++) PyList_SET_ITEM(n, i, copyrec(PyList_GET_ITEM(o, i))); return n; } if (t == &PyDict_Type) { int i = 0; PyObject* dictkey; PyObject* dictvalue; n = PyDict_New(); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; while (PyDict_Next(o, &i, &dictkey, &dictvalue)) if (PyDict_SetItem(n, copyrec(dictkey), copyrec(dictvalue))) goto fail; return n; } if (t == &PyInstance_Type) { int i = 0; PyObject* dictkey; PyObject* dictvalue; PyObject* dsrc; PyObject* ddest; PyObject* inst_build = PyObject_GetAttr(o, str_inst_build); if (inst_build == NULL) { PyErr_Clear(); goto unmodified; } n = PyObject_CallObject(inst_build, NULL); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; dsrc = ((PyInstanceObject*) o)->in_dict; ddest = ((PyInstanceObject*) n)->in_dict; while (PyDict_Next(dsrc, &i, &dictkey, &dictvalue)) if (PyDict_SetItem(ddest, copyrec(dictkey), copyrec(dictvalue))) goto fail; return n; } if (t == &PyFunction_Type) { int i, count; PyObject* tsrc = PyFunction_GET_DEFAULTS(o); PyObject* tdest; if (!tsrc) goto unmodified; count = PyTuple_GET_SIZE(tsrc); if (count == 0) goto unmodified; n = PyFunction_New(PyFunction_GET_CODE(o), PyFunction_GET_GLOBALS(o)); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; tdest = PyTuple_New(count); if (!tdest) goto fail; for (i=0; i<count; i++) PyTuple_SET_ITEM(tdest, i, copyrec(PyTuple_GET_ITEM(tsrc, i))); i = PyFunction_SetDefaults(n, tdest); Py_DECREF(tdest); if (i) goto fail; return n; } if (t == &PyMethod_Type) { PyObject* x; n = PyMethod_New(PyMethod_GET_FUNCTION(o), PyMethod_GET_SELF(o), PyMethod_GET_CLASS(o)); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; x = copyrec(PyMethod_GET_FUNCTION(n)); Py_DECREF(PyMethod_GET_FUNCTION(n)); PyMethod_GET_FUNCTION(n) = x; x = copyrec(PyMethod_GET_SELF(n)); Py_DECREF(PyMethod_GET_SELF(n)); PyMethod_GET_SELF(n) = x; return n; } if (t == GeneratorType) { n = genbuild(o); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; if (gencopy(n, o)) goto fail; return n; } if (t == &PySeqIter_Type) { n = seqiterbuild(o); if (!n || PyDict_SetItem(ss_memo, key, n)) goto fail; if (seqitercopy(n, o)) goto fail; return n; } ss_next_in_block++; return o; /* reference no longer stored in 'fkey->o' */ unmodified: PyDict_SetItem(ss_memo, key, o); Py_INCREF(o); return o; fail1: n = NULL; fail: Py_INCREF(o); Py_XDECREF(n); return o; }
static PyObject * call_function(PyObject ***pp_stack, int oparg) { int na = oparg & 0xff; int nk = (oparg>>8) & 0xff; int n = na + 2 * nk; PyObject **pfunc = (*pp_stack) - n - 1; PyObject *func = *pfunc; PyObject *x, *w; /* Always dispatch PyCFunction first, because these are presumed to be the most frequent callable object. */ if (PyCFunction_Check(func) && nk == 0) { int flags = PyCFunction_GET_FLAGS(func); if (flags & (METH_NOARGS | METH_O)) { PyCFunction meth = PyCFunction_GET_FUNCTION(func); PyObject *self = PyCFunction_GET_SELF(func); if (flags & METH_NOARGS && na == 0) x = (*meth)(self, NULL); else if (flags & METH_O && na == 1) { PyObject *arg = EXT_POP(*pp_stack); x = (*meth)(self, arg); Py_DECREF(arg); } else { err_args(func, flags, na); x = NULL; } } else { PyObject *callargs; callargs = load_args(pp_stack, na); x = PyCFunction_Call(func, callargs, NULL); Py_XDECREF(callargs); } } else { if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) { /* optimize access to bound methods */ PyObject *self = PyMethod_GET_SELF(func); Py_INCREF(self); func = PyMethod_GET_FUNCTION(func); Py_INCREF(func); Py_DECREF(*pfunc); *pfunc = self; na++; n++; } else Py_INCREF(func); if (PyFunction_Check(func)) x = fast_function(func, pp_stack, n, na, nk); else x = do_call(func, pp_stack, na, nk); Py_DECREF(func); } /* What does this do? */ while ((*pp_stack) > pfunc) { w = EXT_POP(*pp_stack); Py_DECREF(w); } return x; }
// Get the receiver QObject from the slot (if there is one) and its signature // (if it wraps a Qt slot). A Python exception will be raised if there was an // error. static QObject *get_receiver(qpycore_pyqtBoundSignal *bs, PyObject *slot_obj, QByteArray &name) { PyObject *rx_self, *decorations; QByteArray rx_name; bool try_qt_slot; Chimera::Signature *signature = bs->unbound_signal->signature; decorations = 0; if (PyMethod_Check(slot_obj)) { rx_self = PyMethod_GET_SELF(slot_obj); PyObject *f = PyMethod_GET_FUNCTION(slot_obj); Q_ASSERT(PyFunction_Check(f)); PyObject *f_name_obj = ((PyFunctionObject *)f)->func_name; const char *f_name = sipString_AsASCIIString(&f_name_obj); Q_ASSERT(f_name); rx_name = f_name; Py_DECREF(f_name_obj); // See if this has been decorated. decorations = PyObject_GetAttr(f, qpycore_signature_attr_name); if (decorations) { try_qt_slot = true; // It's convenient to do this here as it's not going to disappear. Py_DECREF(decorations); } else { try_qt_slot = false; } Py_XINCREF(rx_self); } else if (PyCFunction_Check(slot_obj)) { rx_self = PyCFunction_GET_SELF(slot_obj); rx_name = ((PyCFunctionObject *)slot_obj)->m_ml->ml_name; // We actually want the C++ name which may (in theory) be completely // different. However this will cope with the exec_ case which is // probably good enough. if (rx_name.endsWith('_')) rx_name.chop(1); try_qt_slot = true; Py_XINCREF(rx_self); } else { static PyObject *partial = 0; // Get the functools.partial type object if we haven't already got it. if (!partial) { PyObject *functools = PyImport_ImportModule("functools"); if (functools) { partial = PyObject_GetAttrString(functools, "partial"); Py_DECREF(functools); } } // If we know about functools.partial then remove the outer partials to // get to the original function. if (partial && PyObject_IsInstance(slot_obj, partial)) { PyObject *func = slot_obj; Py_INCREF(func); do { PyObject *subfunc = PyObject_GetAttrString(func, "func"); Py_DECREF(func); // This should never happen. if (!subfunc) return 0; func = subfunc; } while (PyObject_IsInstance(func, partial)); if (PyMethod_Check(func)) rx_self = PyMethod_GET_SELF(func); else if (PyCFunction_Check(func)) rx_self = PyCFunction_GET_SELF(func); else rx_self = 0; Py_XINCREF(rx_self); Py_DECREF(func); try_qt_slot = false; } else { rx_self = 0; } } if (!rx_self) return 0; int iserr = 0; void *rx = sipForceConvertToType(rx_self, sipType_QObject, 0, SIP_NO_CONVERTORS, 0, &iserr); Py_DECREF(rx_self); PyErr_Clear(); if (iserr) return 0; QObject *rx_qobj = reinterpret_cast<QObject *>(rx); // If there might be a Qt slot that can handle the arguments (or a subset // of them) then use it. Otherwise we will fallback to using a proxy. if (try_qt_slot) { for (int ol = signature->parsed_arguments.count(); ol >= 0; --ol) { // If there are decorations then we compare the signal's signature // against them so that we distinguish between Python types that // are passed to Qt as PyQt_PyObject objects. Qt will not make the // distinction. If there are no decorations then let Qt determine // if a slot is available. if (decorations) name = slot_signature_from_decorations(signature, decorations, ol); else name = slot_signature_from_metaobject(signature, rx_qobj->metaObject(), rx_name, ol); if (!name.isEmpty()) { // Prepend the magic slot marker. name.prepend('1'); break; } } } return rx_qobj; }
// Get the receiver QObject from the slot (if there is one) and its signature // (if it wraps a Qt slot). A Python exception will be raised if there was an // error. static QObject *get_receiver(Chimera::Signature *overload, PyObject *slot_obj, QByteArray &name) { PyObject *rx_self, *decorations; QByteArray rx_name; bool try_qt_slot; decorations = 0; if (PyMethod_Check(slot_obj)) { rx_self = PyMethod_GET_SELF(slot_obj); PyObject *f = PyMethod_GET_FUNCTION(slot_obj); Q_ASSERT(PyFunction_Check(f)); PyObject *f_name_obj = ((PyFunctionObject *)f)->func_name; const char *f_name = sipString_AsASCIIString(&f_name_obj); Q_ASSERT(f_name); rx_name = f_name; Py_DECREF(f_name_obj); // See if this has been decorated. decorations = PyObject_GetAttr(f, qpycore_signature_attr_name); if (decorations) { try_qt_slot = true; // It's convenient to do this here as it's not going to disappear. Py_DECREF(decorations); } else { try_qt_slot = false; } } else if (PyCFunction_Check(slot_obj)) { rx_self = PyCFunction_GET_SELF(slot_obj); rx_name = ((PyCFunctionObject *)slot_obj)->m_ml->ml_name; // We actually want the C++ name which may (in theory) be completely // different. However this will cope with the exec_ case which is // probably good enough. if (rx_name.endsWith('_')) rx_name.chop(1); try_qt_slot = true; } else { rx_self = 0; } if (!rx_self) return 0; int iserr = 0; void *rx = sipForceConvertToType(rx_self, sipType_QObject, 0, SIP_NO_CONVERTORS, 0, &iserr); PyErr_Clear(); if (iserr) return 0; QObject *rx_qobj = reinterpret_cast<QObject *>(rx); // If there might be a Qt slot that can handle the arguments (or a subset // of them) then use it. Otherwise we will fallback to using a proxy. if (try_qt_slot) { for (int ol = overload->parsed_arguments.count(); ol >= 0; --ol) { // If there are decorations then we compare the signal's signature // against them so that we distinguish between Python types that // are passed to Qt as PyQt_PyObject objects. Qt will not make the // distinction. If there are no decorations then let Qt determine // if a slot is available. if (decorations) name = slot_signature_from_decorations(overload, decorations, ol); else name = slot_signature_from_metaobject(overload, rx_qobj->metaObject(), rx_name, ol); if (!name.isEmpty()) { // Prepend the magic slot marker. name.prepend('1'); break; } } } return rx_qobj; }