diff options
author | Bryan Van de Ven <bryan@Laptop-3.local> | 2012-02-24 16:21:57 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2012-03-02 18:32:33 -0700 |
commit | 09f01d825e38298f02d4b5f50fb814c0b34db98f (patch) | |
tree | 75bb403a38a0a6907b92c58b4bc15abaf491957c | |
parent | b9872b41422e33c9910829cd54268a510ec9436b (diff) | |
download | numpy-09f01d825e38298f02d4b5f50fb814c0b34db98f.tar.gz |
BUG: fix ticket #2029.
The fix is to disallow views of masked arrays if the element size
of the view is different than that of the original.
-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) |