Skip to content

Commit

Permalink
allow assignment with multiple same indices as susbscripting. Limit t…
Browse files Browse the repository at this point in the history
…o 1 ellipsis object for 0d array subscripting.
  • Loading branch information
teoliphant committed Jan 11, 2006
1 parent 04d7338 commit ba52e16
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 35 deletions.
2 changes: 1 addition & 1 deletion THANKS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ Travis Vaught and Joe Cooper for administration of numpy.org web site and SVN
Eric Firing for bugfixes.
Arnd Baecker for 64-bit testing
David Cooke for many code improvements including the auto-generated C-API
Alexander Belopolsky (sasha) for Masked array bug-fixes and tests...
Alexander Belopolsky (sasha) for Masked array bug-fixes and tests and rank-0 array improvements
70 changes: 36 additions & 34 deletions numpy/core/src/arrayobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,42 +1742,25 @@ PyArray_SetMap(PyArrayMapIterObject *mit, PyObject *op)
return 0;
}

/* Called when treating array object like a mapping -- called first from
Python when using a[object] unless object is a standard slice object
(not an extended one).
*/

/* There are two situations:
1 - the subscript is a standard view and a reference to the
array can be returned
2 - the subscript uses Boolean masks or integer indexing and
therefore a new array is created and returned.
*/

/* Always returns arrays */

static PyObject *iter_subscript(PyArrayIterObject *, PyObject *);

int
count_new_axes_0d(PyObject *tuple)
{
int i, argument_count;
int ellipsis_count = 0;
int newaxis_count = 0;

argument_count = PyTuple_GET_SIZE(tuple);

for (i = 0; i < argument_count; ++i) {
PyObject *arg = PyTuple_GET_ITEM(tuple, i);
ellipsis_count += (arg == Py_Ellipsis);
newaxis_count += (arg == Py_None);
if (arg == Py_Ellipsis && !ellipsis_count) ellipsis_count++;
else if (arg == Py_None) newaxis_count++;
else break;
}
if (newaxis_count + ellipsis_count != argument_count) {
if (i < argument_count) {
PyErr_SetString(PyExc_IndexError,
"0-d arrays can only use a single ()"
" or a list of ellipses and newaxes"
" or a list of newaxes (and a single ...)"
" as an index");
return -1;
}
Expand All @@ -1787,34 +1770,51 @@ count_new_axes_0d(PyObject *tuple)
return -1;
}
return newaxis_count;

}

static PyObject *
add_new_axes_0d(PyArrayObject *arr, int newaxis_count)
{
PyArrayObject *other;
intp dimensions[MAX_DIMS], strides[MAX_DIMS];
intp dimensions[MAX_DIMS];
int i;
for (i = 0; i < newaxis_count; ++i) {
dimensions[i] = strides[i] = 1;
dimensions[i] = 1;
}
Py_INCREF(arr->descr);
if ((other = (PyArrayObject *)
PyArray_NewFromDescr(arr->ob_type, arr->descr,
newaxis_count, dimensions,
strides, arr->data,
NULL, arr->data,
arr->flags,
(PyObject *)arr)) == NULL)
return NULL;

other->base = (PyObject *)arr;
Py_INCREF(arr);

other ->flags &= ~OWNDATA;

return (PyObject *)other;
}

/* Called when treating array object like a mapping -- called first from
Python when using a[object] unless object is a standard slice object
(not an extended one).
*/

/* There are two situations:
1 - the subscript is a standard view and a reference to the
array can be returned
2 - the subscript uses Boolean masks or integer indexing and
therefore a new array is created and returned.
*/

/* Always returns arrays */

static PyObject *iter_subscript(PyArrayIterObject *, PyObject *);


static PyObject *
array_subscript(PyArrayObject *self, PyObject *op)
{
Expand Down Expand Up @@ -1999,8 +1999,9 @@ array_ass_sub(PyArrayObject *self, PyObject *index, PyObject *op)
}

if (self->nd == 0) {
if (index == Py_Ellipsis || (PyTuple_Check(index) && \
0 == PyTuple_GET_SIZE(index)))
if (index == Py_Ellipsis || index == Py_None || \
(PyTuple_Check(index) && (0 == PyTuple_GET_SIZE(index) || \
count_new_axes_0d(index) > 0)))
return self->descr->f->setitem(op, self->data, self);
PyErr_SetString(PyExc_IndexError,
"0-d arrays can't be indexed.");
Expand Down Expand Up @@ -2049,6 +2050,7 @@ array_ass_sub(PyArrayObject *self, PyObject *index, PyObject *op)
return ret;
}


/* 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
Expand Down

0 comments on commit ba52e16

Please sign in to comment.