diff options
-rw-r--r-- | numpy/core/src/multiarray/getset.c | 19 | ||||
-rw-r--r-- | numpy/core/tests/test_maskna.py | 26 |
2 files changed, 39 insertions, 6 deletions
diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c index d3146dc5c..db107ed61 100644 --- a/numpy/core/src/multiarray/getset.c +++ b/numpy/core/src/multiarray/getset.c @@ -414,7 +414,6 @@ array_nbytes_get(PyArrayObject *self) * (contiguous or fortran) with compatibile dimensions The shape and strides * will be adjusted in that case as well. */ - static int array_descr_set(PyArrayObject *self, PyObject *arg) { @@ -431,16 +430,24 @@ array_descr_set(PyArrayObject *self, PyObject *arg) if (!(PyArray_DescrConverter(arg, &newtype)) || newtype == NULL) { - PyErr_SetString(PyExc_TypeError, "invalid data-type for array"); + PyErr_SetString(PyExc_TypeError, + "invalid data-type for array"); + return -1; + } + + if (PyArray_HASMASKNA(self) && + newtype->elsize != PyArray_DESCR(self)->elsize) { + PyErr_SetString(PyExc_TypeError, + "view cannot change element size of NA-masked array"); return -1; } + if (PyDataType_FLAGCHK(newtype, NPY_ITEM_HASOBJECT) || PyDataType_FLAGCHK(newtype, NPY_ITEM_IS_POINTER) || PyDataType_FLAGCHK(PyArray_DESCR(self), NPY_ITEM_HASOBJECT) || PyDataType_FLAGCHK(PyArray_DESCR(self), NPY_ITEM_IS_POINTER)) { - PyErr_SetString(PyExc_TypeError, \ - "Cannot change data-type for object " \ - "array."); + PyErr_SetString(PyExc_TypeError, + "Cannot change data-type for object array."); Py_DECREF(newtype); return -1; } @@ -457,7 +464,7 @@ array_descr_set(PyArrayObject *self, PyObject *arg) /* But no other flexible types */ else { PyErr_SetString(PyExc_TypeError, - "data-type must not be 0-sized"); + "data-type must not be 0-sized"); Py_DECREF(newtype); return -1; } diff --git a/numpy/core/tests/test_maskna.py b/numpy/core/tests/test_maskna.py index 341ed0bc2..e17798db4 100644 --- a/numpy/core/tests/test_maskna.py +++ b/numpy/core/tests/test_maskna.py @@ -3,6 +3,7 @@ from numpy.compat import asbytes from numpy.testing import * import sys, warnings from numpy.testing.utils import WarningManager +import itertools def test_array_maskna_flags(): a = np.arange(3) @@ -456,6 +457,31 @@ def test_array_maskna_view_function(): assert_(c.flags.maskna) assert_(c.flags.ownmaskna) +def test_array_maskna_view_dtype(): + tcs = np.typecodes['AllFloat'] + \ + np.typecodes['AllInteger'] + \ + np.typecodes['Complex'] + + same_size = [] + diff_size = [] + for x in itertools.combinations(tcs, 2): + if np.dtype(x[0]).itemsize == np.dtype(x[1]).itemsize: + same_size.append(x) + else: diff_size.append(x) + + for (from_type, to_type) in diff_size: + a = np.arange(10, dtype=from_type, maskna=True) + + # Ensure that a view of a masked array cannot change to + # different sized dtype + assert_raises(TypeError, a.view, to_type) + + for (from_type, to_type) in same_size: + a = np.arange(10, dtype=from_type, maskna=True) + + # Ensure that a view of a masked array can change to + # same sized dtype + b = a.view(dtype=to_type) def test_array_maskna_array_function_1D(): a = np.arange(10) |