static PyArrayObject* array_from_pyobj(const int type_num, int *dims, const int rank, const int intent, PyObject *obj) { /* Note about reference counting ----------------------------- If the caller returns the array to Python, it must be done with Py_BuildValue("N",arr). Otherwise, if obj!=arr then the caller must call Py_DECREF(arr). */ /* f2py_show_args(type_num,dims,rank,intent); */ if (intent & F2PY_INTENT_CACHE) { /* Don't expect correct storage order or anything reasonable when returning cache array. */ if ((intent & F2PY_INTENT_HIDE) || (obj==Py_None)) { PyArrayObject *arr = NULL; CHECK_DIMS_DEFINED(rank,dims,"optional,intent(cache) must" " have defined dimensions.\n"); arr = (PyArrayObject *)PyArray_FromDims(rank,dims,type_num); ARR_IS_NULL(arr,"FromDims failed: optional,intent(cache)\n"); if (intent & F2PY_INTENT_OUT) Py_INCREF(arr); return arr; } if (PyArray_Check(obj) && ISCONTIGUOUS((PyArrayObject *)obj) && HAS_PROPER_ELSIZE((PyArrayObject *)obj,type_num) ) { if (check_and_fix_dimensions((PyArrayObject *)obj,rank,dims)) return NULL; /*XXX: set exception */ if (intent & F2PY_INTENT_OUT) Py_INCREF(obj); return (PyArrayObject *)obj; } ARR_IS_NULL(NULL,"intent(cache) must be contiguous array with a proper elsize.\n"); } if (intent & F2PY_INTENT_HIDE) { PyArrayObject *arr = NULL; CHECK_DIMS_DEFINED(rank,dims,"intent(hide) must have defined dimensions.\n"); arr = (PyArrayObject *)PyArray_FromDims(rank,dims,type_num); ARR_IS_NULL(arr,"FromDims failed: intent(hide)\n"); if (intent & F2PY_INTENT_OUT) { if ((!(intent & F2PY_INTENT_C)) && (rank>1)) { lazy_transpose(arr); arr->flags &= ~NPY_CONTIGUOUS; } Py_INCREF(arr); } return arr; } if (PyArray_Check(obj)) { /* here we have always intent(in) or intent(inout) */ PyArrayObject *arr = (PyArrayObject *)obj; int is_cont = (intent & F2PY_INTENT_C) ? (ISCONTIGUOUS(arr)) : (array_has_column_major_storage(arr)); if (check_and_fix_dimensions(arr,rank,dims)) return NULL; /*XXX: set exception */ if ((intent & F2PY_INTENT_COPY) || (! (is_cont && HAS_PROPER_ELSIZE(arr,type_num) && PyArray_CanCastSafely(arr->descr->type_num,type_num)))) { PyArrayObject *tmp_arr = NULL; if (intent & F2PY_INTENT_INOUT) { ARR_IS_NULL(NULL,"intent(inout) array must be contiguous and" " with a proper type and size.\n") } if ((rank>1) && (! (intent & F2PY_INTENT_C))) lazy_transpose(arr); if (PyArray_CanCastSafely(arr->descr->type_num,type_num)) { tmp_arr = (PyArrayObject *)PyArray_CopyFromObject(obj,type_num,0,0); ARR_IS_NULL(arr,"CopyFromObject failed: array.\n"); } else { tmp_arr = (PyArrayObject *)PyArray_FromDims(arr->nd, arr->dimensions, type_num); ARR_IS_NULL(tmp_arr,"FromDims failed: array with unsafe cast.\n"); if (copy_ND_array(arr,tmp_arr)) ARR_IS_NULL(NULL,"copy_ND_array failed: array with unsafe cast.\n"); } if ((rank>1) && (! (intent & F2PY_INTENT_C))) { lazy_transpose(arr); lazy_transpose(tmp_arr); tmp_arr->flags &= ~NPY_CONTIGUOUS; } arr = tmp_arr; } if (intent & F2PY_INTENT_OUT) Py_INCREF(arr); return arr; }
static double* coerce_ndarray_double(PyArrayObject *in, PyArrayObject **out) { int pcm_type = PyArray_TYPE(in); if (pcm_type==NPY_DOUBLE) return ((double *) PyArray_DATA(in)); else if (PyArray_CanCastSafely(pcm_type, NPY_DOUBLE)) { *out = (PyArrayObject*)PyArray_Cast(in, NPY_DOUBLE); return ((double *) PyArray_DATA(*out)); } else return NULL; }