8000 Merge pull request #4109 from seberg/scalar-object-indexing · numpy/numpy@09f139a · GitHub
[go: up one dir, main page]

Skip to content

Commit 09f139a

Browse files
committed
Merge pull request #4109 from seberg/scalar-object-indexing
BUG: Fix object scalar return type of 0-d array indices
2 parents 4a9d23b + e607806 commit 09f139a

File tree

2 files changed

+49
-11
lines changed

2 files changed

+49
-11
lines changed

numpy/core/src/multiarray/mapping.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,7 @@ array_subscript_fromobject(PyArrayObject *self, PyObject *op)
10461046
}
10471047
}
10481048
/* optimization for a tuple of integers */
1049-
if (PyArray_NDIM(self) > 1 && _is_full_index(op, self)) {
1049+
if (_is_full_index(op, self)) {
10501050
int ret = _tuple_of_integers(op, vals, PyArray_NDIM(self));
10511051

10521052
if (ret > 0) {
@@ -1182,7 +1182,18 @@ array_subscript_fromobject(PyArrayObject *self, PyObject *op)
11821182

11831183
fancy = fancy_indexing_check(op);
11841184
if (fancy != SOBJ_NOTFANCY) {
1185-
return array_subscript_fancy(self, op, fancy);
1185+
PyObject *ret;
1186+
1187+
ret = array_subscript_fancy(self, op, fancy);
1188+
if (ret == NULL) {
1189+
return NULL;
1190+
}
1191+
if (PyArray_Check(ret) &&
1192+
PyArray_NDIM((PyArrayObject *)ret) == 0 &&
1193+
!_check_ellipses(op)) {
1194+
return PyArray_Return((PyArrayObject *)ret);
1195+
}
1196+
return ret;
11861197
}
11871198
else {
11881199
return array_subscript_simple(self, op, 1);
@@ -1195,7 +1206,7 @@ array_subscript(PyArrayObject *self, PyObject *op)
11951206
int fancy;
11961207
PyObject *ret = NULL;
11971208
if (!PyArray_Check(op)) {
1198-
ret = array_subscript_fromobject(self, op);
1209+
return array_subscript_fromobject(self, op);
11991210
}
12001211

12011212
/* Boolean indexing special case */
@@ -1223,14 +1234,6 @@ array_subscript(PyArrayObject *self, PyObject *op)
12231234
}
12241235
}
12251236

1226-
if (ret == NULL) {
1227-
return NULL;
1228-
}
1229-
1230-
if (PyArray_Check(ret) && PyArray_NDIM((PyArrayObject *)ret) == 0
1231-
&& !_check_ellipses(op)) {
1232-
return PyArray_Return((PyArrayObject *)ret);
1233-
}
12341237
return ret;
12351238
}
12361239

numpy/core/tests/test_indexing.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,32 @@ def test_empty_tuple_index(self):
2222
a = np.array(0)
2323
assert_(isinstance(a[()], np.int_))
2424

25+
def test_scalar_return_type(self):
26+
# Full scalar indices should return scalars and object
27+
# arrays should not call PyArray_Return on their items
28+
class Zero(object):
29+
# The most basic valid indexing
30+
def __index__(self):
31+
return 0
32+
z = Zero()
33+
34+
a = np.zeros(())
35+
assert_(isinstance(a[()], np.float_))
36+
a = np.zeros(1)
37+
assert_(isinstance(a[z], np.float_))
38+
a = np.zeros((1, 1))
39+
assert_(isinstance(a[z, np.array(0)], np.float_))
40+
41+
# And object arrays do not call it too often:
42+
b = np.array(0)
43+
a = np.array(0, dtype=object)
44+
a[()] = b
45+
assert_(isinstance(a[()], np.ndarray))
46+
a = np.array([b, None])
47+
assert_(isinstance(a[z], np.ndarray))
48+
a = np.array([[b, None]])
49+
assert_(isinstance(a[z, np.array(0)], np.ndarray))
50+
2551
def test_empty_fancy_index(self):
2652
# Empty list index creates an empty array
2753
# with the same dtype (but with weird shape)
@@ -124,6 +150,15 @@ def test_boolean_indexing_twodim(self):
124150
[0, 8, 0]])
125151

126152

153+
class TestFieldIndexing(TestCase):
154+
def test_scalar_return_type(self):
155+
# Field access on an array should return an array, even if it
156+
# is 0-d.
157+
a = np.zeros((), [('a','f8')])
158+
assert_(isinstance(a['a'], np.ndarray))
159+
assert_(isinstance(a[['a']], np.ndarray))
160+
161+
127162
class TestMultiIndexingAutomated(TestCase):
128163
"""
129164
These test use code to mimic the C-Code indexing for selection.

0 commit comments

Comments
 (0)
0