static PyObject * method_richcompare(PyObject *self, PyObject *other, int op) { PyMethodObject *a, *b; PyObject *res; int eq; if ((op != Py_EQ && op != Py_NE) || !PyMethod_Check(self) || !PyMethod_Check(other)) { Py_RETURN_NOTIMPLEMENTED; } a = (PyMethodObject *)self; b = (PyMethodObject *)other; eq = PyObject_RichCompareBool(a->im_func, b->im_func, Py_EQ); if (eq == 1) { if (a->im_self == NULL || b->im_self == NULL) eq = a->im_self == b->im_self; else eq = PyObject_RichCompareBool(a->im_self, b->im_self, Py_EQ); } if (eq < 0) return NULL; if (op == Py_EQ) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; Py_INCREF(res); return res; }
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 bool getReceiver(QObject *source, PyObject* callback, QObject** receiver, PyObject** self) { bool forceGlobalReceiver = false; if (PyMethod_Check(callback)) { *self = PyMethod_GET_SELF(callback); if (Shiboken::Converter<QObject*>::checkType(*self)) *receiver = Shiboken::Converter<QObject*>::toCpp(*self); forceGlobalReceiver = isDecorator(callback, *self); } else if (PyCFunction_Check(callback)) { *self = PyCFunction_GET_SELF(callback); if (*self && Shiboken::Converter<QObject*>::checkType(*self)) *receiver = Shiboken::Converter<QObject*>::toCpp(*self); } else if (PyCallable_Check(callback)) { // Ok, just a callable object *receiver = 0; *self = 0; } bool usingGlobalReceiver = !*receiver || forceGlobalReceiver; if (usingGlobalReceiver) { PySide::SignalManager& signalManager = PySide::SignalManager::instance(); *receiver = signalManager.globalReceiver(source, callback); } return usingGlobalReceiver; }
PyObject * PyMethod_Clone(PyObject *orig) { PyMethodObject *om = (PyMethodObject *)orig; PyMethodObject *im = NULL; if (!Py_PXCTX()) __debugbreak(); if (!PyMethod_Check(orig)) { PyErr_BadInternalCall(); return NULL; } if (om->im_weakreflist) __debugbreak(); im = PyObject_GC_New(PyMethodObject, &PyMethod_Type); if (!im) return NULL; im->im_func = om->im_func; im->im_self = om->im_self; return (PyObject *)im; }
PyObject * PyECMethod_New_(PyObject *callable, PyObject *inst) { if (! PyExtensionInstance_Check(inst)) { PyErr_SetString(PyExc_TypeError, "Can't bind non-ExtensionClass instance."); return NULL; } if (PyMethod_Check(callable)) { if (callable->ob_refcnt == 1) { Py_XDECREF(((PyMethodObject*)callable)->im_self); Py_INCREF(inst); ((PyMethodObject*)callable)->im_self = inst; Py_INCREF(callable); return callable; } else return callable->ob_type->tp_descr_get( callable, inst, ((PyMethodObject*)callable)->im_class); } else return PyMethod_New(callable, inst, (PyObject*)(ECBaseType)); }
gboolean pyvsg_boxed_pyobject_check_method (PyObject *obj) { PyObject *clone = PyObject_GetAttrString (obj, "copy"); if (clone == NULL) return FALSE; return (gboolean) PyMethod_Check (clone); }
PyObject * PyMethod_Function(PyObject *im) { if (!PyMethod_Check(im)) { PyErr_BadInternalCall(); return NULL; } return ((PyMethodObject *)im)->im_func; }
PyObject * PyMethod_Self(PyObject *im) { if (!PyMethod_Check(im)) { PyErr_BadInternalCall(); return NULL; } return ((PyMethodObject *)im)->im_self; }
PyObject * as_function(PyObject *o) { if (PyMethod_Check(o)) { return PyMethod_GET_FUNCTION(o); } else { return o; } }
static PyObject* wxPyGetMethod(PyObject* py, char* name) { if (!PyObject_HasAttrString(py, name)) return NULL; PyObject* o = PyObject_GetAttrString(py, name); if (!PyMethod_Check(o) && !PyCFunction_Check(o)) { Py_DECREF(o); return NULL; } return o; }
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; }
/** * Output streaming operator for a generic PyObject * */ std::ostream& operator<<( std::ostream &o, const PyObjectPtrRef & rpObject ) { const PyObject * pObject = rpObject; //dprintf( "ostream::operator<<(PyObjectPtrRef) 0x%08X\n", pObject ); if (pObject == NULL) { o << "(null)"; } else { if (PyMethod_Check( pObject )) { o << "Type: " << pObject->ob_type->tp_name << " rc: " << pObject->ob_refcnt; } else { PyObject * pString = PyObject_Str( const_cast<PyObject*>( pObject ) ); if (pString == NULL) { PyObject * pError = PyErr_Occurred(); if (pError == NULL) { o << "(!!!Error without Exception!!!)"; } else { o << "(" << pError->ob_type->tp_name << ")"; PyErr_Clear(); } } else { o << PyString_AsString( pString ); Py_DECREF( pString ); } } } Py_XDECREF( const_cast<PyObject*>(pObject) ); return o; }
PyObject* BindingManager::getOverride(const void* cptr, const char* methodName) { SbkObject* wrapper = retrieveWrapper(cptr); // The refcount can be 0 if the object is dieing and someone called // a virtual method from the destructor if (!wrapper || ((PyObject*)wrapper)->ob_refcnt == 0) return 0; if (wrapper->ob_dict) { PyObject* method = PyDict_GetItemString(wrapper->ob_dict, methodName); if (method) { Py_INCREF((PyObject*)method); return method; } } PyObject* pyMethodName = Shiboken::String::fromCString(methodName); PyObject* method = PyObject_GetAttr((PyObject*)wrapper, pyMethodName); if (method && PyMethod_Check(method) && reinterpret_cast<PyMethodObject*>(method)->im_self == reinterpret_cast<PyObject*>(wrapper)) { PyObject* defaultMethod; PyObject* mro = Py_TYPE(wrapper)->tp_mro; // The first class in the mro (index 0) is the class being checked and it should not be tested. // The last class in the mro (size - 1) is the base Python object class which should not be tested also. for (int i = 1; i < PyTuple_GET_SIZE(mro) - 1; i++) { PyTypeObject* parent = reinterpret_cast<PyTypeObject*>(PyTuple_GET_ITEM(mro, i)); if (parent->tp_dict) { defaultMethod = PyDict_GetItem(parent->tp_dict, pyMethodName); if (defaultMethod && reinterpret_cast<PyMethodObject*>(method)->im_func != defaultMethod) { Py_DECREF(pyMethodName); return method; } } } } Py_XDECREF(method); Py_DECREF(pyMethodName); return 0; }
/* * 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_DESC( PyObject *object ) { if ( Nuitka_Function_Check( object ) || Nuitka_Generator_Check( object ) || PyMethod_Check( object ) || PyFunction_Check( object ) || PyCFunction_Check( object ) ) { return "()"; } #if PYTHON_VERSION < 300 else if ( PyClass_Check( object ) ) { return " constructor"; } else if ( PyInstance_Check( object )) { return " instance"; } #endif else { return " object"; } }
PyObject* make_callback_dict(obj_list plugin_list){ PyObject* dict = PyDict_New(); int index = 0; while(index++ < obj_list_len(plugin_list)){ PyObject* cur = obj_list_get(plugin_list, index); //Might need to add self reference to args, dunno PyObject* tuple = PyTuple_New((Py_ssize_t)0); if(!tuple){ printf("Couldn't make tuple ?\n"); PyErr_Print(); } PyObject* getName = PyObject_GetAttrString(cur, "getName"); if(!getName){ printf("Couldn't get the getName method...\n"); PyErr_Print(); } PyObject* plugin_name = PyObject_Call(getName, tuple, NULL); if(!plugin_name){ printf("Couldn't call the getName method...\n"); PyErr_Print(); } Py_DECREF(tuple); Py_DECREF(getName); PyObject* cur_plugin_write = PyObject_GetAttrString(cur, "addMessage"); if(!cur_plugin_write){ printf("Couldn't get addMessage method...\n"); PyErr_Print(); } if(!PyMethod_Check(cur_plugin_write) && !PyFunction_Check(cur_plugin_write)){ printf("Not function or method...\n"); } printf("Does it have the __call__ attribute %d\n", PyObject_HasAttrString(cur_plugin_write, "__call__")); PyDict_SetItem(dict, plugin_name, cur_plugin_write); Py_DECREF(plugin_name); Py_DECREF(cur_plugin_write); } return dict; }
static PyObject * do_multi_setopt(CurlMultiObject *self, PyObject *args) { int option, which; PyObject *obj; if (!PyArg_ParseTuple(args, "iO:setopt", &option, &obj)) return NULL; if (check_multi_state(self, 1 | 2, "setopt") != 0) return NULL; /* Early checks of option value */ if (option <= 0) goto error; if (option >= (int)CURLOPTTYPE_OFF_T + MOPTIONS_SIZE) goto error; if (option % 10000 >= MOPTIONS_SIZE) goto error; /* Handle the case of integer arguments */ if (PyInt_Check(obj)) { return do_multi_setopt_int(self, option, obj); } /* Handle the case of list or tuple objects */ which = PyListOrTuple_Check(obj); if (which) { return do_multi_setopt_list(self, option, which, obj); } if (PyFunction_Check(obj) || PyCFunction_Check(obj) || PyCallable_Check(obj) || PyMethod_Check(obj)) { return do_multi_setopt_callable(self, option, obj); } /* Failed to match any of the function signatures -- return error */ error: PyErr_SetString(PyExc_TypeError, "invalid arguments to setopt"); return NULL; }
CVirtualHelper::CVirtualHelper(const char *iname, void *iassoc, EnumVirtualErrorHandling veh/* = VEH_PRINT_ERROR */) { handler=NULL; py_ob = NULL; retVal=NULL; csHandlerName = iname; vehErrorHandling = veh; if (bInFatalShutdown) return; CEnterLeavePython _celp; ui_assoc_object *py_bob = ui_assoc_object::handleMgr.GetAssocObject( iassoc ); if (py_bob==NULL) return; if (!py_bob->is_uiobject( &ui_assoc_object::type)) { TRACE("CVirtualHelper::CVirtualHelper Error: Call object is not of required type\n"); Py_DECREF(py_bob); return; } // ok - have the python data type - now see if it has an override. if (py_bob->virtualInst) { PyObject *t, *v, *tb; PyErr_Fetch(&t,&v,&tb); handler = PyObject_GetAttrString(py_bob->virtualInst, (char *)iname); if (handler) { // explicitely check a method returned, else the classes // delegation may cause a circular call chain. if (!PyMethod_Check(handler)) { if (!PyCFunction_Check(handler)) { TRACE("Handler for object is not a method!\n"); } DODECREF(handler); handler = NULL; } } PyErr_Restore(t,v,tb); } py_ob = py_bob; // reference on 'py_bob' now owned by 'py_ob' }
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 VALUE ptorObjectBasic(PyObject *pObj, int destructive) { VALUE rObj; // Test the Python object vs various types and convert / wrap it // appropriately. If the destructive flag is set, we destroy // the original. if(PyObject_TypeCheck(pObj,&PyString_Type)) { rObj = ptorString(pObj); if(destructive) Py_DECREF(pObj); return rObj; } if(PyObject_TypeCheck(pObj,&PyList_Type)) { rObj = ptorList(pObj); if(destructive) Py_DECREF(pObj); return rObj; } if(PyObject_TypeCheck(pObj,&PyInt_Type)) { rObj = ptorInt(pObj); if(destructive) Py_DECREF(pObj); return rObj; } if(PyObject_TypeCheck(pObj,&PyLong_Type)) { rObj = ptorLong(pObj); if(destructive) Py_DECREF(pObj); return rObj; } if(PyObject_TypeCheck(pObj,&PyFloat_Type)) { rObj = ptorFloat(pObj); if(destructive) Py_DECREF(pObj); return rObj; } if(PyObject_TypeCheck(pObj,&PyTuple_Type)) { rObj = ptorTuple(pObj); if(destructive) Py_DECREF(pObj); return rObj; } if(PyObject_TypeCheck(pObj,&PyDict_Type)) { rObj = ptorDict(pObj); if(destructive) Py_DECREF(pObj); return rObj; } if(pObj == Py_True) { if(destructive) Py_DECREF(Py_True); return Qtrue; } if(pObj == Py_False) { if(destructive) Py_DECREF(Py_False); return Qfalse; } if(pObj == Py_None) { return Qnil; } if(PyFunction_Check(pObj)||PyMethod_Check(pObj)||!PyObject_HasAttrString(pObj,"__dict__")) { return rpFunctionFromPyObject(pObj); } if(PyInstance_Check(pObj)) { rObj = rpInstanceFromPyObject(pObj); return rObj; } // Fallthrough behavior: The object is a class which should be wrapped return rpClassFromPyObject(pObj); }
void PythonQtSignalTarget::call(void **arguments) const { // Note: we check if the callable is a PyFunctionObject and has a fixed number of arguments // if that is the case, we only pass these arguments to python and skip the additional arguments from the signal int numPythonArgs = -1; if (PyFunction_Check(_callable)) { PyObject* o = _callable; PyFunctionObject* func = (PyFunctionObject*)o; PyCodeObject* code = (PyCodeObject*)func->func_code; if (!(code->co_flags & 0x04)) { numPythonArgs = code->co_argcount; } else { // variable numbers of arguments allowed } } else if (PyMethod_Check(_callable)) { PyObject* o = _callable; PyMethodObject* method = (PyMethodObject*)o; if (PyFunction_Check(method->im_func)) { PyFunctionObject* func = (PyFunctionObject*)method->im_func; PyCodeObject* code = (PyCodeObject*)func->func_code; if (!(code->co_flags & 0x04)) { numPythonArgs = code->co_argcount - 1; // we subtract one because the first is "self" } else { // variable numbers of arguments allowed } } } const PythonQtMethodInfo* m = methodInfo(); // parameterCount includes return value: int count = m->parameterCount(); if (numPythonArgs!=-1) { if (count>numPythonArgs+1) { // take less arguments count = numPythonArgs+1; } } PyObject* pargs = NULL; if (count>1) { pargs = PyTuple_New(count-1); } bool err = false; // transform Qt values to Python const QList<PythonQtMethodInfo::ParameterInfo>& params = m->parameters(); for (int i = 1; i < count; i++) { const PythonQtMethodInfo::ParameterInfo& param = params.at(i); PyObject* arg = PythonQtConv::ConvertQtValueToPython(param, arguments[i]); if (arg) { // steals reference, no unref PyTuple_SetItem(pargs, i-1,arg); } else { err = true; break; } } if (!err) { PyErr_Clear(); PyObject* result = PyObject_CallObject(_callable, pargs); if (result) { // ok Py_DECREF(result); } else { PythonQt::self()->handleError(); } } if (pargs) { // free the arguments again Py_DECREF(pargs); } }
static PyObject * do_multi_setopt(CurlMultiObject *self, PyObject *args) { int option; PyObject *obj; if (!PyArg_ParseTuple(args, "iO:setopt", &option, &obj)) return NULL; if (check_multi_state(self, 1 | 2, "setopt") != 0) return NULL; /* Early checks of option value */ if (option <= 0) goto error; if (option >= (int)CURLOPTTYPE_OFF_T + MOPTIONS_SIZE) goto error; if (option % 10000 >= MOPTIONS_SIZE) goto error; /* Handle the case of integer arguments */ if (PyInt_Check(obj)) { long d = PyInt_AsLong(obj); switch(option) { case CURLMOPT_MAXCONNECTS: case CURLMOPT_PIPELINING: #ifdef HAVE_CURL_7_30_0_PIPELINE_OPTS case CURLMOPT_MAX_HOST_CONNECTIONS: case CURLMOPT_MAX_TOTAL_CONNECTIONS: case CURLMOPT_MAX_PIPELINE_LENGTH: case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE: case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE: #endif curl_multi_setopt(self->multi_handle, option, d); break; default: PyErr_SetString(PyExc_TypeError, "integers are not supported for this option"); return NULL; } Py_RETURN_NONE; } if (PyFunction_Check(obj) || PyCFunction_Check(obj) || PyCallable_Check(obj) || PyMethod_Check(obj)) { /* We use function types here to make sure that our callback * definitions exactly match the <curl/multi.h> interface. */ const curl_multi_timer_callback t_cb = multi_timer_callback; const curl_socket_callback s_cb = multi_socket_callback; switch(option) { case CURLMOPT_SOCKETFUNCTION: curl_multi_setopt(self->multi_handle, CURLMOPT_SOCKETFUNCTION, s_cb); curl_multi_setopt(self->multi_handle, CURLMOPT_SOCKETDATA, self); Py_INCREF(obj); self->s_cb = obj; break; case CURLMOPT_TIMERFUNCTION: curl_multi_setopt(self->multi_handle, CURLMOPT_TIMERFUNCTION, t_cb); curl_multi_setopt(self->multi_handle, CURLMOPT_TIMERDATA, self); Py_INCREF(obj); self->t_cb = obj; break; default: PyErr_SetString(PyExc_TypeError, "callables are not supported for this option"); return NULL; } Py_RETURN_NONE; } /* Failed to match any of the function signatures -- return error */ error: PyErr_SetString(PyExc_TypeError, "invalid arguments to setopt"); return NULL; }
// 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; }
/* * Initialise a slot, returning 0 if there was no error. If the signal was a * Qt signal, then the slot may be a Python signal or a Python slot. If the * signal was a Python signal, then the slot may be anything. */ int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot) { sp -> weakSlot = NULL; if (slot == NULL) { sp -> name = NULL; if (PyMethod_Check(rxObj)) { /* * Python creates methods on the fly. We could increment the * reference count to keep it alive, but that would keep "self" * alive as well and would probably be a circular reference. * Instead we remember the component parts and hope they are still * valid when we re-create the method when we need it. */ sipSaveMethod(&sp -> meth,rxObj); /* Notice if the class instance disappears. */ sp -> weakSlot = getWeakRef(sp -> meth.mself); /* This acts a flag to say that the slot is a method. */ sp -> pyobj = NULL; } else { PyObject *self; /* * We know that it is another type of callable, ie. a * function/builtin. */ if (PyCFunction_Check(rxObj) && (self = PyCFunction_GET_SELF(rxObj)) != NULL && PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type)) { /* * It is a wrapped C++ class method. We can't keep a copy * because they are generated on the fly and we can't take a * reference as that may keep the instance (ie. self) alive. * We therefore treat it as if the user had specified the slot * at "obj, SLOT('meth()')" rather than "obj.meth" (see below). */ const char *meth; /* Get the method name. */ meth = ((PyCFunctionObject *)rxObj) -> m_ml -> ml_name; if ((sp -> name = (char *)sip_api_malloc(strlen(meth) + 2)) == NULL) return -1; /* * Copy the name and set the marker that it needs converting to * a built-in method. */ sp -> name[0] = '\0'; strcpy(&sp -> name[1],meth); sp -> pyobj = self; sp -> weakSlot = getWeakRef(self); } else { /* * Give the slot an extra reference to keep it alive and * remember we have done so by treating weakSlot specially. */ Py_INCREF(rxObj); sp->pyobj = rxObj; Py_INCREF(Py_True); sp->weakSlot = Py_True; } } } else if ((sp -> name = sipStrdup(slot)) == NULL) return -1; else if (isQtSlot(slot)) { /* * The user has decided to connect a Python signal to a Qt slot and * specified the slot as "obj, SLOT('meth()')" rather than "obj.meth". */ char *tail; /* Remove any arguments. */ if ((tail = strchr(sp -> name,'(')) != NULL) *tail = '\0'; /* * A bit of a hack to indicate that this needs converting to a built-in * method. */ sp -> name[0] = '\0'; /* Notice if the class instance disappears. */ sp -> weakSlot = getWeakRef(rxObj); sp -> pyobj = rxObj; } else /* It's a Qt signal. */ sp -> pyobj = rxObj; return 0; }
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; }
/**************************** * SV* Py2Pl(PyObject *obj) * * Converts arbitrary Python data structures to Perl data structures * Note on references: does not Py_DECREF(obj). * * Modifications by Eric Wilhelm 2004-07-11 marked as elw * ****************************/ SV *Py2Pl(PyObject * const obj) { /* elw: see what python says things are */ #if PY_MAJOR_VERSION >= 3 int const is_string = PyBytes_Check(obj) || PyUnicode_Check(obj); #else int const is_string = PyString_Check(obj) || PyUnicode_Check(obj); #endif #ifdef I_PY_DEBUG PyObject *this_type = PyObject_Type(obj); /* new reference */ PyObject *t_string = PyObject_Str(this_type); /* new reference */ #if PY_MAJOR_VERSION >= 3 PyObject *type_str_bytes = PyUnicode_AsUTF8String(t_string); /* new reference */ char *type_str = PyBytes_AsString(type_str_bytes); #else char *type_str = PyString_AsString(t_string); #endif Printf(("type is %s\n", type_str)); printf("Py2Pl object:\n\t"); PyObject_Print(obj, stdout, Py_PRINT_RAW); printf("\ntype:\n\t"); PyObject_Print(this_type, stdout, Py_PRINT_RAW); printf("\n"); Printf(("String check: %i\n", is_string)); Printf(("Number check: %i\n", PyNumber_Check(obj))); Printf(("Int check: %i\n", PyInt_Check(obj))); Printf(("Long check: %i\n", PyLong_Check(obj))); Printf(("Float check: %i\n", PyFloat_Check(obj))); Printf(("Type check: %i\n", PyType_Check(obj))); #if PY_MAJOR_VERSION < 3 Printf(("Class check: %i\n", PyClass_Check(obj))); Printf(("Instance check: %i\n", PyInstance_Check(obj))); #endif Printf(("Dict check: %i\n", PyDict_Check(obj))); Printf(("Mapping check: %i\n", PyMapping_Check(obj))); Printf(("Sequence check: %i\n", PySequence_Check(obj))); Printf(("Iter check: %i\n", PyIter_Check(obj))); Printf(("Function check: %i\n", PyFunction_Check(obj))); Printf(("Module check: %i\n", PyModule_Check(obj))); Printf(("Method check: %i\n", PyMethod_Check(obj))); #if PY_MAJOR_VERSION < 3 if ((obj->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE)) printf("heaptype true\n"); if ((obj->ob_type->tp_flags & Py_TPFLAGS_HAVE_CLASS)) printf("has class\n"); #else Py_DECREF(type_str_bytes); #endif Py_DECREF(t_string); Py_DECREF(this_type); #endif /* elw: this needs to be early */ /* None (like undef) */ if (!obj || obj == Py_None) { Printf(("Py2Pl: Py_None\n")); return &PL_sv_undef; } else #ifdef EXPOSE_PERL /* unwrap Perl objects */ if (PerlObjObject_Check(obj)) { Printf(("Py2Pl: Obj_object\n")); return ((PerlObj_object *) obj)->obj; } /* unwrap Perl code refs */ else if (PerlSubObject_Check(obj)) { Printf(("Py2Pl: Sub_object\n")); SV * ref = ((PerlSub_object *) obj)->ref; if (! ref) { /* probably an inherited method */ if (! ((PerlSub_object *) obj)->obj) croak("Error: could not find a code reference or object method for PerlSub"); SV * const sub_obj = (SV*)SvRV(((PerlSub_object *) obj)->obj); HV * const pkg = SvSTASH(sub_obj); #if PY_MAJOR_VERSION >= 3 char * const sub = PyBytes_AsString(((PerlSub_object *) obj)->sub); #else PyObject *obj_sub_str = PyObject_Str(((PerlSub_object *) obj)->sub); /* new ref. */ char * const sub = PyString_AsString(obj_sub_str); #endif GV * const gv = Perl_gv_fetchmethod_autoload(aTHX_ pkg, sub, TRUE); if (gv && isGV(gv)) { ref = (SV *)GvCV(gv); } #if PY_MAJOR_VERSION < 3 Py_DECREF(obj_sub_str); #endif } return newRV_inc((SV *) ref); } else #endif /* wrap an instance of a Python class */ /* elw: here we need to make these look like instances: */ if ((obj->ob_type->tp_flags & Py_TPFLAGS_HEAPTYPE) #if PY_MAJOR_VERSION < 3 || PyInstance_Check(obj) #endif ) { /* This is a Python class instance -- bless it into an * Inline::Python::Object. If we're being called from an * Inline::Python class, it will be re-blessed into whatever * class that is. */ SV * const inst_ptr = newSViv(0); SV * const inst = newSVrv(inst_ptr, "Inline::Python::Object");; _inline_magic priv; /* set up magic */ priv.key = INLINE_MAGIC_KEY; sv_magic(inst, inst, PERL_MAGIC_ext, (char *) &priv, sizeof(priv)); MAGIC * const mg = mg_find(inst, PERL_MAGIC_ext); mg->mg_virtual = &inline_mg_vtbl; sv_setiv(inst, (IV) obj); /*SvREADONLY_on(inst); */ /* to uncomment this means I can't re-bless it */ Py_INCREF(obj); Printf(("Py2Pl: Instance. Obj: %p, inst_ptr: %p\n", obj, inst_ptr)); sv_2mortal(inst_ptr); return inst_ptr; } /* a tuple or a list */ else if (PySequence_Check(obj) && !is_string) { AV * const retval = newAV(); int i; int const sz = PySequence_Length(obj); Printf(("sequence (%i)\n", sz)); for (i = 0; i < sz; i++) { PyObject * const tmp = PySequence_GetItem(obj, i); /* new reference */ SV * const next = Py2Pl(tmp); av_push(retval, next); if (sv_isobject(next)) // needed because objects get mortalized in Py2Pl SvREFCNT_inc(next); Py_DECREF(tmp); } if (PyTuple_Check(obj)) { _inline_magic priv; priv.key = TUPLE_MAGIC_KEY; sv_magic((SV * const)retval, (SV * const)NULL, PERL_MAGIC_ext, (char *) &priv, sizeof(priv)); } return newRV_noinc((SV *) retval); } /* a dictionary or fake Mapping object */ /* elw: PyMapping_Check() now returns true for strings */ else if (! is_string && PyMapping_Check(obj)) { HV * const retval = newHV(); int i; int const sz = PyMapping_Length(obj); PyObject * const keys = PyMapping_Keys(obj); /* new reference */ PyObject * const vals = PyMapping_Values(obj); /* new reference */ Printf(("Py2Pl: dict/map\n")); Printf(("mapping (%i)\n", sz)); for (i = 0; i < sz; i++) { PyObject * const key = PySequence_GetItem(keys, i), /* new reference */ * const val = PySequence_GetItem(vals, i); /* new reference */ SV * const sv_val = Py2Pl(val); char * key_val; if (PyUnicode_Check(key)) { PyObject * const utf8_string = PyUnicode_AsUTF8String(key); /* new reference */ #if PY_MAJOR_VERSION >= 3 key_val = PyBytes_AsString(utf8_string); SV * const utf8_key = newSVpv(key_val, PyBytes_Size(utf8_string)); #else key_val = PyString_AsString(utf8_string); SV * const utf8_key = newSVpv(key_val, PyString_Size(utf8_string)); #endif SvUTF8_on(utf8_key); hv_store_ent(retval, utf8_key, sv_val, 0); Py_DECREF(utf8_string); } else { PyObject * s = NULL; #if PY_MAJOR_VERSION >= 3 PyObject * s_bytes = NULL; if (PyBytes_Check(key)) { key_val = PyBytes_AsString(key); #else if (PyString_Check(key)) { key_val = PyString_AsString(key); #endif } else { /* Warning -- encountered a non-string key value while converting a * Python dictionary into a Perl hash. Perl can only use strings as * key values. Using Python's string representation of the key as * Perl's key value. */ s = PyObject_Str(key); /* new reference */ #if PY_MAJOR_VERSION >= 3 s_bytes = PyUnicode_AsUTF8String(s); /* new reference */ key_val = PyBytes_AsString(s_bytes); #else key_val = PyString_AsString(s); #endif Py_DECREF(s); if (PL_dowarn) warn("Stringifying non-string hash key value: '%s'", key_val); } if (!key_val) { croak("Invalid key on key %i of mapping\n", i); } hv_store(retval, key_val, strlen(key_val), sv_val, 0); #if PY_MAJOR_VERSION >= 3 Py_XDECREF(s_bytes); #endif Py_XDECREF(s); } if (sv_isobject(sv_val)) // needed because objects get mortalized in Py2Pl SvREFCNT_inc(sv_val); Py_DECREF(key); Py_DECREF(val); } Py_DECREF(keys); Py_DECREF(vals); return newRV_noinc((SV *) retval); } /* a boolean */ else if (PyBool_Check(obj)) {
static PyObject * warn_explicit(PyObject *category, PyObject *message, PyObject *filename, int lineno, PyObject *module, PyObject *registry, PyObject *sourceline) { PyObject *key = NULL, *text = NULL, *result = NULL, *lineno_obj = NULL; PyObject *item = Py_None; const char *action; int rc; if (registry && !PyDict_Check(registry) && (registry != Py_None)) { PyErr_SetString(PyExc_TypeError, "'registry' must be a dict"); return NULL; } /* Normalize module. */ if (module == NULL) { module = normalize_module(filename); if (module == NULL) return NULL; } else Py_INCREF(module); /* Normalize message. */ Py_INCREF(message); /* DECREF'ed in cleanup. */ rc = PyObject_IsInstance(message, PyExc_Warning); if (rc == -1) { goto cleanup; } if (rc == 1) { text = PyObject_Str(message); if (text == NULL) goto cleanup; category = (PyObject*)message->ob_type; } else { text = message; message = PyObject_CallFunction(category, "O", message); if (message == NULL) goto cleanup; } lineno_obj = PyInt_FromLong(lineno); if (lineno_obj == NULL) goto cleanup; /* Create key. */ key = PyTuple_Pack(3, text, category, lineno_obj); if (key == NULL) goto cleanup; if ((registry != NULL) && (registry != Py_None)) { rc = already_warned(registry, key, 0); if (rc == -1) goto cleanup; else if (rc == 1) goto return_none; /* Else this warning hasn't been generated before. */ } action = get_filter(category, text, lineno, module, &item); if (action == NULL) goto cleanup; if (strcmp(action, "error") == 0) { PyErr_SetObject(category, message); goto cleanup; } /* Store in the registry that we've been here, *except* when the action is "always". */ rc = 0; if (strcmp(action, "always") != 0) { if (registry != NULL && registry != Py_None && PyDict_SetItem(registry, key, Py_True) < 0) goto cleanup; else if (strcmp(action, "ignore") == 0) goto return_none; else if (strcmp(action, "once") == 0) { if (registry == NULL || registry == Py_None) { registry = get_once_registry(); if (registry == NULL) goto cleanup; } /* _once_registry[(text, category)] = 1 */ rc = update_registry(registry, text, category, 0); } else if (strcmp(action, "module") == 0) { /* registry[(text, category, 0)] = 1 */ if (registry != NULL && registry != Py_None) rc = update_registry(registry, text, category, 0); } else if (strcmp(action, "default") != 0) { PyObject *to_str = PyObject_Str(item); const char *err_str = "???"; if (to_str != NULL) err_str = PyString_AS_STRING(to_str); PyErr_Format(PyExc_RuntimeError, "Unrecognized action (%s) in warnings.filters:\n %s", action, err_str); Py_XDECREF(to_str); goto cleanup; } } if (rc == 1) /* Already warned for this module. */ goto return_none; if (rc == 0) { PyObject *show_fxn = get_warnings_attr("showwarning"); if (show_fxn == NULL) { if (PyErr_Occurred()) goto cleanup; show_warning(filename, lineno, text, category, sourceline); } else { PyObject *res; if (!PyMethod_Check(show_fxn) && !PyFunction_Check(show_fxn)) { PyErr_SetString(PyExc_TypeError, "warnings.showwarning() must be set to a " "function or method"); Py_DECREF(show_fxn); goto cleanup; } res = PyObject_CallFunctionObjArgs(show_fxn, message, category, filename, lineno_obj, NULL); Py_DECREF(show_fxn); Py_XDECREF(res); if (res == NULL) goto cleanup; } } else /* if (rc == -1) */ goto cleanup; return_none: result = Py_None; Py_INCREF(result); cleanup: Py_XDECREF(key); Py_XDECREF(text); Py_XDECREF(lineno_obj); Py_DECREF(module); Py_XDECREF(message); return result; /* Py_None or NULL. */ }
// 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; }