summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2018-07-22 15:02:53 +0100
committerEric Wieser <wieser.eric@gmail.com>2018-07-22 18:47:31 +0100
commitc9ffde629b0f10255714b84fe75681c7f9fc4251 (patch)
tree4711620edb4db433db999be86b7768991a79ac5e /numpy
parent486a764c08c24ccba0d4baad901378112a9eec88 (diff)
downloadnumpy-c9ffde629b0f10255714b84fe75681c7f9fc4251.tar.gz
BUG: Make np.array([[1], 2]) and np.array([1, [2]]) behave in the same way
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/ctors.c40
-rw-r--r--numpy/core/tests/test_multiarray.py13
2 files changed, 34 insertions, 19 deletions
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index 4602245de..938850997 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -845,46 +845,48 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it,
return 0;
}
else {
- int maxndim_m1 = *maxndim - 1;
- PyObject *first = PySequence_Fast_GET_ITEM(seq, 0);
+ int all_elems_maxndim = *maxndim - 1;
+ npy_intp *all_elems_d = d + 1;
+ int all_dimensions_match = 1;
+ /* Get the dimensions of the first item as a baseline */
+ PyObject *first = PySequence_Fast_GET_ITEM(seq, 0);
if (discover_dimensions(
- first, &maxndim_m1, d + 1, check_it,
+ first, &all_elems_maxndim, all_elems_d, check_it,
stop_at_string, stop_at_tuple, out_is_object) < 0) {
Py_DECREF(seq);
return -1;
}
- /* For the dimension truncation check below */
- *maxndim = maxndim_m1 + 1;
+ /* Compare the dimensions of all the remaining items */
for (i = 1; i < n; ++i) {
int j;
- npy_intp dtmp[NPY_MAXDIMS];
- PyObject *elem = PySequence_Fast_GET_ITEM(seq, i);
+ int elem_maxndim = *maxndim - 1;
+ npy_intp elem_d[NPY_MAXDIMS];
- /* Get the dimensions of the remaining items */
+ PyObject *elem = PySequence_Fast_GET_ITEM(seq, i);
if (discover_dimensions(
- elem, &maxndim_m1, dtmp, check_it,
+ elem, &elem_maxndim, elem_d, check_it,
stop_at_string, stop_at_tuple, out_is_object) < 0) {
Py_DECREF(seq);
return -1;
}
- /* Reduce max_ndim_m1 to just items which match */
- for (j = 0; j < maxndim_m1; ++j) {
- if (dtmp[j] != d[j+1]) {
- maxndim_m1 = j;
+ /* Find the number of left-dimensions which match, j */
+ for (j = 0; j < elem_maxndim && j < all_elems_maxndim; ++j) {
+ if (elem_d[j] != all_elems_d[j]) {
break;
}
}
+ if (j != elem_maxndim || j != all_elems_maxndim) {
+ all_dimensions_match = 0;
+ }
+ all_elems_maxndim = j;
}
- /*
- * If the dimensions are truncated, need to produce
- * an object array.
- */
- if (maxndim_m1 + 1 < *maxndim) {
+ *maxndim = all_elems_maxndim + 1;
+ if (!all_dimensions_match) {
+ /* typically results in an array containing variable-length lists */
*out_is_object = 1;
- *maxndim = maxndim_m1 + 1;
}
}
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index e85a73154..07d1361d6 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -903,6 +903,19 @@ class TestCreation(object):
assert_raises(ValueError, np.ndarray, buffer=buf, strides=(0,),
shape=(max_bytes//itemsize + 1,), dtype=dtype)
+ def test_jagged_ndim_object(self):
+ # Lists of mismatching depths are treated as object arrays
+ a = np.array([[1], 2, 3])
+ assert_equal(a.shape, (3,))
+ assert_equal(a.dtype, object)
+
+ a = np.array([1, [2], 3])
+ assert_equal(a.shape, (3,))
+ assert_equal(a.dtype, object)
+
+ a = np.array([1, 2, [3]])
+ assert_equal(a.shape, (3,))
+ assert_equal(a.dtype, object)
class TestStructured(object):
def test_subarray_field_access(self):