/* * Get possible out argument from kwds, and returns the number of outputs * contained within it: if a tuple, the number of elements in it, 1 otherwise. * The out argument itself is returned in out_kwd_obj, and the outputs * in the out_obj array (all as borrowed references). * * Returns -1 if kwds is not a dict, 0 if no outputs found. */ static int get_out_objects(PyObject *kwds, PyObject **out_kwd_obj, PyObject ***out_objs) { if (kwds == NULL) { return 0; } if (!PyDict_CheckExact(kwds)) { PyErr_SetString(PyExc_TypeError, "Internal Numpy error: call to PyUFunc_WithOverride " "with non-dict kwds"); return -1; } /* borrowed reference */ *out_kwd_obj = PyDict_GetItemString(kwds, "out"); if (*out_kwd_obj == NULL) { return 0; } if (PyTuple_CheckExact(*out_kwd_obj)) { *out_objs = PySequence_Fast_ITEMS(*out_kwd_obj); return PySequence_Fast_GET_SIZE(*out_kwd_obj); } else { *out_objs = out_kwd_obj; return 1; } }
static int BaseRowProxy_init(BaseRowProxy *self, PyObject *args, PyObject *kwds) { PyObject *parent, *row, *processors, *keymap; if (!PyArg_UnpackTuple(args, "BaseRowProxy", 4, 4, &parent, &row, &processors, &keymap)) return -1; Py_INCREF(parent); self->parent = parent; if (!PySequence_Check(row)) { PyErr_SetString(PyExc_TypeError, "row must be a sequence"); return -1; } Py_INCREF(row); self->row = row; if (!PyList_CheckExact(processors)) { PyErr_SetString(PyExc_TypeError, "processors must be a list"); return -1; } Py_INCREF(processors); self->processors = processors; if (!PyDict_CheckExact(keymap)) { PyErr_SetString(PyExc_TypeError, "keymap must be a dict"); return -1; } Py_INCREF(keymap); self->keymap = keymap; return 0; }
static Nuitka_DictEntryHandle GET_STRING_DICT_ENTRY( PyDictObject *dict, Nuitka_StringObject *key ) { assert( PyDict_CheckExact( dict ) ); assert( Nuitka_String_Check( key ) ); Py_hash_t hash = key->_base._base.hash; // Only improvement would be to identify how to ensure that the hash is computed // already. Calling hash early on could do that potentially. if ( hash == -1 ) { hash = PyUnicode_Type.tp_hash( (PyObject *)key ); key->_base._base.hash = hash; } PyObject **value_addr; PyDictKeyEntry *entry = dict->ma_keys->dk_lookup( dict, (PyObject *)key, hash, &value_addr ); // The "entry" cannot be NULL, it can only be empty for a string dict lookup, but at // least assert it. assert( entry != NULL ); return value_addr; }
static PyDictEntry *GET_STRING_DICT_ENTRY( PyDictObject *dict, Nuitka_StringObject *key ) { assert( PyDict_CheckExact( dict ) ); assert( Nuitka_String_Check( key ) ); #if PYTHON_VERSION < 300 Py_hash_t hash = key->ob_shash; #else Py_hash_t hash = key->hash; #endif // Only improvement would be to identify how to ensure that the hash is // computed already. Calling hash early on could do that potentially. if ( hash == -1 ) { #if PYTHON_VERSION < 300 hash = PyString_Type.tp_hash( (PyObject *)key ); key->ob_shash = hash; #else hash = PyUnicode_Type.tp_hash( (PyObject *)key ); key->hash = hash; #endif } PyDictEntry *entry = dict->ma_lookup( dict, (PyObject *)key, hash ); // The "entry" cannot be NULL, it can only be empty for a string dict // lookup, but at least assert it. assert( entry != NULL ); return entry; }
static void py_variable_to_json_internal( PyObject *obj, json_writer_t *writer ) { if ( PyString_CheckExact( obj ) ) { json_writer_write_str( writer, PyString_AS_STRING( obj ) ); } else if ( PyInt_CheckExact( obj ) ) { json_writer_write_integer( writer, PyInt_AS_LONG( obj ) ); } else if ( PyFloat_CheckExact( obj ) ) { json_writer_write_number( writer, PyFloat_AS_DOUBLE( obj ) ); } else if ( PyBool_Check( obj ) ) { json_writer_write_boolean( writer, ( obj == Py_True ) ); } else if ( PyUnicode_CheckExact( obj ) ) { /* Create a new string object that is UTF-8 encoded. */ Py_UNICODE *unicode = PyUnicode_AS_UNICODE( obj ); Py_ssize_t size = PyUnicode_GET_SIZE( obj ); PyObject *str_obj = PyUnicode_EncodeUTF8( unicode, size, NULL ); py_variable_to_json_internal( str_obj, writer ); PyObject_Free( str_obj ); } else if ( PyDict_CheckExact( obj ) ) { py_dict_to_json( obj, writer ); } else if ( PyList_CheckExact( obj ) ) { py_list_to_json( obj, writer ); } else if ( PyTuple_CheckExact( obj ) ) { py_tuple_to_json( obj, writer ); } }
Box* setInit(Box* _self, Box* container, BoxedDict* kwargs) { RELEASE_ASSERT(PySet_Check(_self), ""); if (PySet_Check(_self) && !_PyArg_NoKeywords("set()", kwargs)) { throwCAPIException(); } if (!container) return incref(None); BoxedSet* self = static_cast<BoxedSet*>(_self); setClearInternal(self); if (PyAnySet_Check(container)) { for (auto&& elt : ((BoxedSet*)container)->s) { self->s.insert(incref(elt)); } } else if (PyDict_CheckExact(container)) { for (auto&& elt : ((BoxedDict*)container)->d) { self->s.insert(incref(elt.first)); } } else { for (auto elt : container->pyElements()) { _setAddStolen(self, elt); } } return incref(None); }
// Convert a Python object to a QVariantHash and return true if there was no // error. bool Chimera::to_QVariantHash(PyObject *py, QVariantHash &cpp) const { Q_ASSERT(PyDict_CheckExact(py)); PyObject *key_obj, *val_obj; SIP_SSIZE_T i; i = 0; while (PyDict_Next(py, &i, &key_obj, &val_obj)) { int key_state, val_state, iserr = 0; QString *key = reinterpret_cast<QString *>(sipForceConvertToType( key_obj, sipType_QString, NULL, SIP_NOT_NONE, &key_state, &iserr)); QVariant *val = reinterpret_cast<QVariant *>(sipForceConvertToType( val_obj, sipType_QVariant, NULL, SIP_NOT_NONE, &val_state, &iserr)); if (iserr) return false; cpp.insert(*key, *val); sipReleaseType(key, sipType_QString, key_state); sipReleaseType(val, sipType_QVariant, val_state); } return true; }
/* Move the unreachable objects from young to unreachable. After this, * all objects in young have gc_refs = GC_REACHABLE, and all objects in * unreachable have gc_refs = GC_TENTATIVELY_UNREACHABLE. All tracked * gc objects not in young or unreachable still have gc_refs = GC_REACHABLE. * All objects in young after this are directly or indirectly reachable * from outside the original young; and all objects in unreachable are * not. */ static void move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) { PyGC_Head *gc = young->gc.gc_next; /* Invariants: all objects "to the left" of us in young have gc_refs * = GC_REACHABLE, and are indeed reachable (directly or indirectly) * from outside the young list as it was at entry. All other objects * from the original young "to the left" of us are in unreachable now, * and have gc_refs = GC_TENTATIVELY_UNREACHABLE. All objects to the * left of us in 'young' now have been scanned, and no objects here * or to the right have been scanned yet. */ while (gc != young) { PyGC_Head *next; if (gc->gc.gc_refs) { /* gc is definitely reachable from outside the * original 'young'. Mark it as such, and traverse * its pointers to find any other objects that may * be directly reachable from it. Note that the * call to tp_traverse may append objects to young, * so we have to wait until it returns to determine * the next object to visit. */ PyObject *op = FROM_GC(gc); traverseproc traverse = Py_TYPE(op)->tp_traverse; assert(gc->gc.gc_refs > 0); gc->gc.gc_refs = GC_REACHABLE; (void) traverse(op, (visitproc)visit_reachable, (void *)young); next = gc->gc.gc_next; if (PyTuple_CheckExact(op)) { _PyTuple_MaybeUntrack(op); } else if (PyDict_CheckExact(op)) { _PyDict_MaybeUntrack(op); } } else { /* This *may* be unreachable. To make progress, * assume it is. gc isn't directly reachable from * any object we've already traversed, but may be * reachable from an object we haven't gotten to yet. * visit_reachable will eventually move gc back into * young if that's so, and we'll see it again. */ next = gc->gc.gc_next; gc_list_move(gc, unreachable); gc->gc.gc_refs = GC_TENTATIVELY_UNREACHABLE; } gc = next; } }
static int cdefer_Deferred__verify_callback_entry(const char *callback_name, PyObject *callback_entry) { PyObject *callback; PyObject *args; PyObject *kw; if (!PyTuple_Check(callback_entry)) { PyErr_Format(PyExc_TypeError, "%s entries must be tuples", callback_name); return -1; } if (3 != PyTuple_GET_SIZE(callback_entry)) { PyErr_Format(PyExc_TypeError, "%s entries must contain exactly (callback, args, kw)", callback_name); return -1; } callback = PyTuple_GET_ITEM(callback_entry, 0); if ((Py_None != callback) && !PyCallable_Check(callback)) { PyErr_Format(PyExc_TypeError, "%s entry callback must be callable", callback_name); return -1; } args = PyTuple_GET_ITEM(callback_entry, 1); if (Py_None != args) { if (Py_None == callback) { PyErr_Format(PyExc_TypeError, "%s entry got a None callback with non-None args", callback_name); return -1; } if (!PyTuple_Check(args)) { PyErr_Format(PyExc_TypeError, "%s entry args must be tuples or None", callback_name); return -1; } } kw = PyTuple_GET_ITEM(callback_entry, 2); if (Py_None != kw) { if (Py_None == callback) { PyErr_Format(PyExc_TypeError, "%s entry got a None callback with non-None kws", callback_name); return -1; } if (!PyDict_CheckExact(kw)) { PyErr_Format(PyExc_TypeError, "%s entry kws must be dicts or None", callback_name); return -1; } } return 0; }
PyObject * PyTuple_DeepCopy(register PyObject *a) { PyTupleObject *np; PyObject **src, **dest; register Py_ssize_t i; Py_ssize_t len = Py_SIZE(a); np = (PyTupleObject *)PyTuple_New(len); if (np == NULL) return NULL; src = ((PyTupleObject *) a)->ob_item; dest = np->ob_item; for (i = 0; i < len; i++) { register PyObject *v = src[i]; Py_INCREF(v); if (PyTuple_CheckExact(v)) { PyObject *w = PyTuple_DeepCopy(v); Py_DECREF(v); if (!w) { Py_DECREF(np); return NULL; } v = w; } else if (PyList_CheckExact(v)) { PyObject *w = PyList_DeepCopy(v); Py_DECREF(v); if (!w) { Py_DECREF(np); return NULL; } v = w; } else if (PyDict_CheckExact(v)) { PyObject *w = PyDict_DeepCopy(v); Py_DECREF(v); if (!w) { Py_DECREF(np); return NULL; } v = w; } dest[i] = v; } return (PyObject *)np; }
// TODO: Have mapping.hpp NUITKA_MAY_BE_UNUSED static void DICT_SYNC_FROM_VARIABLE( PyObject *dict, PyObject *key, PyObject *value ) { if ( value ) { assert( PyDict_CheckExact( dict ) ); UPDATE_STRING_DICT0( (PyDictObject *)dict, (Nuitka_StringObject *)key, value ); } else { int res = PyDict_DelItem( dict, key ); if ( res != 0 ) { CLEAR_ERROR_OCCURRED(); } } }
static PyObject * partial_setstate(partialobject *pto, PyObject *state) { PyObject *fn, *fnargs, *kw, *dict; if (!PyTuple_Check(state) || !PyArg_ParseTuple(state, "OOOO", &fn, &fnargs, &kw, &dict) || !PyCallable_Check(fn) || !PyTuple_Check(fnargs) || (kw != Py_None && !PyDict_Check(kw))) { PyErr_SetString(PyExc_TypeError, "invalid partial state"); return NULL; } if(!PyTuple_CheckExact(fnargs)) fnargs = PySequence_Tuple(fnargs); else Py_INCREF(fnargs); if (fnargs == NULL) return NULL; if (kw == Py_None) kw = PyDict_New(); else if(!PyDict_CheckExact(kw)) kw = PyDict_Copy(kw); else Py_INCREF(kw); if (kw == NULL) { Py_DECREF(fnargs); return NULL; } if (dict == Py_None) dict = NULL; else Py_INCREF(dict); Py_INCREF(fn); pto->use_fastcall = _PyObject_HasFastCall(fn); Py_SETREF(pto->fn, fn); Py_SETREF(pto->args, fnargs); Py_SETREF(pto->kw, kw); Py_XSETREF(pto->dict, dict); Py_RETURN_NONE; }
static void _setDifferenceUpdate(BoxedSet* self, BoxedTuple* args) { for (auto container : args->pyElements()) { AUTO_DECREF(container); if (PyAnySet_Check(container)) { for (auto&& elt : ((BoxedSet*)container)->s) { _setRemove(self, elt); } } else if (PyDict_CheckExact(container)) { for (auto&& elt : ((BoxedDict*)container)->d) { _setRemove(self, elt.first); } } else { for (auto elt : container->pyElements()) { AUTO_DECREF(elt); _setRemove(self, elt); } } } }
json_t *py_variable_to_json( apr_pool_t *mp, PyObject *obj ) { json_writer_t *writer; json_t *json = NULL; apr_pool_t *tmp_mp; if ( PyDict_CheckExact( obj ) || PyList_CheckExact( obj ) || PyTuple_CheckExact( obj ) ) { apr_pool_create( &tmp_mp, NULL ); writer = json_writer_create( tmp_mp, mp ); py_variable_to_json_internal( obj, writer ); json = writer->json; apr_pool_destroy( tmp_mp ); } else { fprintf( stderr, "Must be an object, list or tuple.\n" ); } return json; }
static int BaseRowProxy_setkeymap(BaseRowProxy *self, PyObject *value, void *closure) { if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the 'keymap' attribute"); return -1; } if (!PyDict_CheckExact(value)) { PyErr_SetString(PyExc_TypeError, "The 'keymap' attribute value must be a dict"); return -1; } Py_XDECREF(self->keymap); Py_INCREF(value); self->keymap = value; return 0; }
static PyObject* convert_nested(PyObject *ob, convert_func convert_string) { /* dict. */ if (PyDict_CheckExact(ob)) { return convert_dict(ob, convert_string); } /* sequence. */ if (PyTuple_CheckExact(ob) || PyList_CheckExact(ob)) { return convert_seq(ob, convert_string); } /* numbers. */ if (PyInt_CheckExact(ob) || PyLong_CheckExact(ob) || PyFloat_CheckExact(ob)) { Py_INCREF(ob); return ob; } /* bool. */ if (PyBool_Check(ob)) { Py_INCREF(ob); return ob; } /* none. */ if (ob == Py_None) { Py_INCREF(ob); return ob; } if (PyString_CheckExact(ob) || PyUnicode_CheckExact(ob)) { return convert_string(ob); } return PyErr_Format( PyExc_TypeError, "Got wrong type: %s", ob->ob_type->tp_name); }
static PyObject* new_check(PyObject* args) { // We don't support a normal constructor, so only allow this for unpickling. There should be a single arg that was // returned by Row_reduce. Make sure the sizes match. The desc and map should have one entry per column, which // should equal the number of remaining items. if (PyTuple_GET_SIZE(args) < 3) return 0; PyObject* desc = PyTuple_GET_ITEM(args, 0); PyObject* map = PyTuple_GET_ITEM(args, 1); if (!PyTuple_CheckExact(desc) || !PyDict_CheckExact(map)) return 0; Py_ssize_t cols = PyTuple_GET_SIZE(desc); if (PyDict_Size(map) != cols || PyTuple_GET_SIZE(args) - 2 != cols) return 0; PyObject** apValues = (PyObject**)pyodbc_malloc(sizeof(PyObject*) * cols); if (!apValues) return 0; for (int i = 0; i < cols; i++) { apValues[i] = PyTuple_GET_ITEM(args, i+2); Py_INCREF(apValues[i]); } // Row_Internal will incref desc and map. PyObject* self = (PyObject*)Row_InternalNew(desc, map, cols, apValues); if (!self) pyodbc_free(apValues); return self; }
// Creates a set of type 'cls' from 'container' (NULL to get an empty set). // Works for frozenset and normal set types. BoxedSet* makeNewSet(BoxedClass* cls, Box* container) { assert(isSubclass(cls, frozenset_cls) || isSubclass(cls, set_cls)); BoxedSet* rtn = new (cls) BoxedSet(); if (container) { AUTO_DECREF(rtn); if (PyAnySet_Check(container)) { for (auto&& elt : ((BoxedSet*)container)->s) { rtn->s.insert(incref(elt)); } } else if (PyDict_CheckExact(container)) { for (auto&& elt : ((BoxedDict*)container)->d) { rtn->s.insert(incref(elt.first)); } } else { for (auto elt : container->pyElements()) { _setAddStolen(rtn, elt); } } return incref(rtn); } return rtn; }
NUITKA_MAY_BE_UNUSED static PyObject *DICT_GET_ITEM( PyObject *dict, PyObject *key ) { CHECK_OBJECT( dict ); assert( PyDict_CheckExact( dict ) ); CHECK_OBJECT( key ); PyObject *result = PyDict_GetItem( dict, key ); if ( result == NULL ) { if (unlikely( PyErr_Occurred() )) { return NULL; } /* Wrap all kinds of tuples, because normalization will later unwrap * it, but then that changes the key for the KeyError, which is not * welcome. The check is inexact, as the unwrapping one is too. */ if ( PyTuple_Check( key ) ) { PyObject *tuple = PyTuple_Pack( 1, key ); PyErr_SetObject( PyExc_KeyError, tuple ); Py_DECREF( tuple ); } else { PyErr_SetObject( PyExc_KeyError, key ); } return NULL; } else { return INCREASE_REFCOUNT( result ); } }
static PyObject * ntracenative_frameSetLocals(PyObject *self, PyObject *args) { PyObject *frameobj = NULL,*dict = NULL; PyFrameObject *frame; (void) self; //printf("before parse\n"); if (!PyArg_ParseTuple( args, "OO", &frameobj, &dict)) { return NULL; } //printf("before framecheck frameobj=%p dict=%p\n", frameobj, dict); if ( frameobj == NULL || !PyFrame_Check(frameobj) ) // check if frame tame { return NULL; } //printf("before dictcheck dict=%p\n", dict); if ( !PyDict_Check(dict) ) { return NULL; } //printf("allchecks ok\n"); frame = (PyFrameObject *) frameobj; if (PyDict_CheckExact(frame->f_locals)) { PyObject *oldLocals; //printf("set f_locals\n"); PyDict_Merge(dict, frame->f_locals, 1); // 1 - add reference to keys and values Py_INCREF(dict); oldLocals = frame->f_locals; frame->f_locals = dict; if (oldLocals != NULL) Py_DECREF( oldLocals ); } #if 0 if (PyDict_CheckExact(frame->f_globals)) { PyObject *oldLocals; PyDict_Merge(dict, frame->f_globals, 1); // 1 - add reference to keys and values Py_INCREF(dict); oldLocals = frame->f_globals; frame->f_globals = dict; if (oldLocals != NULL) Py_DECREF( oldLocals ); } #endif return Py_BuildValue("i", 0); }
// python_apply implements the function call: // (python-apply ("module.submodule" 'obj 'func) // (arg1 arg2 arg3) // (('keyword1 . val4) ('keyword2 . val5)) // sargtemplate // skwtemplate) // which is the basic way to invoke a Python function. // // sfunc specifies the function to be invoked. The possibilities // are: // String - denotes a top level function ("func" means __main__.func). // pysmob - assumed to be a callable object. // ("module.submodule" ...) - a List of strings/symbols/keywords // in which the first item must be a string denotes: // Module "module.submodule" (which should have already been imported // using python-import) // followed by name of object in that module, followed by attribute,..., // until the final callable attribute. // (pysmob ...) - a List starting with pysmob followed by // strings/symbols/keywords - processed similarly, except that the // pysmob stands for the module. // sarg is a list of arguments (in Python it's *arg) // skw is an alist (in Python it's **kw). // sargtemplate - specifies how to convert sarg - optional argument. // skwtemplate - specifies how to convert skw - optional argument. // srestemplate - specifies how to convert the result back into // SCM - optional argument. SCM python_apply(SCM sfunc, SCM sarg, SCM skw, SCM sargtemplate, SCM skwtemplate, SCM srestemplate) { PyObject *pfunc = NULL; PyObject *parg = NULL; PyObject *pkw = NULL; PyObject *pfuncobj = NULL; PyObject *pres = NULL; SCM sres = SCM_UNDEFINED; if (SCM_UNBNDP(sargtemplate)) { //(sargtemplate == SCM_UNDEFINED) // SCM_UNSPECIFIED sargtemplate = sargtemplate_default; } if (SCM_UNBNDP(skwtemplate)) { skwtemplate = skwtemplate_default; } if (SCM_UNBNDP(srestemplate)) { srestemplate = srestemplate_default; } // Retrieve the function object. pfunc = guile2python(sfunc,SCM_UNSPECIFIED); if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) { char *preprfunc = PyString_AsString(PyObject_Repr(pfunc)); scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded pfunc ~S\n"),scm_list_1(scm_makfrom0str(preprfunc))); } if (NULL == pfunc) { scm_misc_error("python-apply","conversion failure (~S)", scm_list_1(SCM_CDR(sfunc))); } // If it is a string, prepend it with "__main__". if (PyString_CheckExact(pfunc)) { // Convert it into a List of two items, to unify // subsequent treatment. PyObject *plist = PyList_New(2); if (NULL == plist) { Py_DECREF(pfunc); // NOT COVERED BY TESTS scm_memory_error("python-apply"); // NOT COVERED BY TESTS } if (-1 == PyList_SetItem(plist,0,PyString_FromString("__main__"))) { Py_DECREF(pfunc); // NOT COVERED BY TESTS Py_DECREF(plist); // NOT COVERED BY TESTS scm_misc_error("python-apply","PyList_SetItem 0 failure (~S)", // NOT COVERED BY TESTS scm_list_1(SCM_CAR(sfunc))); } if (-1 == PyList_SetItem(plist,1,pfunc)) { Py_DECREF(pfunc); // NOT COVERED BY TESTS Py_DECREF(plist); // NOT COVERED BY TESTS scm_misc_error("python-apply","PyList_SetItem 1 failure (~S)", // NOT COVERED BY TESTS scm_list_1(SCM_CAR(sfunc))); } pfunc = plist; // plist stole previous pfunc's value's reference. } else if (IS_PYSMOBP(sfunc)) { // We check the SCM object because guile2python() destroys // the indication whether the SCM was originally a pysmob, when it // converts it into PyObject. PyObject *plist1 = PyList_New(1); if (NULL == plist1) { Py_DECREF(pfunc); // NOT COVERED BY TESTS scm_memory_error("python-apply"); // NOT COVERED BY TESTS } if (-1 == PyList_SetItem(plist1,0,pfunc)) { Py_DECREF(pfunc); // NOT COVERED BY TESTS Py_DECREF(plist1); // NOT COVERED BY TESTS scm_misc_error("python-apply","PyList_SetItem 0 failure (~S)", // NOT COVERED BY TESTS scm_list_1(SCM_CAR(sfunc))); } pfunc = plist1; // plist1 stole previous pfunc's value's reference. // Now pfunc is an 1-member list, and this member is // expected to be callable. } else if (!PyList_CheckExact(pfunc)) { // Now, the qualified function name must be a proper list. scm_wrong_type_arg("python-apply",SCM_ARG1,sfunc); } if (1 > PyList_Size(pfunc)) { // The list must consist of at least one callable module name/object. scm_misc_error("python-apply", "first argument must contain at least one callable object (~S)", scm_list_1(SCM_CAR(sfunc))); } if (PyString_CheckExact(PyList_GetItem(pfunc,0))) { // If it is a string, we assume it to be the name of a module // which has already been imported. // Due to the existence of dots, // we don't allow it to be symbol or keyword. pfuncobj = PyImport_AddModule(PyString_AsString(PyList_GetItem(pfunc,0))); if (NULL == pfuncobj) { Py_DECREF(pfunc); scm_misc_error("python-apply", "module ~S could not be accessed - probably not imported", scm_list_1(SCM_CAR(sfunc))); } Py_INCREF(pfuncobj); } else { // We assume that it is a callable or object with attributes. pfuncobj = PyList_GetItem(pfunc,0); if (NULL == pfuncobj) { Py_DECREF(pfunc); scm_misc_error("python-apply", "could not access object starting ~S", scm_list_1(sfunc)); } Py_INCREF(pfuncobj); } // Here we dereference attributes (if any). int listsize = PyList_Size(pfunc); int ind; for (ind = 1; ind < listsize; ++ind) { PyObject *pnextobj = PyObject_GetAttr(pfuncobj,PyList_GetItem(pfunc,ind)); if (NULL == pnextobj) { PyObject *pexception = PyErr_Occurred(); Py_DECREF(pfunc); Py_DECREF(pfuncobj); if (pexception) { PyErr_Clear(); // An AttributeError exception is expected here. if (!PyErr_GivenExceptionMatches(pexception,PyExc_AttributeError)) { PyObject *prepr = PyObject_Repr(pexception); if (NULL == prepr) { scm_misc_error("python-apply", "python exception - could not be identified", SCM_UNSPECIFIED); } else { int strlength = PyString_Size(prepr); char *pstr = PyString_AsString(prepr); SCM srepr = scm_list_1(scm_mem2string(pstr,strlength)); Py_DECREF(prepr); scm_misc_error("python-apply", "Python exception (~A) while dereferencing object attribute", srepr); } } // else we got the expected AttributeError exception. } // else we got NULL==pnextobj without Python exception. scm_misc_error("python-apply", "could not dereference ~Ath level attribute in ~S", scm_list_2(scm_long2num(ind),sfunc)); } Py_INCREF(pnextobj); Py_DECREF(pfuncobj); pfuncobj = pnextobj; } Py_DECREF(pfunc); // We do not need it anymore. pfuncobj points at // the function actually to be invoked. if (!PyCallable_Check(pfuncobj)) { Py_DECREF(pfuncobj); scm_misc_error("python-apply","function denoted by ~S is not callable",scm_list_1(sfunc)); } if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) { char *preprfuncobj = PyString_AsString(PyObject_Repr(pfuncobj)); scm_simple_format(scm_current_output_port(), scm_makfrom0str("# python_apply: decoded function actually to be invoked: ~S\n"), scm_list_1(scm_makfrom0str(preprfuncobj))); } // Retrieve positional arguments parg = g2p_apply(sarg,sargtemplate); if (NULL == parg) { Py_DECREF(pfuncobj); scm_misc_error("python-apply","positional arguments conversion failure (~S)", scm_list_1(sarg)); } // Validate that it is indeed a tuple. if (!PyTuple_CheckExact(parg)) { Py_DECREF(pfuncobj); Py_DECREF(parg); scm_wrong_type_arg("python-apply",SCM_ARG2,sarg); } if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) { char *pposarg = PyString_AsString(PyObject_Repr(parg)); scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded positional arguments ~S\n"),scm_list_1(scm_makfrom0str(pposarg))); } // Retrieve keyword arguments. pkw = guileassoc2pythondict(skw,skwtemplate); if (NULL == pkw) { // Seems that PyDict_CheckExact() does not handle NULL argument gracefully. Py_DECREF(pfuncobj); Py_DECREF(parg); scm_misc_error("python-apply","keyword arguments conversion failure (~S)", scm_list_1(skw)); } if (!PyDict_CheckExact(pkw)) { Py_DECREF(pfuncobj); Py_DECREF(parg); Py_DECREF(pkw); scm_misc_error("python-apply", "keyword arguments (~S) not properly converted into Python Dict", scm_list_1(skw)); } if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) { char *pkwarg = PyString_AsString(PyObject_Repr(pkw)); scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded keyword arguments ~S\n"),scm_list_1(scm_makfrom0str(pkwarg))); } // Ready to invoke the function. pres = PyEval_CallObjectWithKeywords(pfuncobj,parg,pkw); PyObject *pexception = PyErr_Occurred(); if (pexception) { PyObject *prepr = PyObject_Repr(pexception); Py_DECREF(pfuncobj); Py_DECREF(parg); Py_DECREF(pkw); Py_XDECREF(pres); PyErr_Clear(); if (NULL == prepr) { scm_misc_error("python-apply", "python exception - could not be identified", SCM_UNSPECIFIED); } else { int strlength = PyString_Size(prepr); char *pstr = PyString_AsString(prepr); SCM srepr = scm_list_1(scm_mem2string(pstr,strlength)); Py_DECREF(prepr); scm_misc_error("python-apply","Python exception: ~A", srepr); } } if (NULL != pres) { sres = p2g_apply(pres,srestemplate); if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) { char *presstr = PyString_AsString(PyObject_Repr(pres)); scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: decoded results:\n# Python: ~S\n# Scheme: ~S\n"),scm_list_2(scm_makfrom0str(presstr),sres)); } } else { // else sres remains SCM_UNDEFINED. if (pyguile_verbosity_test(PYGUILE_VERBOSE_PYTHON_APPLY)) { scm_simple_format(scm_current_output_port(),scm_makfrom0str("# python_apply: Python code returned <NULL>\n"),SCM_EOL); } } return(sres); }