Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
    }
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
Archivo: _kiwi.c Proyecto: Schevo/kiwi
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(&param_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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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())));
 }
Ejemplo n.º 12
0
 List List::operator+(const List &rhs)
 {
     return List(NewReference(PySequence_Concat(mPtr, rhs.borrowReference())));
 }
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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(&param_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);
}
Ejemplo n.º 16
0
/* 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;
}
Ejemplo n.º 17
0
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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(&param_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(&param_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);
}