static PyObject *Py_GeometricTransform(PyObject *obj, PyObject *args) { PyArrayObject *input = NULL, *output = NULL; PyArrayObject *coordinates = NULL, *matrix = NULL, *shift = NULL; PyObject *fnc = NULL, *extra_arguments = NULL, *extra_keywords = NULL; int mode, order; double cval; void *func = NULL, *data = NULL; NI_PythonCallbackData cbdata; if (!PyArg_ParseTuple(args, "O&OO&O&O&O&iidOO", NI_ObjectToInputArray, &input, &fnc, NI_ObjectToOptionalInputArray, &coordinates, NI_ObjectToOptionalInputArray, &matrix, NI_ObjectToOptionalInputArray, &shift, NI_ObjectToOutputArray, &output, &order, &mode, &cval, &extra_arguments, &extra_keywords)) goto exit; if (fnc != Py_None) { if (!PyTuple_Check(extra_arguments)) { PyErr_SetString(PyExc_RuntimeError, "extra_arguments must be a tuple"); goto exit; } if (!PyDict_Check(extra_keywords)) { PyErr_SetString(PyExc_RuntimeError, "extra_keywords must be a dictionary"); goto exit; } if (NpyCapsule_Check(fnc)) { func = NpyCapsule_AsVoidPtr(fnc); data = NpyCapsule_GetDesc(fnc); } else if (PyCallable_Check(fnc)) { func = Py_Map; cbdata.function = fnc; cbdata.extra_arguments = extra_arguments; cbdata.extra_keywords = extra_keywords; data = (void*)&cbdata; } else { PyErr_SetString(PyExc_RuntimeError, "function parameter is not callable"); goto exit; } } if (!NI_GeometricTransform(input, func, data, matrix, shift, coordinates, output, order, (NI_ExtendMode)mode, cval)) goto exit; exit: Py_XDECREF(input); Py_XDECREF(output); Py_XDECREF(coordinates); Py_XDECREF(matrix); Py_XDECREF(shift); return PyErr_Occurred() ? NULL : Py_BuildValue(""); }
static PyObject *Py_BinaryErosion2(PyObject *obj, PyObject *args) { PyArrayObject *array = NULL, *strct = NULL, *mask = NULL; PyObject *cobj = NULL; int invert, niter; npy_intp *origins = NULL; if (!PyArg_ParseTuple(args, "O&O&O&iO&iO", NI_ObjectToIoArray, &array, NI_ObjectToInputArray, &strct, NI_ObjectToOptionalInputArray, &mask, &niter, NI_ObjectToLongSequence, &origins, &invert, &cobj)) goto exit; if (NpyCapsule_Check(cobj)) { NI_CoordinateList *cobj_data = NpyCapsule_AsVoidPtr(cobj); if (!NI_BinaryErosion2(array, strct, mask, niter, origins, invert, &cobj_data)) goto exit; } else { PyErr_SetString(PyExc_RuntimeError, "cannot convert CObject"); goto exit; } exit: Py_XDECREF(array); Py_XDECREF(strct); Py_XDECREF(mask); if (origins) free(origins); return PyErr_Occurred() ? NULL : Py_BuildValue(""); }
static HDSLoc * HDS_retrieve_locator( HDSObject *self) { if (self) { return (HDSLoc*)NpyCapsule_AsVoidPtr(self->_locator); } else { return NULL; } }
static PyObject *Py_GenericFilter1D(PyObject *obj, PyObject *args) { PyArrayObject *input = NULL, *output = NULL; PyObject *fnc = NULL, *extra_arguments = NULL, *extra_keywords = NULL; void *func = Py_Filter1DFunc, *data = NULL; NI_PythonCallbackData cbdata; int axis, mode; #if PY_VERSION_HEX < 0x02050000 long origin, filter_size; #define FMT "l" #else npy_intp origin, filter_size; #define FMT "n" #endif double cval; if (!PyArg_ParseTuple(args, "O&O" FMT "iO&id" FMT "OO", NI_ObjectToInputArray, &input, &fnc, &filter_size, &axis, NI_ObjectToOutputArray, &output, &mode, &cval, &origin, &extra_arguments, &extra_keywords)) goto exit; #undef FMT if (!PyTuple_Check(extra_arguments)) { PyErr_SetString(PyExc_RuntimeError, "extra_arguments must be a tuple"); goto exit; } if (!PyDict_Check(extra_keywords)) { PyErr_SetString(PyExc_RuntimeError, "extra_keywords must be a dictionary"); goto exit; } if (NpyCapsule_Check(fnc)) { func = NpyCapsule_AsVoidPtr(fnc); data = NpyCapsule_GetDesc(fnc); } else if (PyCallable_Check(fnc)) { cbdata.function = fnc; cbdata.extra_arguments = extra_arguments; cbdata.extra_keywords = extra_keywords; data = (void*)&cbdata; } else { PyErr_SetString(PyExc_RuntimeError, "function parameter is not callable"); goto exit; } if (!NI_GenericFilter1D(input, func, data, filter_size, axis, output, (NI_ExtendMode)mode, cval, origin)) goto exit; exit: Py_XDECREF(input); Py_XDECREF(output); return PyErr_Occurred() ? NULL : Py_BuildValue(""); }
static PyObject *Py_GenericFilter(PyObject *obj, PyObject *args) { PyArrayObject *input = NULL, *output = NULL, *footprint = NULL; PyObject *fnc = NULL, *extra_arguments = NULL, *extra_keywords = NULL; void *func = Py_FilterFunc, *data = NULL; NI_PythonCallbackData cbdata; int mode; npy_intp *origin = NULL; double cval; if (!PyArg_ParseTuple(args, "O&OO&O&idO&OO", NI_ObjectToInputArray, &input, &fnc, NI_ObjectToInputArray, &footprint, NI_ObjectToOutputArray, &output, &mode, &cval, NI_ObjectToLongSequence, &origin, &extra_arguments, &extra_keywords)) goto exit; if (!PyTuple_Check(extra_arguments)) { PyErr_SetString(PyExc_RuntimeError, "extra_arguments must be a tuple"); goto exit; } if (!PyDict_Check(extra_keywords)) { PyErr_SetString(PyExc_RuntimeError, "extra_keywords must be a dictionary"); goto exit; } if (NpyCapsule_Check(fnc)) { func = NpyCapsule_AsVoidPtr(fnc); data = NpyCapsule_GetDesc(fnc); } else if (PyCallable_Check(fnc)) { cbdata.function = fnc; cbdata.extra_arguments = extra_arguments; cbdata.extra_keywords = extra_keywords; data = (void*)&cbdata; } else { PyErr_SetString(PyExc_RuntimeError, "function parameter is not callable"); goto exit; } if (!NI_GenericFilter(input, func, data, footprint, output, (NI_ExtendMode)mode, cval, origin)) goto exit; exit: Py_XDECREF(input); Py_XDECREF(output); Py_XDECREF(footprint); if (origin) free(origin); return PyErr_Occurred() ? NULL : Py_BuildValue(""); }
static PyObject *Py_BinaryErosion2(PyObject *obj, PyObject *args) { PyArrayObject *array = NULL, *strct = NULL, *mask = NULL; PyObject *cobj = NULL; int invert, niter; PyArray_Dims origin; if (!PyArg_ParseTuple(args, "O&O&O&iO&iO", NI_ObjectToInputOutputArray, &array, NI_ObjectToInputArray, &strct, NI_ObjectToOptionalInputArray, &mask, &niter, PyArray_IntpConverter, &origin, &invert, &cobj)) { goto exit; } if (!_validate_origin(array, origin)) { goto exit; } if (NpyCapsule_Check(cobj)) { NI_CoordinateList *cobj_data = NpyCapsule_AsVoidPtr(cobj); if (!NI_BinaryErosion2(array, strct, mask, niter, origin.ptr, invert, &cobj_data)) { goto exit; } } else { PyErr_SetString(PyExc_RuntimeError, "cannot convert CObject"); } exit: Py_XDECREF(array); Py_XDECREF(strct); Py_XDECREF(mask); PyDimMem_FREE(origin.ptr); return PyErr_Occurred() ? NULL : Py_BuildValue(""); }
NPY_NO_EXPORT int PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, PyArray_Descr **out_dtype, int string_type) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; Py_buffer buffer_view; /* Check if it's an ndarray */ if (PyArray_Check(obj)) { dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* See if it's a python None */ if (obj == Py_None) { dtype = PyArray_DescrFromType(NPY_OBJECT); if (dtype == NULL) { goto fail; } Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ else if (PyArray_IsScalar(obj, Generic)) { if (!string_type) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } } else { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { if (string_type) { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* PEP 3118 buffer interface */ if (PyObject_CheckBuffer(obj) == 1) { memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } } /* The array interface */ ip = PyArray_GetAttrString_SuppressException(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; #if defined(NPY_PY3K) PyObject *tmp = NULL; #endif typestr = PyDict_GetItemString(ip, "typestr"); #if defined(NPY_PY3K) /* Allow unicode type strings */ if (PyUnicode_Check(typestr)) { tmp = PyUnicode_AsASCIIString(typestr); typestr = tmp; } #endif if (typestr && PyBytes_Check(typestr)) { dtype =_array_typedescr_fromstr(PyBytes_AS_STRING(typestr)); #if defined(NPY_PY3K) if (tmp == typestr) { Py_DECREF(tmp); } #endif Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The array struct interface */ ip = PyArray_GetAttrString_SuppressException(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ ip = PyArray_GetAttrString_SuppressException(obj, "__array__"); if (ip != NULL) { Py_DECREF(ip); ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* Not exactly sure what this is about... */ #if !defined(NPY_PY3K) if (PyInstance_Check(obj)) { dtype = _use_default_type(obj); if (dtype == NULL) { goto fail; } else { goto promote_types; } } #endif /* * If we reached the maximum recursion depth without hitting one * of the above cases, the output dtype should be OBJECT */ if (maxdims == 0 || !PySequence_Check(obj)) { if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case */ size = PySequence_Size(obj); if (size < 0) { goto fail; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { int res; ip = PySequence_GetItem(obj, i); if (ip == NULL) { goto fail; } res = PyArray_DTypeFromObjectHelper(ip, maxdims - 1, out_dtype, string_type); if (res < 0) { Py_DECREF(ip); goto fail; } else if (res > 0) { Py_DECREF(ip); return res; } Py_DECREF(ip); } return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { if (!string_type && dtype->type_num == NPY_STRING) { Py_DECREF(dtype); return RETRY_WITH_STRING; } if (!string_type && dtype->type_num == NPY_UNICODE) { Py_DECREF(dtype); return RETRY_WITH_UNICODE; } *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } if (!string_type && res_dtype->type_num == NPY_UNICODE && (*out_dtype)->type_num != NPY_UNICODE) { Py_DECREF(res_dtype); return RETRY_WITH_UNICODE; } if (!string_type && res_dtype->type_num == NPY_STRING && (*out_dtype)->type_num != NPY_STRING) { Py_DECREF(res_dtype); return RETRY_WITH_STRING; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; } #undef RETRY_WITH_STRING #undef RETRY_WITH_UNICODE /* new reference */ NPY_NO_EXPORT PyArray_Descr * _array_typedescr_fromstr(char *c_str) { PyArray_Descr *descr = NULL; PyObject *stringobj = PyString_FromString(c_str); if (stringobj == NULL) { return NULL; } if (PyArray_DescrConverter(stringobj, &descr) != NPY_SUCCEED) { Py_DECREF(stringobj); return NULL; } Py_DECREF(stringobj); return descr; } NPY_NO_EXPORT char * index2ptr(PyArrayObject *mp, npy_intp i) { npy_intp dim0; if (PyArray_NDIM(mp) == 0) { PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed"); return NULL; } dim0 = PyArray_DIMS(mp)[0]; if (check_and_adjust_index(&i, dim0, 0) < 0) return NULL; if (i == 0) { return PyArray_DATA(mp); } return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0]; }
NPY_NO_EXPORT int PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, PyArray_Descr **out_dtype, int string_type) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; Py_buffer buffer_view; /* types for sequence handling */ PyObject ** objects; PyObject * seq; PyTypeObject * common_type; /* Check if it's an ndarray */ if (PyArray_Check(obj)) { dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* See if it's a python None */ if (obj == Py_None) { dtype = PyArray_DescrFromType(NPY_OBJECT); if (dtype == NULL) { goto fail; } Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ else if (PyArray_IsScalar(obj, Generic)) { if (!string_type) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } } else { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { if (string_type) { int itemsize; PyObject *temp; if (string_type == NPY_STRING) { if ((temp = PyObject_Str(obj)) == NULL) { return -1; } #if defined(NPY_PY3K) #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); #else itemsize = PyUnicode_GET_SIZE(temp); #endif #else itemsize = PyString_GET_SIZE(temp); #endif } else if (string_type == NPY_UNICODE) { #if defined(NPY_PY3K) if ((temp = PyObject_Str(obj)) == NULL) { #else if ((temp = PyObject_Unicode(obj)) == NULL) { #endif return -1; } itemsize = PyUnicode_GET_DATA_SIZE(temp); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif } else { goto fail; } Py_DECREF(temp); if (*out_dtype != NULL && (*out_dtype)->type_num == string_type && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(string_type); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; } goto promote_types; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* PEP 3118 buffer interface */ if (PyObject_CheckBuffer(obj) == 1) { memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } } /* The array interface */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; #if defined(NPY_PY3K) PyObject *tmp = NULL; #endif typestr = PyDict_GetItemString(ip, "typestr"); #if defined(NPY_PY3K) /* Allow unicode type strings */ if (PyUnicode_Check(typestr)) { tmp = PyUnicode_AsASCIIString(typestr); typestr = tmp; } #endif if (typestr && PyBytes_Check(typestr)) { dtype =_array_typedescr_fromstr(PyBytes_AS_STRING(typestr)); #if defined(NPY_PY3K) if (tmp == typestr) { Py_DECREF(tmp); } #endif Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The array struct interface */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ ip = PyArray_LookupSpecial_OnInstance(obj, "__array__"); if (ip != NULL) { Py_DECREF(ip); ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* * If we reached the maximum recursion depth without hitting one * of the above cases, and obj isn't a sequence-like object, the output * dtype should be either OBJECT or a user-defined type. * * Note that some libraries define sequence-like classes but want them to * be treated as objects, and they expect numpy to treat it as an object if * __len__ is not defined. */ if (maxdims == 0 || !PySequence_Check(obj) || PySequence_Size(obj) < 0) { // clear any PySequence_Size error, which corrupts further calls to it PyErr_Clear(); if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case, first check the sequence contains only one type */ seq = PySequence_Fast(obj, "Could not convert object to sequence"); if (seq == NULL) { goto fail; } size = PySequence_Fast_GET_SIZE(seq); objects = PySequence_Fast_ITEMS(seq); common_type = size > 0 ? Py_TYPE(objects[0]) : NULL; for (i = 1; i < size; ++i) { if (Py_TYPE(objects[i]) != common_type) { common_type = NULL; break; } } /* all types are the same and scalar, one recursive call is enough */ if (common_type != NULL && !string_type && (common_type == &PyFloat_Type || /* TODO: we could add longs if we add a range check */ #if !defined(NPY_PY3K) common_type == &PyInt_Type || #endif common_type == &PyBool_Type || common_type == &PyComplex_Type)) { size = 1; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { int res = PyArray_DTypeFromObjectHelper(objects[i], maxdims - 1, out_dtype, string_type); if (res < 0) { Py_DECREF(seq); goto fail; } else if (res > 0) { Py_DECREF(seq); return res; } } Py_DECREF(seq); return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { if (!string_type && dtype->type_num == NPY_STRING) { Py_DECREF(dtype); return RETRY_WITH_STRING; } if (!string_type && dtype->type_num == NPY_UNICODE) { Py_DECREF(dtype); return RETRY_WITH_UNICODE; } *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } if (!string_type && res_dtype->type_num == NPY_UNICODE && (*out_dtype)->type_num != NPY_UNICODE) { Py_DECREF(res_dtype); return RETRY_WITH_UNICODE; } if (!string_type && res_dtype->type_num == NPY_STRING && (*out_dtype)->type_num != NPY_STRING) { Py_DECREF(res_dtype); return RETRY_WITH_STRING; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; } #undef RETRY_WITH_STRING #undef RETRY_WITH_UNICODE /* new reference */ NPY_NO_EXPORT PyArray_Descr * _array_typedescr_fromstr(char *c_str) { PyArray_Descr *descr = NULL; PyObject *stringobj = PyString_FromString(c_str); if (stringobj == NULL) { return NULL; } if (PyArray_DescrConverter(stringobj, &descr) != NPY_SUCCEED) { Py_DECREF(stringobj); return NULL; } Py_DECREF(stringobj); return descr; } NPY_NO_EXPORT char * index2ptr(PyArrayObject *mp, npy_intp i) { npy_intp dim0; if (PyArray_NDIM(mp) == 0) { PyErr_SetString(PyExc_IndexError, "0-d arrays can't be indexed"); return NULL; } dim0 = PyArray_DIMS(mp)[0]; if (check_and_adjust_index(&i, dim0, 0, NULL) < 0) return NULL; if (i == 0) { return PyArray_DATA(mp); } return PyArray_BYTES(mp)+i*PyArray_STRIDES(mp)[0]; }
/* * Recursively examines the object to determine an appropriate dtype * to use for converting to an ndarray. * * 'obj' is the object to be converted to an ndarray. * * 'maxdims' is the maximum recursion depth. * * 'out_contains_na' gets set to 1 if an np.NA object is encountered. * The NA does not affect the dtype produced, so if this is set to 1 * and the result is for an array without NA support, the dtype should * be switched to NPY_OBJECT. When adding multi-NA support, this should * also signal whether just regular NAs or NAs with payloads were seen. * * 'out_dtype' should be either NULL or a minimal starting dtype when * the function is called. It is updated with the results of type * promotion. This dtype does not get updated when processing NA objects. * This is reset to NULL on failure. * * Returns 0 on success, -1 on failure. */ NPY_NO_EXPORT int PyArray_DTypeFromObject(PyObject *obj, int maxdims, int *out_contains_na, PyArray_Descr **out_dtype) { int i, size; PyArray_Descr *dtype = NULL; PyObject *ip; #if PY_VERSION_HEX >= 0x02060000 Py_buffer buffer_view; #endif /* Check if it's an ndarray */ if (PyArray_Check(obj)) { /* Check for any NAs in the array */ int containsna = PyArray_ContainsNA((PyArrayObject *)obj, NULL, NULL); if (containsna == -1) { goto fail; } else if (containsna) { *out_contains_na = 1; } dtype = PyArray_DESCR((PyArrayObject *)obj); Py_INCREF(dtype); goto promote_types; } /* Check if it's a NumPy scalar */ if (PyArray_IsScalar(obj, Generic)) { dtype = PyArray_DescrFromScalar(obj); if (dtype == NULL) { goto fail; } goto promote_types; } /* Check if it's a Python scalar */ dtype = _array_find_python_scalar_type(obj); if (dtype != NULL) { goto promote_types; } /* Check if it's an NA */ if (NpyNA_Check(obj)) { *out_contains_na = 1; return 0; } /* Check if it's an ASCII string */ if (PyBytes_Check(obj)) { int itemsize = PyString_GET_SIZE(obj); /* If it's already a big enough string, don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_STRING && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_STRING); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } /* Check if it's a Unicode string */ if (PyUnicode_Check(obj)) { int itemsize = PyUnicode_GET_DATA_SIZE(obj); #ifndef Py_UNICODE_WIDE itemsize <<= 1; #endif /* * If it's already a big enough unicode object, * don't bother type promoting */ if (*out_dtype != NULL && (*out_dtype)->type_num == NPY_UNICODE && (*out_dtype)->elsize >= itemsize) { return 0; } dtype = PyArray_DescrNewFromType(NPY_UNICODE); if (dtype == NULL) { goto fail; } dtype->elsize = itemsize; goto promote_types; } #if PY_VERSION_HEX >= 0x02060000 /* PEP 3118 buffer interface */ memset(&buffer_view, 0, sizeof(Py_buffer)); if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT|PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_FORMAT) == 0) { PyErr_Clear(); dtype = _descriptor_from_pep3118_format(buffer_view.format); PyBuffer_Release(&buffer_view); if (dtype) { goto promote_types; } } else if (PyObject_GetBuffer(obj, &buffer_view, PyBUF_STRIDES) == 0 || PyObject_GetBuffer(obj, &buffer_view, PyBUF_SIMPLE) == 0) { PyErr_Clear(); dtype = PyArray_DescrNewFromType(NPY_VOID); dtype->elsize = buffer_view.itemsize; PyBuffer_Release(&buffer_view); goto promote_types; } else { PyErr_Clear(); } #endif /* The array interface */ ip = PyObject_GetAttrString(obj, "__array_interface__"); if (ip != NULL) { if (PyDict_Check(ip)) { PyObject *typestr; typestr = PyDict_GetItemString(ip, "typestr"); if (typestr && PyString_Check(typestr)) { dtype =_array_typedescr_fromstr(PyString_AS_STRING(typestr)); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } else { PyErr_Clear(); } /* The array struct interface */ ip = PyObject_GetAttrString(obj, "__array_struct__"); if (ip != NULL) { PyArrayInterface *inter; char buf[40]; if (NpyCapsule_Check(ip)) { inter = (PyArrayInterface *)NpyCapsule_AsVoidPtr(ip); if (inter->two == 2) { PyOS_snprintf(buf, sizeof(buf), "|%c%d", inter->typekind, inter->itemsize); dtype = _array_typedescr_fromstr(buf); Py_DECREF(ip); if (dtype == NULL) { goto fail; } goto promote_types; } } Py_DECREF(ip); } else { PyErr_Clear(); } /* The old buffer interface */ #if !defined(NPY_PY3K) if (PyBuffer_Check(obj)) { dtype = PyArray_DescrNewFromType(NPY_VOID); if (dtype == NULL) { goto fail; } dtype->elsize = Py_TYPE(obj)->tp_as_sequence->sq_length(obj); PyErr_Clear(); goto promote_types; } #endif /* The __array__ attribute */ if (PyObject_HasAttrString(obj, "__array__")) { ip = PyObject_CallMethod(obj, "__array__", NULL); if(ip && PyArray_Check(ip)) { dtype = PyArray_DESCR((PyArrayObject *)ip); Py_INCREF(dtype); Py_DECREF(ip); goto promote_types; } Py_XDECREF(ip); if (PyErr_Occurred()) { goto fail; } } /* Not exactly sure what this is about... */ #if !defined(NPY_PY3K) if (PyInstance_Check(obj)) { dtype = _use_default_type(obj); if (dtype == NULL) { goto fail; } else { goto promote_types; } } #endif /* * If we reached the maximum recursion depth without hitting one * of the above cases, the output dtype should be OBJECT */ if (maxdims == 0 || !PySequence_Check(obj)) { if (*out_dtype == NULL || (*out_dtype)->type_num != NPY_OBJECT) { Py_XDECREF(*out_dtype); *out_dtype = PyArray_DescrFromType(NPY_OBJECT); if (*out_dtype == NULL) { return -1; } } return 0; } /* Recursive case */ size = PySequence_Size(obj); if (size < 0) { goto fail; } /* Recursive call for each sequence item */ for (i = 0; i < size; ++i) { ip = PySequence_GetItem(obj, i); if (ip==NULL) { goto fail; } if (PyArray_DTypeFromObject(ip, maxdims - 1, out_contains_na, out_dtype) < 0) { Py_DECREF(ip); goto fail; } Py_DECREF(ip); } return 0; promote_types: /* Set 'out_dtype' if it's NULL */ if (*out_dtype == NULL) { *out_dtype = dtype; return 0; } /* Do type promotion with 'out_dtype' */ else { PyArray_Descr *res_dtype = PyArray_PromoteTypes(dtype, *out_dtype); Py_DECREF(dtype); if (res_dtype == NULL) { return -1; } Py_DECREF(*out_dtype); *out_dtype = res_dtype; return 0; } fail: Py_XDECREF(*out_dtype); *out_dtype = NULL; return -1; }