static int Py_FilterFunc(double *buffer, npy_intp filter_size, double *output, void *data) { PyArrayObject *py_buffer = NULL; PyObject *rv = NULL, *args = NULL, *tmp = NULL; NI_PythonCallbackData *cbdata = (NI_PythonCallbackData*)data; py_buffer = NA_NewArray(buffer, PyArray_DOUBLE, 1, &filter_size); if (!py_buffer) goto exit; tmp = Py_BuildValue("(O)", py_buffer); if (!tmp) goto exit; args = PySequence_Concat(tmp, cbdata->extra_arguments); if (!args) goto exit; rv = PyObject_Call(cbdata->function, args, cbdata->extra_keywords); if (!rv) goto exit; *output = PyFloat_AsDouble(rv); exit: Py_XDECREF(py_buffer); Py_XDECREF(rv); Py_XDECREF(args); Py_XDECREF(tmp); return PyErr_Occurred() ? 0 : 1; }
static int Py_Filter1DFunc(double *iline, npy_intp ilen, double *oline, npy_intp olen, void *data) { PyArrayObject *py_ibuffer = NULL, *py_obuffer = NULL; PyObject *rv = NULL, *args = NULL, *tmp = NULL; npy_intp ii; double *po = NULL; NI_PythonCallbackData *cbdata = (NI_PythonCallbackData*)data; py_ibuffer = NA_NewArray(iline, PyArray_DOUBLE, 1, &ilen); py_obuffer = NA_NewArray(NULL, PyArray_DOUBLE, 1, &olen); if (!py_ibuffer || !py_obuffer) goto exit; tmp = Py_BuildValue("(OO)", py_ibuffer, py_obuffer); if (!tmp) goto exit; args = PySequence_Concat(tmp, cbdata->extra_arguments); if (!args) goto exit; rv = PyObject_Call(cbdata->function, args, cbdata->extra_keywords); if (!rv) goto exit; po = (double*)PyArray_DATA(py_obuffer); for(ii = 0; ii < olen; ii++) oline[ii] = po[ii]; exit: Py_XDECREF(py_ibuffer); Py_XDECREF(py_obuffer); Py_XDECREF(rv); Py_XDECREF(args); Py_XDECREF(tmp); return PyErr_Occurred() ? 0 : 1; }
static PyObject * structseq_concat(PyStructSequence *obj, PyObject *b) { PyObject *tup, *result; tup = make_tuple(obj); result = PySequence_Concat(tup, b); Py_DECREF(tup); return result; }
PyObject * SWIG_AppendResult(PyObject * result, PyObject ** to_add, int num){ if ((!result) || (result == Py_None)) { /* no other results, so just add our values */ /* if only one object, return that */ if(num==1){ return to_add[0]; } /* create a new tuple to put in our new pointer python objects */ result = PyTuple_New (num); /* put in our new pointer python objects */ for(int i=0; i<num; i++){ PyTuple_SetItem (result, i, to_add[i]); } } else { /* we have other results, so add it to the end */ if (!PyTuple_Check (result)) { /* previous result is not a tuple, so create one and put previous result and current pointer in it */ /* first, save previous result */ PyObject *obj_save = result; /* then, create the tuple */ result = PyTuple_New (1); /* finaly, put the saved value in the tuple */ PyTuple_SetItem (result, 0, obj_save); } /* create a new tuple to put in our new pointer python object */ PyObject *my_obj = PyTuple_New (num); /* put in our new pointer python object */ for( int i=0; i<num ; i++ ){ PyTuple_SetItem (my_obj, i, to_add[i]); } /* save the previous result */ PyObject *obj_save = result; /* concat previous and our new result */ result = PySequence_Concat (obj_save, my_obj); /* decrement the usage of no more used objects */ Py_DECREF (obj_save); Py_DECREF (my_obj); } return result; }
static PyObject *t_sequence_seq_concat(t_sequence *self, PyObject *arg) { if (self->itemvalue.flags & V_PURE) return PySequence_Concat(self->sequence, arg); else { int size = PySequence_Size(self->sequence); PyObject *values, *result; if (size < 0) return NULL; values = t_sequence_seq_getslice(self, 0, size); if (!values) return NULL; result = PySequence_Concat(values, arg); Py_DECREF(values); return result; } }
static PyObject * partial_call_impl(partialobject *pto, PyObject *args, PyObject *kwargs) { PyObject *ret, *args2; /* Note: tupleconcat() is optimized for empty tuples */ args2 = PySequence_Concat(pto->args, args); if (args2 == NULL) { return NULL; } assert(PyTuple_Check(args2)); ret = PyObject_Call(pto->fn, args2, kwargs); Py_DECREF(args2); return ret; }
static gboolean marshal_emission_hook(GSignalInvocationHint *ihint, guint n_param_values, const GValue *param_values, gpointer user_data) { PyGILState_STATE state; gboolean retval = FALSE; PyObject *func, *args; PyObject *retobj; PyObject *params; guint i; state = pyg_gil_state_ensure(); /* construct Python tuple for the parameter values */ params = PyTuple_New(n_param_values); for (i = 0; i < n_param_values; i++) { PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); /* error condition */ if (!item) { goto out; } PyTuple_SetItem(params, i, item); } args = (PyObject *)user_data; func = PyTuple_GetItem(args, 0); args = PySequence_Concat(params, PyTuple_GetItem(args, 1)); Py_DECREF(params); /* params passed to function may have extra arguments */ retobj = PyObject_CallObject(func, args); Py_DECREF(args); if (retobj == NULL) { PyErr_Print(); } retval = (retobj == Py_True ? TRUE : FALSE); Py_XDECREF(retobj); out: pyg_gil_state_release(state); return retval; }
static PyObject * partial_call(partialobject *pto, PyObject *args, PyObject *kw) { PyObject *ret; PyObject *argappl, *kwappl; assert (PyCallable_Check(pto->fn)); assert (PyTuple_Check(pto->args)); assert (PyDict_Check(pto->kw)); if (PyTuple_GET_SIZE(pto->args) == 0) { argappl = args; Py_INCREF(args); } else if (PyTuple_GET_SIZE(args) == 0) { argappl = pto->args; Py_INCREF(pto->args); } else { argappl = PySequence_Concat(pto->args, args); if (argappl == NULL) return NULL; assert(PyTuple_Check(argappl)); } if (PyDict_Size(pto->kw) == 0) { kwappl = kw; Py_XINCREF(kwappl); } else { kwappl = PyDict_Copy(pto->kw); if (kwappl == NULL) { Py_DECREF(argappl); return NULL; } if (kw != NULL) { if (PyDict_Merge(kwappl, kw, 1) != 0) { Py_DECREF(argappl); Py_DECREF(kwappl); return NULL; } } } ret = PyObject_Call(pto->fn, argappl, kwappl); Py_DECREF(argappl); Py_XDECREF(kwappl); return ret; }
static int Py_Map(npy_intp *ocoor, double* icoor, int orank, int irank, void *data) { PyObject *coors = NULL, *rets = NULL, *args = NULL, *tmp = NULL; npy_intp ii; NI_PythonCallbackData *cbdata = (NI_PythonCallbackData*)data; coors = PyTuple_New(orank); if (!coors) goto exit; for(ii = 0; ii < orank; ii++) { #if PY_VERSION_HEX < 0x02060000 PyTuple_SetItem(coors, ii, PyLong_FromLong(ocoor[ii])); #else PyTuple_SetItem(coors, ii, PyLong_FromSsize_t(ocoor[ii])); #endif if (PyErr_Occurred()) goto exit; } tmp = Py_BuildValue("(O)", coors); if (!tmp) goto exit; args = PySequence_Concat(tmp, cbdata->extra_arguments); if (!args) goto exit; rets = PyObject_Call(cbdata->function, args, cbdata->extra_keywords); if (!rets) goto exit; for(ii = 0; ii < irank; ii++) { icoor[ii] = PyFloat_AsDouble(PyTuple_GetItem(rets, ii)); if (PyErr_Occurred()) goto exit; } exit: Py_XDECREF(coors); Py_XDECREF(tmp); Py_XDECREF(rets); Py_XDECREF(args); return PyErr_Occurred() ? 0 : 1; }
int ode_jacobian_function(int *n, double *t, double *y, int *ml, int *mu, double *pd, int *nrowpd) { /* This is the function called from the Fortran code it should -- use call_python_function to get a multiarrayobject result -- check for errors and return -1 if any (though this is ignored by calling program). -- otherwise place result of calculation in pd */ PyArrayObject *result_array; PyObject *arglist, *arg1; int ndim, nrows, ncols, dim_error; npy_intp *dims; /* Append t to argument list */ if ((arg1 = PyTuple_New(1)) == NULL) { *n = -1; return -1; } PyTuple_SET_ITEM(arg1, 0, PyFloat_FromDouble(*t)); /* arg1 now owns newly created reference */ if ((arglist = PySequence_Concat(arg1, global_params.extra_arguments)) == NULL) { *n = -1; Py_DECREF(arg1); return -1; } Py_DECREF(arg1); /* arglist has reference */ result_array = (PyArrayObject *)call_python_function(global_params.python_jacobian, *n, y, arglist, odepack_error); if (result_array == NULL) { *n = -1; Py_DECREF(arglist); return -1; } ncols = *n; if (global_params.jac_type == 4) { nrows = *ml + *mu + 1; } else { nrows = *n; } if (!global_params.jac_transpose) { int tmp; tmp = nrows; nrows = ncols; ncols = tmp; } ndim = PyArray_NDIM(result_array); if (ndim > 2) { PyErr_Format(PyExc_RuntimeError, "The Jacobian array must be two dimensional, but got ndim=%d.", ndim); *n = -1; Py_DECREF(arglist); Py_DECREF(result_array); return -1; } dims = PyArray_DIMS(result_array); dim_error = 0; if (ndim == 0) { if ((nrows != 1) || (ncols != 1)) { dim_error = 1; } } if (ndim == 1) { if ((nrows != 1) || (dims[0] != ncols)) { dim_error = 1; } } if (ndim == 2) { if ((dims[0] != nrows) || (dims[1] != ncols)) { dim_error = 1; } } if (dim_error) { char *b = ""; if (global_params.jac_type == 4) { b = "banded "; } PyErr_Format(PyExc_RuntimeError, "Expected a %sJacobian array with shape (%d, %d)", b, nrows, ncols); *n = -1; Py_DECREF(arglist); Py_DECREF(result_array); return -1; } /* * global_params.jac_type is either 1 (full Jacobian) or 4 (banded Jacobian). * global_params.jac_transpose is !col_deriv, so if global_params.jac_transpose * is 0, the array created by the user is already in Fortran order, and * a transpose is not needed when it is copied to pd. */ if ((global_params.jac_type == 1) && !global_params.jac_transpose) { /* Full Jacobian, no transpose needed, so we can use memcpy. */ memcpy(pd, PyArray_DATA(result_array), (*n)*(*nrowpd)*sizeof(double)); } else { /* * global_params.jac_type == 4 (banded Jacobian), or * global_params.jac_type == 1 and global_params.jac_transpose == 1. * * We can't use memcpy when global_params.jac_type is 4 because the leading * dimension of pd doesn't necessarily equal the number of rows of the * matrix. */ int m; /* Number of rows in the (full or packed banded) Jacobian. */ if (global_params.jac_type == 4) { m = *ml + *mu + 1; } else { m = *n; } copy_array_to_fortran(pd, *nrowpd, m, *n, (double *) PyArray_DATA(result_array), !global_params.jac_transpose); } Py_DECREF(arglist); Py_DECREF(result_array); return 0; }
Sequence Sequence::operator+(const Sequence &rhs) const { return Sequence(NewReference(PySequence_Concat(mPtr, rhs.borrowReference()))); }
List List::operator+(const List &rhs) { return List(NewReference(PySequence_Concat(mPtr, rhs.borrowReference()))); }
static PyObject * partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) { PyObject *func, *pargs, *nargs, *pkw; partialobject *pto; if (PyTuple_GET_SIZE(args) < 1) { PyErr_SetString(PyExc_TypeError, "type 'partial' takes at least one argument"); return NULL; } pargs = pkw = NULL; func = PyTuple_GET_ITEM(args, 0); if (Py_TYPE(func) == &partial_type && type == &partial_type) { partialobject *part = (partialobject *)func; if (part->dict == NULL) { pargs = part->args; pkw = part->kw; func = part->fn; assert(PyTuple_Check(pargs)); assert(PyDict_Check(pkw)); } } if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "the first argument must be callable"); return NULL; } /* create partialobject structure */ pto = (partialobject *)type->tp_alloc(type, 0); if (pto == NULL) return NULL; pto->fn = func; Py_INCREF(func); nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX); if (nargs == NULL) { Py_DECREF(pto); return NULL; } if (pargs == NULL || PyTuple_GET_SIZE(pargs) == 0) { pto->args = nargs; Py_INCREF(nargs); } else if (PyTuple_GET_SIZE(nargs) == 0) { pto->args = pargs; Py_INCREF(pargs); } else { pto->args = PySequence_Concat(pargs, nargs); if (pto->args == NULL) { Py_DECREF(nargs); Py_DECREF(pto); return NULL; } assert(PyTuple_Check(pto->args)); } Py_DECREF(nargs); if (pkw == NULL || PyDict_GET_SIZE(pkw) == 0) { if (kw == NULL) { pto->kw = PyDict_New(); } else { Py_INCREF(kw); pto->kw = kw; } } else { pto->kw = PyDict_Copy(pkw); if (kw != NULL && pto->kw != NULL) { if (PyDict_Merge(pto->kw, kw, 1) != 0) { Py_DECREF(pto); return NULL; } } } if (pto->kw == NULL) { Py_DECREF(pto); return NULL; } return (PyObject *)pto; }
static PyObject * partial_call(partialobject *pto, PyObject *args, PyObject *kw) { PyObject *ret; PyObject *argappl, *kwappl; PyObject **stack; Py_ssize_t nargs; assert (PyCallable_Check(pto->fn)); assert (PyTuple_Check(pto->args)); assert (PyDict_Check(pto->kw)); if (PyTuple_GET_SIZE(pto->args) == 0) { stack = &PyTuple_GET_ITEM(args, 0); nargs = PyTuple_GET_SIZE(args); argappl = NULL; } else if (PyTuple_GET_SIZE(args) == 0) { stack = &PyTuple_GET_ITEM(pto->args, 0); nargs = PyTuple_GET_SIZE(pto->args); argappl = NULL; } else { stack = NULL; argappl = PySequence_Concat(pto->args, args); if (argappl == NULL) { return NULL; } assert(PyTuple_Check(argappl)); } if (PyDict_GET_SIZE(pto->kw) == 0) { kwappl = kw; Py_XINCREF(kwappl); } else { kwappl = PyDict_Copy(pto->kw); if (kwappl == NULL) { Py_XDECREF(argappl); return NULL; } if (kw != NULL) { if (PyDict_Merge(kwappl, kw, 1) != 0) { Py_XDECREF(argappl); Py_DECREF(kwappl); return NULL; } } } if (stack) { ret = _PyObject_FastCallDict(pto->fn, stack, nargs, kwappl); } else { ret = PyObject_Call(pto->fn, argappl, kwappl); Py_DECREF(argappl); } Py_XDECREF(kwappl); return ret; }
static void pyg_closure_marshal(GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { PyGILState_STATE state; PyGClosure *pc = (PyGClosure *)closure; PyObject *params, *ret; guint i; state = pyglib_gil_state_ensure(); /* construct Python tuple for the parameter values */ params = PyTuple_New(n_param_values); for (i = 0; i < n_param_values; i++) { /* swap in a different initial data for connect_object() */ if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) { g_return_if_fail(pc->swap_data != NULL); Py_INCREF(pc->swap_data); PyTuple_SetItem(params, 0, pc->swap_data); } else { PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); /* error condition */ if (!item) { if (!PyErr_Occurred ()) PyErr_SetString (PyExc_TypeError, "can't convert parameter to desired type"); if (pc->exception_handler) pc->exception_handler (return_value, n_param_values, param_values); else PyErr_Print(); goto out; } PyTuple_SetItem(params, i, item); } } /* params passed to function may have extra arguments */ if (pc->extra_args) { PyObject *tuple = params; params = PySequence_Concat(tuple, pc->extra_args); Py_DECREF(tuple); } ret = PyObject_CallObject(pc->callback, params); if (ret == NULL) { if (pc->exception_handler) pc->exception_handler(return_value, n_param_values, param_values); else PyErr_Print(); goto out; } if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) { /* If we already have an exception set, use that, otherwise set a * generic one */ if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "can't convert return value to desired type"); if (pc->exception_handler) pc->exception_handler(return_value, n_param_values, param_values); else PyErr_Print(); } Py_DECREF(ret); out: Py_DECREF(params); pyglib_gil_state_release(state); }
/* callback to pass to DODRC; calls the Python function in the global structure |odr_global| */ void fcn_callback(int *n, int *m, int *np, int *nq, int *ldn, int *ldm, int *ldnp, double *beta, double *xplusd, int *ifixb, int *ifixx, int *ldfix, int *ideval, double *f, double *fjacb, double *fjacd, int *istop) { PyObject *arg01, *arglist; PyObject *result; PyArrayObject *result_array = NULL; PyArrayObject *pyXplusD; arg01 = PyTuple_New(2); if (*m != 1) { npy_intp dim2[2]; dim2[0] = *m; dim2[1] = *n; pyXplusD = (PyArrayObject *) PyArray_SimpleNew(2, dim2, NPY_DOUBLE); memcpy(pyXplusD->data, (void *)xplusd, (*m) * (*n) * sizeof(double)); } else { npy_intp dim1[1]; dim1[0] = *n; pyXplusD = (PyArrayObject *) PyArray_SimpleNew(1, dim1, NPY_DOUBLE); memcpy(pyXplusD->data, (void *)xplusd, (*n) * sizeof(double)); } PyTuple_SetItem(arg01, 0, odr_global.pyBeta); Py_INCREF(odr_global.pyBeta); PyTuple_SetItem(arg01, 1, (PyObject *) pyXplusD); Py_INCREF((PyObject *) pyXplusD); if (odr_global.extra_args != NULL) { arglist = PySequence_Concat(arg01, odr_global.extra_args); } else { arglist = PySequence_Tuple(arg01); /* make a copy */ } Py_DECREF(arg01); *istop = 0; memcpy(((PyArrayObject *) (odr_global.pyBeta))->data, (void *)beta, (*np) * sizeof(double)); if ((*ideval % 10) >= 1) { /* compute f with odr_global.fcn */ if (odr_global.fcn == NULL) { /* we don't have a function to call */ PYERR2(odr_error, "Function has not been initialized"); } if ((result = PyEval_CallObject(odr_global.fcn, arglist)) == NULL) { PyObject *tmpobj, *str1; if (PyErr_ExceptionMatches(odr_stop)) { /* stop, don't fail */ *istop = 1; Py_DECREF(arglist); return; } PyErr_Print(); tmpobj = PyObject_GetAttrString(odr_global.fcn, "func_name"); if (tmpobj == NULL) goto fail; str1 = PyString_FromString ("Error occurred while calling the Python function named "); if (str1 == NULL) { Py_DECREF(tmpobj); goto fail; } PyString_ConcatAndDel(&str1, tmpobj); PyErr_SetString(odr_error, PyString_AsString(str1)); Py_DECREF(str1); goto fail; } if ((result_array = (PyArrayObject *) PyArray_ContiguousFromObject(result, NPY_DOUBLE, 0, 2)) == NULL) { PYERR2(odr_error, "Result from function call is not a proper array of floats."); } memcpy((void *)f, result_array->data, (*n) * (*nq) * sizeof(double)); Py_DECREF(result_array); } if (((*ideval) / 10) % 10 >= 1) { /* compute fjacb with odr_global.fjacb */ if (odr_global.fjacb == NULL) { /* we don't have a function to call */ PYERR2(odr_error, "Function has not been initialized"); } if ((result = PyEval_CallObject(odr_global.fjacb, arglist)) == NULL) { PyObject *tmpobj, *str1; if (PyErr_ExceptionMatches(odr_stop)) { /* stop, don't fail */ *istop = 1; Py_DECREF(arglist); return; } PyErr_Print(); tmpobj = PyObject_GetAttrString(odr_global.fjacb, "func_name"); if (tmpobj == NULL) goto fail; str1 = PyString_FromString ("Error occurred while calling the Python function named "); if (str1 == NULL) { Py_DECREF(tmpobj); goto fail; } PyString_ConcatAndDel(&str1, tmpobj); PyErr_SetString(odr_error, PyString_AsString(str1)); Py_DECREF(str1); goto fail; } if ((result_array = (PyArrayObject *) PyArray_ContiguousFromObject(result, NPY_DOUBLE, 0, 2)) == NULL) { PYERR2(odr_error, "Result from function call is not a proper array of floats."); } if (*nq != 1 && *np != 1) { /* result_array should be rank-3 */ if (result_array->nd != 3) { Py_DECREF(result_array); PYERR2(odr_error, "Beta Jacobian is not rank-3"); } } else if (*nq == 1) { /* result_array should be rank-2 */ if (result_array->nd != 2) { Py_DECREF(result_array); PYERR2(odr_error, "Beta Jacobian is not rank-2"); } } memcpy((void *)fjacb, result_array->data, (*n) * (*nq) * (*np) * sizeof(double)); Py_DECREF(result_array); } if (((*ideval) / 100) % 10 >= 1) { /* compute fjacd with odr_global.fjacd */ if (odr_global.fjacd == NULL) { /* we don't have a function to call */ PYERR2(odr_error, "fjcad has not been initialized"); } if ((result = PyEval_CallObject(odr_global.fjacd, arglist)) == NULL) { PyObject *tmpobj, *str1; if (PyErr_ExceptionMatches(odr_stop)) { /* stop, don't fail */ *istop = 1; Py_DECREF(arglist); return; } PyErr_Print(); tmpobj = PyObject_GetAttrString(odr_global.fjacd, "func_name"); if (tmpobj == NULL) goto fail; str1 = PyString_FromString ("Error occurred while calling the Python function named "); if (str1 == NULL) { Py_DECREF(tmpobj); goto fail; } PyString_ConcatAndDel(&str1, tmpobj); PyErr_SetString(odr_error, PyString_AsString(str1)); Py_DECREF(str1); goto fail; } if ((result_array = (PyArrayObject *) PyArray_ContiguousFromObject(result, NPY_DOUBLE, 0, 2)) == NULL) { PYERR2(odr_error, "Result from function call is not a proper array of floats."); } if (*nq != 1 && *m != 1) { /* result_array should be rank-3 */ if (result_array->nd != 3) { Py_DECREF(result_array); PYERR2(odr_error, "xplusd Jacobian is not rank-3"); } } else if (*nq == 1 && *m != 1) { /* result_array should be rank-2 */ if (result_array->nd != 2) { Py_DECREF(result_array); PYERR2(odr_error, "xplusd Jacobian is not rank-2"); } } else if (*nq == 1 && *m == 1) { /* result_array should be rank-1 */ if (result_array->nd != 1) { Py_DECREF(result_array); PYERR2(odr_error, "xplusd Jacobian is not rank-1"); } } memcpy((void *)fjacd, result_array->data, (*n) * (*nq) * (*m) * sizeof(double)); Py_DECREF(result_array); } Py_DECREF(result); Py_DECREF(arglist); Py_DECREF(pyXplusD); return; fail: Py_XDECREF(result); Py_XDECREF(arglist); Py_XDECREF(pyXplusD); *istop = -1; return; }
static PyObject *call_python_function(PyObject *func, npy_intp n, double *x, PyObject *args, PyObject *error_obj) { /* This is a generic function to call a python function that takes a 1-D sequence as a first argument and optional extra_arguments (should be a zero-length tuple if none desired). The result of the function is returned in a multiarray object. -- build sequence object from values in x. -- add extra arguments (if any) to an argument list. -- call Python callable object -- check if error occurred: if so return NULL -- if no error, place result of Python code into multiarray object. */ PyArrayObject *sequence = NULL; PyObject *arglist = NULL; PyObject *arg1 = NULL; PyObject *result = NULL; PyArrayObject *result_array = NULL; /* Build sequence argument from inputs */ sequence = (PyArrayObject *) PyArray_SimpleNewFromData(1, &n, NPY_DOUBLE, (char *) x); if (sequence == NULL) { goto fail; } /* Build argument list */ if ((arg1 = PyTuple_New(1)) == NULL) { Py_DECREF(sequence); return NULL; } PyTuple_SET_ITEM(arg1, 0, (PyObject *)sequence); /* arg1 now owns sequence reference */ if ((arglist = PySequence_Concat(arg1, args)) == NULL) { goto fail; } Py_DECREF(arg1); /* arglist has a reference to sequence, now. */ arg1 = NULL; /* * Call function object --- variable passed to routine. Extra * arguments are in another passed variable. */ if ((result = PyEval_CallObject(func, arglist))==NULL) { goto fail; } result_array = (PyArrayObject *) PyArray_ContiguousFromObject(result, NPY_DOUBLE, 0, 0); if (result_array == NULL) { goto fail; } Py_DECREF(result); Py_DECREF(arglist); return (PyObject *) result_array; fail: Py_XDECREF(arglist); Py_XDECREF(result); Py_XDECREF(arg1); return NULL; }
void ode_function(int *n, double *t, double *y, double *ydot) { /* This is the function called from the Fortran code it should -- use call_python_function to get a multiarrayobject result -- check for errors and set *n to -1 if any -- otherwise place result of calculation in ydot */ PyArrayObject *result_array = NULL; PyObject *arg1, *arglist; /* Append t to argument list */ if ((arg1 = PyTuple_New(1)) == NULL) { *n = -1; return; } PyTuple_SET_ITEM(arg1, 0, PyFloat_FromDouble(*t)); /* arg1 now owns newly created reference */ if ((arglist = PySequence_Concat(arg1, global_params.extra_arguments)) == NULL) { *n = -1; Py_DECREF(arg1); return; } Py_DECREF(arg1); /* arglist has reference */ result_array = (PyArrayObject *)call_python_function(global_params.python_function, *n, y, arglist, odepack_error); if (result_array == NULL) { *n = -1; Py_DECREF(arglist); return; } if (PyArray_NDIM(result_array) > 1) { *n = -1; PyErr_Format(PyExc_RuntimeError, "The array return by func must be one-dimensional, but got ndim=%d.", PyArray_NDIM(result_array)); Py_DECREF(arglist); Py_DECREF(result_array); return; } if (PyArray_Size((PyObject *)result_array) != *n) { PyErr_Format(PyExc_RuntimeError, "The size of the array returned by func (%ld) does not match " "the size of y0 (%d).", PyArray_Size((PyObject *)result_array), *n); *n = -1; Py_DECREF(arglist); Py_DECREF(result_array); return; } memcpy(ydot, PyArray_DATA(result_array), (*n)*sizeof(double)); Py_DECREF(result_array); Py_DECREF(arglist); return; }
static void pygi_signal_closure_marshal(GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { PyGILState_STATE state; PyGClosure *pc = (PyGClosure *)closure; PyObject *params, *ret = NULL; guint i; GISignalInfo *signal_info; gint n_sig_info_args; gint sig_info_highest_arg; GSList *list_item = NULL; GSList *pass_by_ref_structs = NULL; state = PyGILState_Ensure(); signal_info = ((PyGISignalClosure *)closure)->signal_info; n_sig_info_args = g_callable_info_get_n_args(signal_info); /* the first argument to a signal callback is instance, but instance is not counted in the introspection data */ sig_info_highest_arg = n_sig_info_args + 1; g_assert_cmpint(sig_info_highest_arg, ==, n_param_values); /* construct Python tuple for the parameter values */ params = PyTuple_New(n_param_values); for (i = 0; i < n_param_values; i++) { /* swap in a different initial data for connect_object() */ if (i == 0 && G_CCLOSURE_SWAP_DATA(closure)) { g_return_if_fail(pc->swap_data != NULL); Py_INCREF(pc->swap_data); PyTuple_SetItem(params, 0, pc->swap_data); } else if (i == 0) { PyObject *item = pyg_value_as_pyobject(¶m_values[i], FALSE); if (!item) { goto out; } PyTuple_SetItem(params, i, item); } else if (i < sig_info_highest_arg) { GIArgInfo arg_info; GITypeInfo type_info; GITypeTag type_tag; GIArgument arg = { 0, }; PyObject *item = NULL; gboolean free_array = FALSE; gboolean pass_struct_by_ref = FALSE; g_callable_info_load_arg(signal_info, i - 1, &arg_info); g_arg_info_load_type(&arg_info, &type_info); arg = _pygi_argument_from_g_value(¶m_values[i], &type_info); type_tag = g_type_info_get_tag (&type_info); if (type_tag == GI_TYPE_TAG_ARRAY) { /* Skip the self argument of param_values */ arg.v_pointer = _pygi_argument_to_array (&arg, _pygi_argument_array_length_marshal, (void *)(param_values + 1), signal_info, &type_info, &free_array); } /* Hack to ensure struct arguments are passed-by-reference allowing * callback implementors to modify the struct values. This is needed * for keeping backwards compatibility and should be removed in future * versions which support signal output arguments as return values. * See: https://bugzilla.gnome.org/show_bug.cgi?id=735486 * * Note the logic here must match the logic path taken in _pygi_argument_to_object. */ if (type_tag == GI_TYPE_TAG_INTERFACE) { GIBaseInfo *info = g_type_info_get_interface (&type_info); GIInfoType info_type = g_base_info_get_type (info); if (info_type == GI_INFO_TYPE_STRUCT || info_type == GI_INFO_TYPE_BOXED || info_type == GI_INFO_TYPE_UNION) { GType gtype = g_registered_type_info_get_g_type ((GIRegisteredTypeInfo *) info); gboolean is_foreign = (info_type == GI_INFO_TYPE_STRUCT) && (g_struct_info_is_foreign ((GIStructInfo *) info)); if (!is_foreign && !g_type_is_a (gtype, G_TYPE_VALUE) && g_type_is_a (gtype, G_TYPE_BOXED)) { pass_struct_by_ref = TRUE; } } g_base_info_unref (info); } if (pass_struct_by_ref) { /* transfer everything will ensure the struct is not copied when wrapped. */ item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_EVERYTHING); if (item && PyObject_IsInstance (item, (PyObject *) &PyGIBoxed_Type)) { ((PyGBoxed *)item)->free_on_dealloc = FALSE; pass_by_ref_structs = g_slist_prepend (pass_by_ref_structs, item); } } else { item = _pygi_argument_to_object (&arg, &type_info, GI_TRANSFER_NOTHING); } if (free_array) { g_array_free (arg.v_pointer, FALSE); } if (item == NULL) { PyErr_Print (); goto out; } PyTuple_SetItem(params, i, item); } } /* params passed to function may have extra arguments */ if (pc->extra_args) { PyObject *tuple = params; params = PySequence_Concat(tuple, pc->extra_args); Py_DECREF(tuple); } ret = PyObject_CallObject(pc->callback, params); if (ret == NULL) { if (pc->exception_handler) pc->exception_handler(return_value, n_param_values, param_values); else PyErr_Print(); goto out; } if (G_IS_VALUE(return_value) && pyg_value_from_pyobject(return_value, ret) != 0) { PyErr_SetString(PyExc_TypeError, "can't convert return value to desired type"); if (pc->exception_handler) pc->exception_handler(return_value, n_param_values, param_values); else PyErr_Print(); } Py_DECREF(ret); /* Run through the list of structs which have been passed by reference and * check if they are being held longer than the duration of the callback * execution. This is determined if the ref count is greater than 1. * A single ref is held by the argument list and any more would mean the callback * stored a ref somewhere else. In this case we make an internal copy of * the boxed struct so Python can own the memory to it. */ list_item = pass_by_ref_structs; while (list_item) { PyObject *item = list_item->data; if (item->ob_refcnt > 1) { _pygi_boxed_copy_in_place ((PyGIBoxed *)item); } list_item = g_slist_next (list_item); } out: g_slist_free (pass_by_ref_structs); Py_DECREF(params); PyGILState_Release(state); }