static int HALF_setitem(PyObject *op, char *ov, PyArrayObject *ap) { npy_half temp; /* ensures alignment */ if (PyArray_IsScalar(op, Half)) { temp = ((PyHalfScalarObject *)op)->obval; } else { temp = MyPyFloat_AsHalf(op); } if (PyErr_Occurred()) { if (PySequence_Check(op)) { PyErr_Clear(); PyErr_SetString(PyExc_ValueError, "setting an array element with a sequence."); } return -1; } if (ap == NULL || PyArray_ISBEHAVED(ap)) *((npy_half *)ov)=temp; else { ap->descr->f->copyswap(ov, &temp, !PyArray_ISNOTSWAPPED(ap), ap); } return 0; }
static int QUATERNION_setitem(PyObject *op, char *ov, PyArrayObject *ap) { quaternion q; if (PyArray_IsScalar(op, Quaternion)) { q = ((PyQuaternionScalarObject *)op)->obval; } else { q.w = PyFloat_AsDouble(PyTuple_GetItem(op, 0)); q.x = PyFloat_AsDouble(PyTuple_GetItem(op, 1)); q.y = PyFloat_AsDouble(PyTuple_GetItem(op, 2)); q.z = PyFloat_AsDouble(PyTuple_GetItem(op, 3)); } if (PyErr_Occurred()) { if (PySequence_Check(op)) { PyErr_Clear(); PyErr_SetString(PyExc_ValueError, "setting an array element with a sequence."); } return -1; } if (ap == NULL || PyArray_ISBEHAVED(ap)) *((quaternion *)ov)=q; else { PyArray_Descr *descr; descr = PyArray_DescrFromType(NPY_DOUBLE); descr->f->copyswap(ov, &q.w, !PyArray_ISNOTSWAPPED(ap), NULL); descr->f->copyswap(ov+8, &q.x, !PyArray_ISNOTSWAPPED(ap), NULL); descr->f->copyswap(ov+16, &q.y, !PyArray_ISNOTSWAPPED(ap), NULL); descr->f->copyswap(ov+24, &q.z, !PyArray_ISNOTSWAPPED(ap), NULL); Py_DECREF(descr); } return 0; }
static int array_power_is_scalar(PyObject *o2, double* exp) { PyObject *temp; const int optimize_fpexps = 1; if (PyInt_Check(o2)) { *exp = (double)PyInt_AsLong(o2); return 1; } if (optimize_fpexps && PyFloat_Check(o2)) { *exp = PyFloat_AsDouble(o2); return 1; } if ((PyArray_IsZeroDim(o2) && ((PyArray_ISINTEGER(o2) || (optimize_fpexps && PyArray_ISFLOAT(o2))))) || PyArray_IsScalar(o2, Integer) || (optimize_fpexps && PyArray_IsScalar(o2, Floating))) { temp = o2->ob_type->tp_as_number->nb_float(o2); if (temp != NULL) { *exp = PyFloat_AsDouble(o2); Py_DECREF(temp); return 1; } } #if (PY_VERSION_HEX >= 0x02050000) if (PyIndex_Check(o2)) { PyObject* value = PyNumber_Index(o2); Py_ssize_t val; if (value==NULL) { if (PyErr_Occurred()) { PyErr_Clear(); } return 0; } val = PyInt_AsSsize_t(value); if (val == -1 && PyErr_Occurred()) { PyErr_Clear(); return 0; } *exp = (double) val; return 1; } #endif return 0; }
/*NUMPY_API*/ NPY_NO_EXPORT int PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object) { PyArrayObject *src; PyObject *r; int ret; /* * Special code to mimic Numeric behavior for * character arrays. */ if (dest->descr->type == PyArray_CHARLTR && dest->nd > 0 \ && PyString_Check(src_object)) { intp n_new, n_old; char *new_string; PyObject *tmp; n_new = dest->dimensions[dest->nd-1]; n_old = PyString_Size(src_object); if (n_new > n_old) { new_string = (char *)malloc(n_new); memmove(new_string, PyString_AS_STRING(src_object), n_old); memset(new_string + n_old, ' ', n_new - n_old); tmp = PyString_FromStringAndSize(new_string, n_new); free(new_string); src_object = tmp; } } if (PyArray_Check(src_object)) { src = (PyArrayObject *)src_object; Py_INCREF(src); } else if (!PyArray_IsScalar(src_object, Generic) && PyArray_HasArrayInterface(src_object, r)) { src = (PyArrayObject *)r; } else { PyArray_Descr* dtype; dtype = dest->descr; Py_INCREF(dtype); src = (PyArrayObject *)PyArray_FromAny(src_object, dtype, 0, dest->nd, FORTRAN_IF(dest), NULL); } if (src == NULL) { return -1; } ret = PyArray_MoveInto(dest, src); Py_DECREF(src); return ret; }
static int array_power_is_scalar(PyObject *o2, double* out_exponent) { PyObject *temp; const int optimize_fpexps = 1; if (PyInt_Check(o2)) { *out_exponent = (double)PyInt_AsLong(o2); return NPY_INTPOS_SCALAR; } if (optimize_fpexps && PyFloat_Check(o2)) { *out_exponent = PyFloat_AsDouble(o2); return NPY_FLOAT_SCALAR; } if ((PyArray_IsZeroDim(o2) && ((PyArray_ISINTEGER((PyArrayObject *)o2) || (optimize_fpexps && PyArray_ISFLOAT((PyArrayObject *)o2))))) || PyArray_IsScalar(o2, Integer) || (optimize_fpexps && PyArray_IsScalar(o2, Floating))) { temp = Py_TYPE(o2)->tp_as_number->nb_float(o2); if (temp != NULL) { *out_exponent = PyFloat_AsDouble(o2); Py_DECREF(temp); if (PyArray_IsZeroDim(o2)) { if (PyArray_ISINTEGER((PyArrayObject *)o2)) { return NPY_INTPOS_SCALAR; } else { /* ISFLOAT */ return NPY_FLOAT_SCALAR; } } else if PyArray_IsScalar(o2, Integer) { return NPY_INTPOS_SCALAR; } else { /* IsScalar(o2, Floating) */ return NPY_FLOAT_SCALAR;
/* Fill in the info structure */ static _buffer_info_t* _buffer_info_new(PyObject *obj) { _buffer_info_t *info; _tmp_string_t fmt = {NULL, 0, 0}; int k; PyArray_Descr *descr = NULL; int err = 0; info = malloc(sizeof(_buffer_info_t)); if (info == NULL) { PyErr_NoMemory(); goto fail; } if (PyArray_IsScalar(obj, Datetime) || PyArray_IsScalar(obj, Timedelta)) { /* * Special case datetime64 scalars to remain backward compatible. * This will change in a future version. * Note arrays of datetime64 and strutured arrays with datetime64 * fields will not hit this code path and are currently unsupported * in _buffer_format_string. */ if (_append_char(&fmt, 'B') < 0) { goto fail; } if (_append_char(&fmt, '\0') < 0) { goto fail; } info->ndim = 1; info->shape = malloc(sizeof(Py_ssize_t) * 2); if (info->shape == NULL) { PyErr_NoMemory(); goto fail; } info->strides = info->shape + info->ndim; info->shape[0] = 8; info->strides[0] = 1; info->format = fmt.s; return info; } else if (PyArray_IsScalar(obj, Generic)) { descr = PyArray_DescrFromScalar(obj); if (descr == NULL) { goto fail; } info->ndim = 0; info->shape = NULL; info->strides = NULL; } else { PyArrayObject * arr = (PyArrayObject *)obj; descr = PyArray_DESCR(arr); /* Fill in shape and strides */ info->ndim = PyArray_NDIM(arr); if (info->ndim == 0) { info->shape = NULL; info->strides = NULL; } else { info->shape = malloc(sizeof(Py_ssize_t) * PyArray_NDIM(arr) * 2 + 1); if (info->shape == NULL) { PyErr_NoMemory(); goto fail; } info->strides = info->shape + PyArray_NDIM(arr); for (k = 0; k < PyArray_NDIM(arr); ++k) { info->shape[k] = PyArray_DIMS(arr)[k]; info->strides[k] = PyArray_STRIDES(arr)[k]; } } Py_INCREF(descr); } /* Fill in format */ err = _buffer_format_string(descr, &fmt, obj, NULL, NULL); Py_DECREF(descr); if (err != 0) { goto fail; } if (_append_char(&fmt, '\0') < 0) { goto fail; } info->format = fmt.s; return info; fail: free(fmt.s); free(info); return NULL; }
/* * Fill in str with an appropriate PEP 3118 format string, based on * descr. For structured dtypes, calls itself recursively. Each call extends * str at offset then updates offset, and uses descr->byteorder, (and * possibly the byte order in obj) to determine the byte-order char. * * Returns 0 for success, -1 for failure */ static int _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str, PyObject* obj, Py_ssize_t *offset, char *active_byteorder) { int k; char _active_byteorder = '@'; Py_ssize_t _offset = 0; if (active_byteorder == NULL) { active_byteorder = &_active_byteorder; } if (offset == NULL) { offset = &_offset; } if (descr->subarray) { PyObject *item, *subarray_tuple; Py_ssize_t total_count = 1; Py_ssize_t dim_size; Py_ssize_t old_offset; char buf[128]; int ret; if (PyTuple_Check(descr->subarray->shape)) { subarray_tuple = descr->subarray->shape; Py_INCREF(subarray_tuple); } else { subarray_tuple = Py_BuildValue("(O)", descr->subarray->shape); } if (_append_char(str, '(') < 0) { ret = -1; goto subarray_fail; } for (k = 0; k < PyTuple_GET_SIZE(subarray_tuple); ++k) { if (k > 0) { if (_append_char(str, ',') < 0) { ret = -1; goto subarray_fail; } } item = PyTuple_GET_ITEM(subarray_tuple, k); dim_size = PyNumber_AsSsize_t(item, NULL); PyOS_snprintf(buf, sizeof(buf), "%ld", (long)dim_size); if (_append_str(str, buf) < 0) { ret = -1; goto subarray_fail; } total_count *= dim_size; } if (_append_char(str, ')') < 0) { ret = -1; goto subarray_fail; } old_offset = *offset; ret = _buffer_format_string(descr->subarray->base, str, obj, offset, active_byteorder); *offset = old_offset + (*offset - old_offset) * total_count; subarray_fail: Py_DECREF(subarray_tuple); return ret; } else if (PyDataType_HASFIELDS(descr)) { Py_ssize_t base_offset = *offset; if (_append_str(str, "T{") < 0) return -1; for (k = 0; k < PyTuple_GET_SIZE(descr->names); ++k) { PyObject *name, *item, *offset_obj; PyArray_Descr *child; Py_ssize_t new_offset; int ret; name = PyTuple_GET_ITEM(descr->names, k); item = PyDict_GetItem(descr->fields, name); child = (PyArray_Descr*)PyTuple_GetItem(item, 0); offset_obj = PyTuple_GetItem(item, 1); new_offset = PyInt_AsLong(offset_obj); if (error_converting(new_offset)) { return -1; } new_offset += base_offset; /* Insert padding manually */ if (*offset > new_offset) { PyErr_SetString( PyExc_ValueError, "dtypes with overlapping or out-of-order fields are not " "representable as buffers. Consider reordering the fields." ); return -1; } while (*offset < new_offset) { if (_append_char(str, 'x') < 0) return -1; ++*offset; } /* Insert child item */ ret = _buffer_format_string(child, str, obj, offset, active_byteorder); if (ret < 0) { return -1; } /* Insert field name */ if (_append_field_name(str, name) < 0) return -1; } if (_append_char(str, '}') < 0) return -1; } else { int is_standard_size = 1; int is_natively_aligned; int is_native_only_type = (descr->type_num == NPY_LONGDOUBLE || descr->type_num == NPY_CLONGDOUBLE); if (sizeof(npy_longlong) != 8) { is_native_only_type = is_native_only_type || ( descr->type_num == NPY_LONGLONG || descr->type_num == NPY_ULONGLONG); } *offset += descr->elsize; if (PyArray_IsScalar(obj, Generic)) { /* scalars are always natively aligned */ is_natively_aligned = 1; } else { is_natively_aligned = _is_natively_aligned_at(descr, (PyArrayObject*)obj, *offset); } if (descr->byteorder == '=' && is_natively_aligned) { /* Prefer native types, to cater for Cython */ is_standard_size = 0; if (*active_byteorder != '@') { if (_append_char(str, '@') < 0) return -1; *active_byteorder = '@'; } } else if (descr->byteorder == '=' && is_native_only_type) { /* Data types that have no standard size */ is_standard_size = 0; if (*active_byteorder != '^') { if (_append_char(str, '^') < 0) return -1; *active_byteorder = '^'; } } else if (descr->byteorder == '<' || descr->byteorder == '>' || descr->byteorder == '=') { is_standard_size = 1; if (*active_byteorder != descr->byteorder) { if (_append_char(str, descr->byteorder) < 0) return -1; *active_byteorder = descr->byteorder; } if (is_native_only_type) { /* * It's not possible to express native-only data types * in non-native npy_byte orders */ PyErr_Format(PyExc_ValueError, "cannot expose native-only dtype '%c' in " "non-native byte order '%c' via buffer interface", descr->type, descr->byteorder); return -1; } } switch (descr->type_num) { case NPY_BOOL: if (_append_char(str, '?') < 0) return -1; break; case NPY_BYTE: if (_append_char(str, 'b') < 0) return -1; break; case NPY_UBYTE: if (_append_char(str, 'B') < 0) return -1; break; case NPY_SHORT: if (_append_char(str, 'h') < 0) return -1; break; case NPY_USHORT: if (_append_char(str, 'H') < 0) return -1; break; case NPY_INT: if (_append_char(str, 'i') < 0) return -1; break; case NPY_UINT: if (_append_char(str, 'I') < 0) return -1; break; case NPY_LONG: if (is_standard_size && (NPY_SIZEOF_LONG == 8)) { if (_append_char(str, 'q') < 0) return -1; } else { if (_append_char(str, 'l') < 0) return -1; } break; case NPY_ULONG: if (is_standard_size && (NPY_SIZEOF_LONG == 8)) { if (_append_char(str, 'Q') < 0) return -1; } else { if (_append_char(str, 'L') < 0) return -1; } break; case NPY_LONGLONG: if (_append_char(str, 'q') < 0) return -1; break; case NPY_ULONGLONG: if (_append_char(str, 'Q') < 0) return -1; break; case NPY_HALF: if (_append_char(str, 'e') < 0) return -1; break; case NPY_FLOAT: if (_append_char(str, 'f') < 0) return -1; break; case NPY_DOUBLE: if (_append_char(str, 'd') < 0) return -1; break; case NPY_LONGDOUBLE: if (_append_char(str, 'g') < 0) return -1; break; case NPY_CFLOAT: if (_append_str(str, "Zf") < 0) return -1; break; case NPY_CDOUBLE: if (_append_str(str, "Zd") < 0) return -1; break; case NPY_CLONGDOUBLE: if (_append_str(str, "Zg") < 0) return -1; break; /* XXX NPY_DATETIME */ /* XXX NPY_TIMEDELTA */ case NPY_OBJECT: if (_append_char(str, 'O') < 0) return -1; break; case NPY_STRING: { char buf[128]; PyOS_snprintf(buf, sizeof(buf), "%ds", descr->elsize); if (_append_str(str, buf) < 0) return -1; break; } case NPY_UNICODE: { /* NumPy Unicode is always 4-byte */ char buf[128]; assert(descr->elsize % 4 == 0); PyOS_snprintf(buf, sizeof(buf), "%dw", descr->elsize / 4); if (_append_str(str, buf) < 0) return -1; break; } case NPY_VOID: { /* Insert padding bytes */ char buf[128]; PyOS_snprintf(buf, sizeof(buf), "%dx", descr->elsize); if (_append_str(str, buf) < 0) return -1; break; } default: PyErr_Format(PyExc_ValueError, "cannot include dtype '%c' in a buffer", descr->type); return -1; } } return 0; }
/*NUMPY_API*/ NPY_NO_EXPORT intp PyArray_PyIntAsIntp(PyObject *o) { longlong long_value = -1; PyObject *obj; static char *msg = "an integer is required"; PyObject *arr; PyArray_Descr *descr; intp ret; if (!o) { PyErr_SetString(PyExc_TypeError, msg); return -1; } if (PyInt_Check(o)) { long_value = (longlong) PyInt_AS_LONG(o); goto finish; } else if (PyLong_Check(o)) { long_value = (longlong) PyLong_AsLongLong(o); goto finish; } #if SIZEOF_INTP == SIZEOF_LONG descr = &LONG_Descr; #elif SIZEOF_INTP == SIZEOF_INT descr = &INT_Descr; #else descr = &LONGLONG_Descr; #endif arr = NULL; if (PyArray_Check(o)) { if (PyArray_SIZE(o)!=1 || !PyArray_ISINTEGER(o)) { PyErr_SetString(PyExc_TypeError, msg); return -1; } Py_INCREF(descr); arr = PyArray_CastToType((PyArrayObject *)o, descr, 0); } else if (PyArray_IsScalar(o, Integer)) { Py_INCREF(descr); arr = PyArray_FromScalar(o, descr); } if (arr != NULL) { ret = *((intp *)PyArray_DATA(arr)); Py_DECREF(arr); return ret; } #if (PY_VERSION_HEX >= 0x02050000) if (PyIndex_Check(o)) { PyObject* value = PyNumber_Index(o); if (value == NULL) { return -1; } long_value = (longlong) PyInt_AsSsize_t(value); goto finish; } #endif #if !defined(NPY_PY3K) if (Py_TYPE(o)->tp_as_number != NULL && \ Py_TYPE(o)->tp_as_number->nb_long != NULL) { obj = Py_TYPE(o)->tp_as_number->nb_long(o); if (obj != NULL) { long_value = (longlong) PyLong_AsLongLong(obj); Py_DECREF(obj); } } else #endif if (Py_TYPE(o)->tp_as_number != NULL && \ Py_TYPE(o)->tp_as_number->nb_int != NULL) { obj = Py_TYPE(o)->tp_as_number->nb_int(o); if (obj != NULL) { long_value = (longlong) PyLong_AsLongLong(obj); Py_DECREF(obj); } } else { PyErr_SetString(PyExc_NotImplementedError,""); } finish: if error_converting(long_value) { PyErr_SetString(PyExc_TypeError, msg); return -1; } #if (SIZEOF_LONGLONG > SIZEOF_INTP) if ((long_value < MIN_INTP) || (long_value > MAX_INTP)) { PyErr_SetString(PyExc_ValueError, "integer won't fit into a C intp"); return -1; } #endif return (intp) long_value; }
/* * Determine if object is a scalar and if so, convert the object * to a double and place it in the out_exponent argument * and return the "scalar kind" as a result. If the object is * not a scalar (or if there are other error conditions) * return NPY_NOSCALAR, and out_exponent is undefined. */ static NPY_SCALARKIND is_scalar_with_conversion(PyObject *o2, double* out_exponent) { PyObject *temp; const int optimize_fpexps = 1; if (PyInt_Check(o2)) { *out_exponent = (double)PyInt_AsLong(o2); return NPY_INTPOS_SCALAR; } if (optimize_fpexps && PyFloat_Check(o2)) { *out_exponent = PyFloat_AsDouble(o2); return NPY_FLOAT_SCALAR; } if (PyArray_Check(o2)) { if ((PyArray_NDIM((PyArrayObject *)o2) == 0) && ((PyArray_ISINTEGER((PyArrayObject *)o2) || (optimize_fpexps && PyArray_ISFLOAT((PyArrayObject *)o2))))) { temp = Py_TYPE(o2)->tp_as_number->nb_float(o2); if (temp == NULL) { return NPY_NOSCALAR; } *out_exponent = PyFloat_AsDouble(o2); Py_DECREF(temp); if (PyArray_ISINTEGER((PyArrayObject *)o2)) { return NPY_INTPOS_SCALAR; } else { /* ISFLOAT */ return NPY_FLOAT_SCALAR; } } } else if (PyArray_IsScalar(o2, Integer) || (optimize_fpexps && PyArray_IsScalar(o2, Floating))) { temp = Py_TYPE(o2)->tp_as_number->nb_float(o2); if (temp == NULL) { return NPY_NOSCALAR; } *out_exponent = PyFloat_AsDouble(o2); Py_DECREF(temp); if (PyArray_IsScalar(o2, Integer)) { return NPY_INTPOS_SCALAR; } else { /* IsScalar(o2, Floating) */ return NPY_FLOAT_SCALAR; } } else if (PyIndex_Check(o2)) { PyObject* value = PyNumber_Index(o2); Py_ssize_t val; if (value==NULL) { if (PyErr_Occurred()) { PyErr_Clear(); } return NPY_NOSCALAR; } val = PyInt_AsSsize_t(value); if (error_converting(val)) { PyErr_Clear(); return NPY_NOSCALAR; } *out_exponent = (double) val; return NPY_INTPOS_SCALAR; } return NPY_NOSCALAR; }
static npy_intp PyArray_PyIntAsIntp_ErrMsg(PyObject *o, const char * msg) { #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long long long_value = -1; #else long long_value = -1; #endif PyObject *obj, *err; if (!o) { PyErr_SetString(PyExc_TypeError, msg); return -1; } /* Be a bit stricter and not allow bools, np.bool_ is handled later */ if (PyBool_Check(o)) { if (DEPRECATE("using a boolean instead of an integer" " will result in an error in the future") < 0) { return -1; } } /* * Since it is the usual case, first check if o is an integer. This is * an exact check, since otherwise __index__ is used. */ #if !defined(NPY_PY3K) if (PyInt_CheckExact(o)) { #if (NPY_SIZEOF_LONG <= NPY_SIZEOF_INTP) /* No overflow is possible, so we can just return */ return PyInt_AS_LONG(o); #else long_value = PyInt_AS_LONG(o); goto overflow_check; #endif } else #endif if (PyLong_CheckExact(o)) { #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long_value = PyLong_AsLongLong(o); #else long_value = PyLong_AsLong(o); #endif return (npy_intp)long_value; } /* Disallow numpy.bool_. Boolean arrays do not currently support index. */ if (PyArray_IsScalar(o, Bool)) { if (DEPRECATE("using a boolean instead of an integer" " will result in an error in the future") < 0) { return -1; } } /* * The most general case. PyNumber_Index(o) covers everything * including arrays. In principle it may be possible to replace * the whole function by PyIndex_AsSSize_t after deprecation. */ obj = PyNumber_Index(o); if (obj) { #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long_value = PyLong_AsLongLong(obj); #else long_value = PyLong_AsLong(obj); #endif Py_DECREF(obj); goto finish; } else { /* * Set the TypeError like PyNumber_Index(o) would after trying * the general case. */ PyErr_Clear(); } /* * For backward compatibility check the number C-Api number protcol * This should be removed up the finish label after deprecation. */ if (Py_TYPE(o)->tp_as_number != NULL && Py_TYPE(o)->tp_as_number->nb_int != NULL) { obj = Py_TYPE(o)->tp_as_number->nb_int(o); if (obj == NULL) { return -1; } #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long_value = PyLong_AsLongLong(obj); #else long_value = PyLong_AsLong(obj); #endif Py_DECREF(obj); } #if !defined(NPY_PY3K) else if (Py_TYPE(o)->tp_as_number != NULL && Py_TYPE(o)->tp_as_number->nb_long != NULL) { obj = Py_TYPE(o)->tp_as_number->nb_long(o); if (obj == NULL) { return -1; } #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long_value = PyLong_AsLongLong(obj); #else long_value = PyLong_AsLong(obj); #endif Py_DECREF(obj); } #endif else { PyErr_SetString(PyExc_TypeError, msg); return -1; } /* Give a deprecation warning, unless there was already an error */ if (!error_converting(long_value)) { if (DEPRECATE("using a non-integer number instead of an integer" " will result in an error in the future") < 0) { return -1; } } finish: if (error_converting(long_value)) { err = PyErr_Occurred(); /* Only replace TypeError's here, which are the normal errors. */ if (PyErr_GivenExceptionMatches(err, PyExc_TypeError)) { PyErr_SetString(PyExc_TypeError, msg); } return -1; } overflow_check: #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) #if (NPY_SIZEOF_LONGLONG > NPY_SIZEOF_INTP) if ((long_value < NPY_MIN_INTP) || (long_value > NPY_MAX_INTP)) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C numpy.intp"); return -1; } #endif #else #if (NPY_SIZEOF_LONG > NPY_SIZEOF_INTP) if ((long_value < NPY_MIN_INTP) || (long_value > NPY_MAX_INTP)) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C numpy.intp"); return -1; } #endif #endif return long_value; }
/*NUMPY_API*/ NPY_NO_EXPORT int PyArray_CopyObject(PyArrayObject *dest, PyObject *src_object) { int ret; PyArrayObject *src; PyArray_Descr *dtype = NULL; int ndim = 0; npy_intp dims[NPY_MAXDIMS]; Py_INCREF(src_object); /* * Special code to mimic Numeric behavior for * character arrays. */ if (dest->descr->type == PyArray_CHARLTR && dest->nd > 0 \ && PyString_Check(src_object)) { npy_intp n_new, n_old; char *new_string; PyObject *tmp; n_new = dest->dimensions[dest->nd-1]; n_old = PyString_Size(src_object); if (n_new > n_old) { new_string = (char *)malloc(n_new); memmove(new_string, PyString_AS_STRING(src_object), n_old); memset(new_string + n_old, ' ', n_new - n_old); tmp = PyString_FromStringAndSize(new_string, n_new); free(new_string); Py_DECREF(src_object); src_object = tmp; } } /* * Get either an array object we can copy from, or its parameters * if there isn't a convenient array available. */ if (PyArray_GetArrayParamsFromObject(src_object, PyArray_DESCR(dest), 0, &dtype, &ndim, dims, &src, NULL) < 0) { Py_DECREF(src_object); return -1; } /* If it's not an array, either assign from a sequence or as a scalar */ if (src == NULL) { /* If the input is scalar */ if (ndim == 0) { /* If there's one dest element and src is a Python scalar */ if (PyArray_IsScalar(src_object, Generic)) { src = (PyArrayObject *)PyArray_FromScalar(src_object, dtype); if (src == NULL) { Py_DECREF(src_object); return -1; } } else { if (PyArray_SIZE(dest) == 1) { Py_DECREF(dtype); return PyArray_DESCR(dest)->f->setitem(src_object, PyArray_DATA(dest), dest); } else { src = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, 0, NULL, NULL, NULL, 0, NULL); if (src == NULL) { Py_DECREF(src_object); return -1; } if (PyArray_DESCR(src)->f->setitem(src_object, PyArray_DATA(src), src) < 0) { Py_DECREF(src_object); Py_DECREF(src); return -1; } } } } else { /* * If there are more than enough dims, use AssignFromSequence * because it can handle this style of broadcasting. */ if (ndim >= PyArray_NDIM(dest)) { int res; Py_DECREF(dtype); res = PyArray_AssignFromSequence(dest, src_object); Py_DECREF(src_object); return res; } /* Otherwise convert to an array and do an array-based copy */ src = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, ndim, dims, NULL, NULL, PyArray_ISFORTRAN(dest), NULL); if (src == NULL) { Py_DECREF(src_object); return -1; } if (PyArray_AssignFromSequence(src, src_object) < 0) { Py_DECREF(src); Py_DECREF(src_object); return -1; } } } /* If it's an array, do a move (handling possible overlapping data) */ ret = PyArray_MoveInto(dest, src); Py_DECREF(src); Py_DECREF(src_object); return ret; }
static npy_intp PyArray_PyIntAsIntp_ErrMsg(PyObject *o, const char * msg) { #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long long long_value = -1; #else long long_value = -1; #endif PyObject *obj, *err; /* * Be a bit stricter and not allow bools. * np.bool_ is also disallowed as Boolean arrays do not currently * support index. */ if (!o || PyBool_Check(o) || PyArray_IsScalar(o, Bool)) { PyErr_SetString(PyExc_TypeError, msg); return -1; } /* * Since it is the usual case, first check if o is an integer. This is * an exact check, since otherwise __index__ is used. */ #if !defined(NPY_PY3K) if (PyInt_CheckExact(o)) { #if (NPY_SIZEOF_LONG <= NPY_SIZEOF_INTP) /* No overflow is possible, so we can just return */ return PyInt_AS_LONG(o); #else long_value = PyInt_AS_LONG(o); goto overflow_check; #endif } else #endif if (PyLong_CheckExact(o)) { #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long_value = PyLong_AsLongLong(o); #else long_value = PyLong_AsLong(o); #endif return (npy_intp)long_value; } /* * The most general case. PyNumber_Index(o) covers everything * including arrays. In principle it may be possible to replace * the whole function by PyIndex_AsSSize_t after deprecation. */ obj = PyNumber_Index(o); if (obj == NULL) { return -1; } #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) long_value = PyLong_AsLongLong(obj); #else long_value = PyLong_AsLong(obj); #endif Py_DECREF(obj); if (error_converting(long_value)) { err = PyErr_Occurred(); /* Only replace TypeError's here, which are the normal errors. */ if (PyErr_GivenExceptionMatches(err, PyExc_TypeError)) { PyErr_SetString(PyExc_TypeError, msg); } return -1; } goto overflow_check; /* silence unused warning */ overflow_check: #if (NPY_SIZEOF_LONG < NPY_SIZEOF_INTP) #if (NPY_SIZEOF_LONGLONG > NPY_SIZEOF_INTP) if ((long_value < NPY_MIN_INTP) || (long_value > NPY_MAX_INTP)) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C numpy.intp"); return -1; } #endif #else #if (NPY_SIZEOF_LONG > NPY_SIZEOF_INTP) if ((long_value < NPY_MIN_INTP) || (long_value > NPY_MAX_INTP)) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C numpy.intp"); return -1; } #endif #endif return long_value; }
/* * 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; }