summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
author87 <hangenuit@gmail.com>2011-10-17 00:24:29 +0200
committerSebastian Berg <sebastian@sipsolutions.net>2013-04-11 16:40:47 +0200
commit793595279432e3f4627bf713ca3554c8caa3419e (patch)
tree7fa1ebeca11de9e295f078c7b38da7686778c4b8 /numpy
parent818e3ebc61b485465412251e86d3b4f95c75deb8 (diff)
downloadnumpy-793595279432e3f4627bf713ca3554c8caa3419e.tar.gz
ENH: Rename array_subscript to array_subscipt_fromobject and refactor array_subscript_nice to array_subscript
Conflicts: numpy/core/src/multiarray/mapping.c
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/mapping.c301
-rw-r--r--numpy/core/src/multiarray/mapping.h4
2 files changed, 108 insertions, 197 deletions
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index 861739695..9f09f27ca 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -926,6 +926,48 @@ array_ass_boolean_subscript(PyArrayObject *self,
}
+/* Check if ind is a tuple and if it has as many elements as arr has axes. */
+static NPY_INLINE int
+_is_full_index(PyObject *ind, PyArrayObject *arr)
+{
+ return PyTuple_Check(ind) && (PyTuple_GET_SIZE(ind) == PyArray_NDIM(arr));
+}
+
+/*
+ * Returns 0 if tuple-object seq is not a tuple of integers.
+ * If the return value is positive, vals will be filled with the elements
+ * from the tuple.
+ * Returns -1 on error.
+ */
+static int
+_tuple_of_integers(PyObject *seq, npy_intp *vals, int maxvals)
+{
+ int i;
+ PyObject *obj;
+ npy_intp temp;
+
+ for(i=0; i<maxvals; i++) {
+ obj = PyTuple_GET_ITEM(seq, i);
+ if ((PyArray_Check(obj) && PyArray_NDIM((PyArrayObject *)obj) > 0)
+ || PyList_Check(obj)) {
+ return 0;
+ }
+ temp = PyArray_PyIntAsIntp(obj);
+ if (error_converting(temp)) {
+ return 0;
+ }
+ if (!PyIndex_Check_Or_Unsupported(obj)) {
+ if (DEPRECATE("non-integer scalar index. In a future numpy "
+ "release, this will raise an error.") < 0) {
+ return -1;
+ }
+ }
+ vals[i] = temp;
+ }
+ return 1;
+}
+
+
/* return TRUE if ellipses are found else return FALSE */
static npy_bool
_check_ellipses(PyObject *op)
@@ -1002,7 +1044,7 @@ array_subscript_asarray(PyArrayObject *self, PyObject *op)
}
NPY_NO_EXPORT PyObject *
-array_subscript(PyArrayObject *self, PyObject *op)
+array_subscript_fromobject(PyArrayObject *self, PyObject *op)
{
int fancy;
npy_intp vals[NPY_MAXDIMS];
@@ -1020,65 +1062,27 @@ array_subscript(PyArrayObject *self, PyObject *op)
return array_item(self, (Py_ssize_t) value);
}
}
- /* Optimization for a tuple of integers */
- if (PyArray_NDIM(self) > 1 &&
- PyTuple_Check(op) &&
- (PyTuple_GET_SIZE(op) == PyArray_NDIM(self)) &&
- (_tuple_of_integers(op, vals, PyArray_NDIM(self)) >= 0)) {
- int idim, ndim = PyArray_NDIM(self);
- npy_intp *shape = PyArray_DIMS(self);
- npy_intp *strides = PyArray_STRIDES(self);
- char *item = PyArray_DATA(self);
-
- if (!PyArray_HASMASKNA(self)) {
- for (idim = 0; idim < ndim; idim++) {
- npy_intp v = vals[idim];
- if (v < 0) {
- v += shape[idim];
- }
- if (v < 0 || v >= shape[idim]) {
- PyErr_Format(PyExc_IndexError,
- "index (%"INTP_FMT") out of range "\
- "(0<=index<%"INTP_FMT") in dimension %d",
- vals[idim], PyArray_DIMS(self)[idim], idim);
- return NULL;
- }
- else {
- item += v * strides[idim];
- }
- }
- return PyArray_Scalar(item, PyArray_DESCR(self), (PyObject *)self);
- }
- else {
- char *maskna_item = PyArray_MASKNA_DATA(self);
- npy_intp *maskna_strides = PyArray_MASKNA_STRIDES(self);
-
+ /* optimization for a tuple of integers */
+ if (PyArray_NDIM(self) > 1 && _is_full_index(op, self)) {
+ int ret = _tuple_of_integers(op, vals, PyArray_NDIM(self));
+ /* In case an exception occurred (e.g. in PyErr_WarnEx) */
+ if (ret < 0) {
+ return NULL;
+ }
+ else if (ret > 0) {
+ int idim, ndim = PyArray_NDIM(self);
+ npy_intp *shape = PyArray_DIMS(self);
+ npy_intp *strides = PyArray_STRIDES(self);
+ char *item = PyArray_DATA(self);
for (idim = 0; idim < ndim; idim++) {
npy_intp v = vals[idim];
- if (v < 0) {
- v += shape[idim];
- }
- if (v < 0 || v >= shape[idim]) {
- PyErr_Format(PyExc_IndexError,
- "index (%"INTP_FMT") out of range "\
- "(0<=index<%"INTP_FMT") in dimension %d",
- vals[idim], PyArray_DIMS(self)[idim], idim);
- return NULL;
- }
- else {
- item += v * strides[idim];
- maskna_item += v * maskna_strides[idim];
+ if (check_and_adjust_index(&v, shape[idim], idim) < 0) {
+ return NULL;
}
- }
- if (NpyMaskValue_IsExposed((npy_mask)*maskna_item)) {
- return PyArray_Scalar(item, PyArray_DESCR(self),
- (PyObject *)self);
- }
- else {
- return (PyObject *)NpyNA_FromDTypeAndPayload(
- PyArray_DESCR(self), 0, 0);
+ item += v * strides[idim];
}
}
+ return PyArray_Scalar(item, PyArray_DESCR(self), (PyObject *)self);
}
/* Check for single field access */
@@ -1195,6 +1199,24 @@ array_subscript(PyArrayObject *self, PyObject *op)
return NULL;
}
+ fancy = fancy_indexing_check(op);
+ if (fancy != SOBJ_NOTFANCY) {
+ return array_subscript_fancy(self, op, fancy);
+ }
+ else {
+ return array_subscript_simple(self, op);
+ }
+}
+
+NPY_NO_EXPORT PyObject *
+array_subscript(PyArrayObject *self, PyObject *op)
+{
+ int fancy;
+ PyObject *ret = NULL;
+ if (!PyArray_Check(op)) {
+ ret = array_subscript_fromobject(self, op);
+ }
+
/* Boolean indexing special case */
/* The SIZE check might be overly cautious */
if (PyArray_Check(op) && (PyArray_TYPE((PyArrayObject *)op) == NPY_BOOL)
@@ -1203,13 +1225,35 @@ array_subscript(PyArrayObject *self, PyObject *op)
return (PyObject *)array_boolean_subscript(self,
(PyArrayObject *)op, NPY_CORDER);
}
-
- fancy = fancy_indexing_check(op);
- if (fancy != SOBJ_NOTFANCY) {
- return array_subscript_fancy(self, op, fancy);
+ /* Error case when indexing 0-dim array with non-boolean. */
+ else if (PyArray_NDIM(self) == 0) {
+ PyErr_SetString(PyExc_IndexError, "0-dimensional arrays can't be indexed");
+ return NULL;
}
-
- return array_subscript_simple(self, op);
+
+ else {
+ fancy = fancy_indexing_check(op);
+ if (fancy != SOBJ_NOTFANCY) {
+ ret = array_subscript_fancy(self, op, fancy);
+ }
+ else {
+ ret = array_subscript_simple(self, op);
+ }
+ }
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ if (PyErr_Occurred()) {
+ Py_XDECREF(ret);
+ return NULL;
+ }
+
+ if (PyArray_Check(ret) && PyArray_NDIM((PyArrayObject *)ret) == 0
+ && !_check_ellipses(op)) {
+ return PyArray_Return((PyArrayObject *)ret);
+ }
+ return ret;
}
/*
@@ -1267,47 +1311,6 @@ array_ass_sub_simple(PyArrayObject *self, PyObject *ind, PyObject *op)
return ret;
}
-/* Check if ind is a tuple and if it has as many elements as arr has axes. */
-static NPY_INLINE int
-_is_full_index(PyObject *ind, PyArrayObject *arr)
-{
- return PyTuple_Check(ind) && (PyTuple_GET_SIZE(ind) == PyArray_NDIM(arr));
-}
-
-/*
- * Returns 0 if tuple-object seq is not a tuple of integers.
- * If the return value is positive, vals will be filled with the elements
- * from the tuple.
- * Returns -1 on error.
- */
-static int
-_tuple_of_integers(PyObject *seq, npy_intp *vals, int maxvals)
-{
- int i;
- PyObject *obj;
- npy_intp temp;
-
- for(i=0; i<maxvals; i++) {
- obj = PyTuple_GET_ITEM(seq, i);
- if ((PyArray_Check(obj) && PyArray_NDIM((PyArrayObject *)obj) > 0)
- || PyList_Check(obj)) {
- return 0;
- }
- temp = PyArray_PyIntAsIntp(obj);
- if (error_converting(temp)) {
- return 0;
- }
- if (!PyIndex_Check_Or_Unsupported(obj)) {
- if (DEPRECATE("non-integer scalar index. In a future numpy "
- "release, this will raise an error.") < 0) {
- return -1;
- }
- }
- vals[i] = temp;
- }
- return 1;
-}
-
static int
array_ass_sub(PyArrayObject *self, PyObject *ind, PyObject *op)
{
@@ -1503,105 +1506,13 @@ array_ass_sub(PyArrayObject *self, PyObject *ind, PyObject *op)
return array_ass_sub_simple(self, ind, op);
}
-
-/*
- * There are places that require that array_subscript return a PyArrayObject
- * and not possibly a scalar. Thus, this is the function exposed to
- * Python so that 0-dim arrays are passed as scalars
- */
-
-
-static PyObject *
-array_subscript_nice(PyArrayObject *self, PyObject *op)
-{
-
- PyArrayObject *mp;
- int ret;
- npy_intp vals[NPY_MAXDIMS];
-
- if (PyInt_Check(op) || PyArray_IsScalar(op, Integer) ||
- PyLong_Check(op) || (PyIndex_Check(op) &&
- !PySequence_Check(op))) {
- npy_intp value;
- value = PyArray_PyIntAsIntp(op);
- if (PyErr_Occurred()) {
- PyErr_Clear();
- }
- else {
- return array_item(self, (Py_ssize_t) value);
- }
- }
- /*
- * Optimization for a tuple of integers that is the same size as the
- * array's dimension.
- */
- if (PyArray_NDIM(self) > 1 && _is_full_index(op, self)) {
- ret = _tuple_of_integers(op, vals, PyArray_NDIM(self));
- /* In case an exception occurred (e.g. in PyErr_WarnEx) */
- if (ret < 0) {
- return NULL;
- }
- else if (ret > 0) {
- int idim, ndim = PyArray_NDIM(self);
- npy_intp *shape = PyArray_DIMS(self);
- npy_intp *strides = PyArray_STRIDES(self);
- char *item = PyArray_DATA(self);
- for (idim = 0; idim < ndim; idim++) {
- npy_intp v = vals[idim];
- if (check_and_adjust_index(&v, shape[idim], idim) < 0) {
- return NULL;
- }
- item += v * strides[idim];
- }
- return PyArray_Scalar(item, PyArray_DESCR(self), (PyObject *)self);
- }
- }
- PyErr_Clear();
- if ((PyNumber_Check(op) || PyArray_IsScalar(op, Number)) &&
- !PyIndex_Check_Or_Unsupported(op)) {
- if (DEPRECATE("non-integer scalar index. In a future numpy "
- "release, this will raise an error.") < 0) {
- return NULL;
- }
- }
- mp = (PyArrayObject *)array_subscript(self, op);
- /*
- * mp could be a scalar if op is not an Int, Scalar, Long or other Index
- * object and still convertable to an integer (so that the code goes to
- * array_subscript_simple). So, this cast is a bit dangerous..
- */
-
- if (mp == NULL) {
- return NULL;
- }
-
- if (PyErr_Occurred()) {
- Py_XDECREF(mp);
- return NULL;
- }
-
- /*
- * The following adds some additional logic to avoid calling
- * PyArray_Return if there is an ellipsis.
- */
-
- if (PyArray_Check(mp) && PyArray_NDIM(mp) == 0) {
- if (!_check_ellipses(op)) {
- return PyArray_Return(mp);
- }
- }
-
- return (PyObject *)mp;
-}
-
-
NPY_NO_EXPORT PyMappingMethods array_as_mapping = {
#if PY_VERSION_HEX >= 0x02050000
(lenfunc)array_length, /*mp_length*/
#else
(inquiry)array_length, /*mp_length*/
#endif
- (binaryfunc)array_subscript_nice, /*mp_subscript*/
+ (binaryfunc)array_subscript, /*mp_subscript*/
(objobjargproc)array_ass_sub, /*mp_ass_subscript*/
};
diff --git a/numpy/core/src/multiarray/mapping.h b/numpy/core/src/multiarray/mapping.h
index ef08ca4f1..816b3b8e6 100644
--- a/numpy/core/src/multiarray/mapping.h
+++ b/numpy/core/src/multiarray/mapping.h
@@ -11,10 +11,10 @@ NPY_NO_EXPORT Py_ssize_t
array_length(PyArrayObject *self);
NPY_NO_EXPORT PyObject *
-array_item_asarray(PyArrayObject *self, intp i);
+array_item_asarray(PyArrayObject *self, npy_intp i);
NPY_NO_EXPORT PyObject *
-array_item_asscalar(PyArrayObject *self, intp i);
+array_item_asscalar(PyArrayObject *self, npy_intp i);
NPY_NO_EXPORT PyObject *
array_item(PyArrayObject *self, Py_ssize_t i);