PyObject * rpcErrorClass(void) { PyObject *klass, *dict, *func, *meth; PyMethodDef *method; dict = PyDict_New(); if (dict == NULL) return (NULL); klass = PyErr_NewException("xmlrpc.error", NULL, dict); if (klass == NULL) return (NULL); for (method = rpcErrorMethods; method->ml_name != NULL; method++) { func = PyCFunction_New(method, NULL); if (func == NULL) return (NULL); meth = PyMethod_New(func, NULL, klass); if (meth == NULL) return (NULL); if (PyDict_SetItemString(dict, method->ml_name, meth)) return (NULL); Py_DECREF(meth); Py_DECREF(func); } return (klass); }
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)); }
// Stolen from Python's funcobject.c static PyObject * function_descr_get(PyObject *func, PyObject *obj, PyObject *type_) { #if PY_VERSION_HEX >= 0x03000000 // The implement is different in Python 3 because of the removal of unbound method if (obj == Py_None || obj == NULL) { Py_INCREF(func); return func; } return PyMethod_New(func, obj); #else if (obj == Py_None) obj = NULL; return PyMethod_New(func, obj, type_); #endif }
/* Bind a function to an object */ static PyObject * func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { if (obj == Py_None) obj = NULL; return PyMethod_New(func, obj, type); }
static int add_method (PyObject * klass, PyObject * dict, PyMethodDef * method) { PyObject *module = NULL; PyObject *func = NULL; PyObject *meth = NULL; module = PyString_FromString ("gst"); if (module == NULL) goto exception; func = PyCFunction_NewEx (method, NULL, module); if (func == NULL) goto exception; Py_DECREF (module); meth = PyMethod_New (func, NULL, klass); if (meth == NULL) goto exception; Py_DECREF (func); if (PyDict_SetItemString (dict, method->ml_name, meth) < 0) goto exception; Py_DECREF (meth); return 0; exception: Py_XDECREF (module); Py_XDECREF (func); Py_XDECREF (meth); return -1; }
static PyObject * new_instancemethod(PyObject* unused, PyObject* args) { PyObject* func; PyObject* self; PyObject* classObj; if (!PyArg_ParseTuple(args, "OOO!:instancemethod", &func, &self, &PyClass_Type, &classObj)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "first argument must be callable"); return NULL; } if (self == Py_None) self = NULL; else if (!PyInstance_Check(self)) { PyErr_SetString(PyExc_TypeError, "second argument must be instance or None"); return NULL; } return PyMethod_New(func, self, classObj); }
void init_scope(void) { PyMethodDef *def; PyObject *module=Py_InitModule("_scope", ModuleMethods); PyObject *moduleDict=PyModule_GetDict(module); PyObject *classDict=PyDict_New(); PyObject *className = PyString_FromString("Scopeable"); PyObject *scopeableClass = PyClass_New(NULL, classDict, className); PyDict_SetItemString(moduleDict, "Scopeable", scopeableClass); Py_DECREF(classDict); Py_DECREF(className); Py_DECREF(scopeableClass); for (def = ScopeableMethods; def->ml_name != NULL; def++) { PyObject *func=PyCFunction_New(def, NULL); PyObject *method= PyMethod_New(func, NULL, scopeableClass); PyDict_SetItemString(classDict, def->ml_name, method); /* * this would normally happen in PyClass_New() if the classDict * were already populated; but I'm passing it an empty dict */ if (!strncmp(def->ml_name, "__getattr__", strlen("__getattr__"))) { ((PyClassObject *)scopeableClass)->cl_getattr=method; } Py_DECREF(func); Py_DECREF(method); } }
/* * This function returns a NEW reference, i.e. caller must decref it in the end. */ PyObject* JySync_Init_PyMethod_From_JyMethod(jobject src, PyTypeObject* nonNativeSubtype) { env(NULL); return PyMethod_New( JyNI_PyObject_FromJythonPyObject((*env)->GetObjectField(env, src, pyMethod___func__Field)), JyNI_PyObject_FromJythonPyObject((*env)->GetObjectField(env, src, pyMethod___self__Field)), JyNI_PyObject_FromJythonPyObject((*env)->GetObjectField(env, src, pyMethod_im_classField))); }
static PyObject * lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type) { if (obj == Py_None || obj == NULL) { Py_INCREF(self); return self; } return PyMethod_New(self, obj); }
/* Bind a function to an object */ static PyObject * func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { if (obj == Py_None || obj == NULL) { Py_INCREF(func); return func; } return PyMethod_New(func, obj); }
static PyObject * instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); if (obj == NULL) { Py_INCREF(func); return func; } else return PyMethod_New(func, obj); }
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 * cm_descr_get(PyObject *self, PyObject *obj, PyObject *type) { classmethod *cm = (classmethod *)self; if (cm->cm_callable == NULL) { PyErr_SetString(PyExc_RuntimeError, "uninitialized classmethod object"); return NULL; } if (type == NULL) type = (PyObject *)(Py_TYPE(obj)); return PyMethod_New(cm->cm_callable, type); }
static PyObject * adamethod_descr_get (PyAdaMethodDescrObject *descr, PyObject *obj, PyObject *type) { PyObject *res; if (obj == NULL) { Py_INCREF(descr); return (PyObject*) descr; } if (!PyObject_TypeCheck(obj, PyDescr_TYPE(descr))) { PyErr_Format(PyExc_TypeError, "descriptor '%V' for '%s' objects " "doesn't apply to '%s' object", PyDescr_NAME(descr), "?", PyDescr_TYPE(descr)->tp_name, obj->ob_type->tp_name); return NULL; } return PyMethod_New (descr->cfunc, obj); }
static PyObject * method_new(PyTypeObject* type, PyObject* args, PyObject *kw) { PyObject *func; PyObject *self; if (!_PyArg_NoKeywords("method", kw)) return NULL; if (!PyArg_UnpackTuple(args, "method", 2, 2, &func, &self)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "first argument must be callable"); return NULL; } if (self == NULL || self == Py_None) { PyErr_SetString(PyExc_TypeError, "self must not be None"); return NULL; } return PyMethod_New(func, self); }
void initredirector() { PyMethodDef *def; /* create a new module and class */ PyObject *module = Py_InitModule("redirector", ModuleMethods); PyObject *moduleDict = PyModule_GetDict(module); PyObject *classDict = PyDict_New(); PyObject *className = PyString_FromString("redirector"); PyObject *fooClass = PyClass_New(NULL, classDict, className); PyDict_SetItemString(moduleDict, "redirector", fooClass); Py_DECREF(classDict); Py_DECREF(className); Py_DECREF(fooClass); /* add methods to class */ for (def = redirectorMethods; def->ml_name != NULL; def++) { PyObject *func = PyCFunction_New(def, NULL); PyObject *method = PyMethod_New(func, NULL, fooClass); PyDict_SetItemString(classDict, def->ml_name, method); Py_DECREF(func); Py_DECREF(method); } }
/* Implementation of classmethargdefault */ static PyObject *__pyx_f_19classmethargdefault_7Swallow_spam(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/ static PyMethodDef __pyx_mdef_19classmethargdefault_7Swallow_spam = {"spam", (PyCFunction)__pyx_f_19classmethargdefault_7Swallow_spam, METH_VARARGS|METH_KEYWORDS, 0}; static PyObject *__pyx_f_19classmethargdefault_7Swallow_spam(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) { PyObject *__pyx_v_w = 0; int __pyx_v_x; PyObject *__pyx_v_y = 0; PyObject *__pyx_v_z = 0; PyObject *__pyx_r; static char *__pyx_argnames[] = {"w","x","y","z",0}; __pyx_v_x = __pyx_d1; __pyx_v_y = __pyx_d2; __pyx_v_z = __pyx_d3; if (!PyArg_ParseTupleAndKeywords(__pyx_args, __pyx_kwds, "O|iOO", __pyx_argnames, &__pyx_v_w, &__pyx_v_x, &__pyx_v_y, &__pyx_v_z)) return 0; Py_INCREF(__pyx_v_w); Py_INCREF(__pyx_v_y); Py_INCREF(__pyx_v_z); __pyx_r = Py_None; Py_INCREF(Py_None); Py_DECREF(__pyx_v_w); Py_DECREF(__pyx_v_y); Py_DECREF(__pyx_v_z); return __pyx_r; } static struct PyMethodDef __pyx_methods[] = { {0, 0, 0, 0} }; static void __pyx_init_filenames(void); /*proto*/ PyMODINIT_FUNC initclassmethargdefault(void); /*proto*/ PyMODINIT_FUNC initclassmethargdefault(void) { PyObject *__pyx_1 = 0; PyObject *__pyx_2 = 0; PyObject *__pyx_3 = 0; PyObject *__pyx_4 = 0; PyObject *__pyx_5 = 0; __pyx_init_filenames(); __pyx_m = Py_InitModule4("classmethargdefault", __pyx_methods, 0, 0, PYTHON_API_VERSION); if (!__pyx_m) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; }; Py_INCREF(__pyx_m); __pyx_b = PyImport_AddModule("__builtin__"); if (!__pyx_b) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; }; if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; }; if (__Pyx_InitStrings(__pyx_string_tab) < 0) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; }; __pyx_1 = PyDict_New(); if (!__pyx_1) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; } __pyx_2 = PyTuple_New(0); if (!__pyx_2) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; } __pyx_3 = __Pyx_CreateClass(__pyx_2, __pyx_1, __pyx_n_Swallow, "classmethargdefault"); if (!__pyx_3) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; } Py_DECREF(__pyx_2); __pyx_2 = 0; __pyx_d1 = 42; Py_INCREF(__pyx_n_grail); __pyx_d2 = __pyx_n_grail; __pyx_2 = __Pyx_GetName(__pyx_b, __pyx_n_swallow); if (!__pyx_2) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 3; goto __pyx_L1; } __pyx_d3 = __pyx_2; __pyx_2 = 0; __pyx_4 = PyCFunction_NewEx(&__pyx_mdef_19classmethargdefault_7Swallow_spam, 0, __pyx_n_classmethargdefault); if (!__pyx_4) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 3; goto __pyx_L1; } __pyx_5 = PyMethod_New(__pyx_4, 0, __pyx_3); if (!__pyx_5) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 3; goto __pyx_L1; } Py_DECREF(__pyx_4); __pyx_4 = 0; if (PyObject_SetAttr(__pyx_3, __pyx_n_spam, __pyx_5) < 0) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 3; goto __pyx_L1; } Py_DECREF(__pyx_5); __pyx_5 = 0; if (PyObject_SetAttr(__pyx_m, __pyx_n_Swallow, __pyx_3) < 0) { __pyx_filename = __pyx_f[0]; __pyx_lineno = 1; goto __pyx_L1; } Py_DECREF(__pyx_3); __pyx_3 = 0; Py_DECREF(__pyx_1); __pyx_1 = 0; return; __pyx_L1: ; Py_XDECREF(__pyx_1); Py_XDECREF(__pyx_2); Py_XDECREF(__pyx_3); Py_XDECREF(__pyx_4); Py_XDECREF(__pyx_5); __Pyx_AddTraceback("classmethargdefault"); }
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 int PyExtensionClass_Export_(PyObject *dict, char *name, PyTypeObject *typ) { long ecflags = 0; PyMethodDef *pure_methods = NULL, *mdef = NULL; PyObject *m; if (typ->tp_flags == 0) { /* Old-style EC */ if (typ->tp_traverse) { /* ExtensionClasses stick there methods in the tp_traverse slot */ mdef = (PyMethodDef *)typ->tp_traverse; if (typ->tp_basicsize <= sizeof(_emptyobject)) /* Pure mixin. We want rebindable methods */ pure_methods = mdef; else typ->tp_methods = mdef; typ->tp_traverse = NULL; /* Look for __init__ method */ for (; mdef->ml_name; mdef++) { if (strcmp(mdef->ml_name, "__init__") == 0) { /* we have an old-style __init__, install a special slot */ typ->tp_init = ec_init; break; } } } if (typ->tp_clear) { /* ExtensionClasses stick there flags in the tp_clear slot */ ecflags = (long)(typ->tp_clear); /* Some old-style flags were set */ if ((ecflags & EXTENSIONCLASS_BINDABLE_FLAG) && typ->tp_descr_get == NULL) /* We have __of__-style binding */ typ->tp_descr_get = of_get; } typ->tp_clear = NULL; typ->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE; if (typ->tp_dealloc != NULL) typ->tp_new = ec_new_for_custom_dealloc; } typ->ob_type = ECExtensionClassType; if (ecflags & EXTENSIONCLASS_NOINSTDICT_FLAG) typ->tp_base = &NoInstanceDictionaryBaseType; else typ->tp_base = &BaseType; typ->tp_basicsize += typ->tp_base->tp_basicsize; if (typ->tp_new == NULL) typ->tp_new = PyType_GenericNew; if (PyType_Ready(typ) < 0) return -1; if (pure_methods) { /* We had pure methods. We want to be able to rebind these, so we'll make them ordinary method wrappers around method descrs */ for (; pure_methods->ml_name; pure_methods++) { m = PyDescr_NewMethod(ECBaseType, pure_methods); if (! m) return -1; m = PyMethod_New((PyObject *)m, NULL, (PyObject *)ECBaseType); if (! m) return -1; if (PyDict_SetItemString(typ->tp_dict, pure_methods->ml_name, m) < 0) return -1; } #ifdef Py_TPFLAGS_HAVE_VERSION_TAG PyType_Modified(typ); #endif } else if (mdef && mdef->ml_name) { /* Blast, we have to stick __init__ in the dict ourselves because PyType_Ready probably stuck a wrapper for ec_init in instead. */ m = PyDescr_NewMethod(typ, mdef); if (! m) return -1; if (PyDict_SetItemString(typ->tp_dict, mdef->ml_name, m) < 0) return -1; #ifdef Py_TPFLAGS_HAVE_VERSION_TAG PyType_Modified(typ); #endif } if (PyMapping_SetItemString(dict, name, (PyObject*)typ) < 0) return -1; return 0; }
/* * Invoke a single slot (Qt or Python) and return the result. */ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs) { PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref; /* Keep some compilers quiet. */ oxtype = oxvalue = oxtb = NULL; /* Fan out Qt signals. (Only PyQt3 will do this.) */ if (slot->name != NULL && slot->name[0] != '\0') { assert(sipQtSupport->qt_emit_signal); if (sipQtSupport->qt_emit_signal(slot->pyobj, slot->name, sigargs) < 0) return NULL; Py_INCREF(Py_None); return Py_None; } /* Get the object to call, resolving any weak references. */ if (slot->weakSlot == Py_True) { /* * The slot is guaranteed to be Ok because it has an extra reference or * is None. */ sref = slot->pyobj; Py_INCREF(sref); } else if (slot -> weakSlot == NULL) sref = NULL; else if ((sref = PyWeakref_GetObject(slot -> weakSlot)) == NULL) return NULL; else Py_INCREF(sref); if (sref == Py_None) { /* * If the real object has gone then we pretend everything is Ok. This * mimics the Qt behaviour of not caring if a receiving object has been * deleted. */ Py_DECREF(sref); Py_INCREF(Py_None); return Py_None; } if (slot -> pyobj == NULL) { PyObject *self = (sref != NULL ? sref : slot->meth.mself); /* * If the receiver wraps a C++ object then ignore the call if it no * longer exists. */ if (PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type) && sip_api_get_address((sipSimpleWrapper *)self) == NULL) { Py_XDECREF(sref); Py_INCREF(Py_None); return Py_None; } #if PY_MAJOR_VERSION >= 3 sfunc = PyMethod_New(slot->meth.mfunc, self); #else sfunc = PyMethod_New(slot->meth.mfunc, self, slot->meth.mclass); #endif if (sfunc == NULL) { Py_XDECREF(sref); return NULL; } } else if (slot -> name != NULL) { char *mname = slot -> name + 1; PyObject *self = (sref != NULL ? sref : slot->pyobj); if ((sfunc = PyObject_GetAttrString(self, mname)) == NULL || !PyCFunction_Check(sfunc)) { /* * Note that in earlier versions of SIP this error would be * detected when the slot was connected. */ PyErr_Format(PyExc_NameError,"Invalid slot %s",mname); Py_XDECREF(sfunc); Py_XDECREF(sref); return NULL; } } else { sfunc = slot->pyobj; Py_INCREF(sfunc); } /* * We make repeated attempts to call a slot. If we work out that it failed * because of an immediate type error we try again with one less argument. * We keep going until we run out of arguments to drop. This emulates the * Qt ability of the slot to accept fewer arguments than a signal provides. */ sa = sigargs; Py_INCREF(sa); for (;;) { PyObject *nsa, *xtype, *xvalue, *xtb, *resobj; if ((resobj = PyEval_CallObject(sfunc, sa)) != NULL) { Py_DECREF(sfunc); Py_XDECREF(sref); /* Remove any previous exception. */ if (sa != sigargs) { Py_XDECREF(oxtype); Py_XDECREF(oxvalue); Py_XDECREF(oxtb); PyErr_Clear(); } Py_DECREF(sa); return resobj; } /* Get the exception. */ PyErr_Fetch(&xtype,&xvalue,&xtb); /* * See if it is unacceptable. An acceptable failure is a type error * with no traceback - so long as we can still reduce the number of * arguments and try again. */ if (!PyErr_GivenExceptionMatches(xtype,PyExc_TypeError) || xtb != NULL || PyTuple_GET_SIZE(sa) == 0) { /* * If there is a traceback then we must have called the slot and * the exception was later on - so report the exception as is. */ if (xtb != NULL) { if (sa != sigargs) { Py_XDECREF(oxtype); Py_XDECREF(oxvalue); Py_XDECREF(oxtb); } PyErr_Restore(xtype,xvalue,xtb); } else if (sa == sigargs) PyErr_Restore(xtype,xvalue,xtb); else { /* * Discard the latest exception and restore the original one. */ Py_XDECREF(xtype); Py_XDECREF(xvalue); Py_XDECREF(xtb); PyErr_Restore(oxtype,oxvalue,oxtb); } break; } /* If this is the first attempt, save the exception. */ if (sa == sigargs) { oxtype = xtype; oxvalue = xvalue; oxtb = xtb; } else { Py_XDECREF(xtype); Py_XDECREF(xvalue); Py_XDECREF(xtb); } /* Create the new argument tuple. */ if ((nsa = PyTuple_GetSlice(sa,0,PyTuple_GET_SIZE(sa) - 1)) == NULL) { /* Tidy up. */ Py_XDECREF(oxtype); Py_XDECREF(oxvalue); Py_XDECREF(oxtb); break; } Py_DECREF(sa); sa = nsa; } Py_DECREF(sfunc); Py_XDECREF(sref); Py_DECREF(sa); return NULL; }
// get attribute 'name' for object. // uses obj->attr list of tuples for storage. // returns new reference. PyObject* pyjobject_getattr(PyJObject *obj, char *name) { PyObject *ret, *pyname, *methods, *members; ret = pyname = methods = members = NULL; if (!name) { Py_RETURN_NONE; } pyname = PyString_FromString(name); methods = PyString_FromString("__methods__"); members = PyString_FromString("__members__"); if (PyObject_RichCompareBool(pyname, methods, Py_EQ)) { Py_DECREF(pyname); Py_DECREF(methods); Py_DECREF(members); Py_INCREF(obj->methods); return obj->methods; } Py_DECREF(methods); if (PyObject_RichCompareBool(pyname, members, Py_EQ)) { Py_DECREF(pyname); Py_DECREF(members); Py_INCREF(obj->fields); return obj->fields; } Py_DECREF(members); if (!PyList_Check(obj->attr)) { Py_DECREF(pyname); PyErr_Format(PyExc_RuntimeError, "Invalid attr list."); return NULL; } // util function fetches from attr list for us. ret = tuplelist_getitem(obj->attr, pyname); /* new reference */ Py_DECREF(pyname); // method optimizations if (pyjmethod_check(ret) || PyJmultiMethod_Check(ret)) { /* * TODO Should not bind non-static methods to pyjclass objects, but not * sure yet how to handle multimethods and static methods. */ #if PY_MAJOR_VERSION >= 3 PyObject* wrapper = PyMethod_New(ret, (PyObject*) obj); #else PyObject* wrapper = PyMethod_New(ret, (PyObject*) obj, (PyObject*) Py_TYPE(obj)); #endif Py_DECREF(ret); ret = wrapper; } if (PyErr_Occurred() || ret == Py_None) { if (ret == Py_None) { Py_DECREF(Py_None); } PyErr_Format(PyExc_AttributeError, "attr not found: %s", name); return NULL; } if (pyjfield_check(ret)) { PyObject *t = pyjfield_get((PyJFieldObject *) ret); Py_DECREF(ret); return t; } return ret; }