summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/descriptor.c5
-rw-r--r--numpy/core/src/multiarray/flagsobject.c45
-rw-r--r--numpy/core/src/multiarray/getset.c2
-rw-r--r--numpy/core/src/multiarray/iterators.c6
-rw-r--r--numpy/core/src/multiarray/na_object.c13
-rw-r--r--numpy/core/src/multiarray/nditer_pywrap.c57
-rw-r--r--numpy/core/tests/test_dtype.py18
-rw-r--r--numpy/core/tests/test_multiarray.py41
-rw-r--r--numpy/core/tests/test_na.py8
-rw-r--r--numpy/core/tests/test_nditer.py28
10 files changed, 185 insertions, 38 deletions
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index 3f2da284d..1bb439dcf 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -1807,6 +1807,11 @@ arraydescr_names_set(PyArray_Descr *self, PyObject *val)
PyObject *new_names;
PyObject *new_fields;
+ if (val == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete dtype names attribute");
+ return -1;
+ }
if (!PyDataType_HASFIELDS(self)) {
PyErr_SetString(PyExc_ValueError,
"there are no fields defined");
diff --git a/numpy/core/src/multiarray/flagsobject.c b/numpy/core/src/multiarray/flagsobject.c
index 9ada8a26b..a633a2ac2 100644
--- a/numpy/core/src/multiarray/flagsobject.c
+++ b/numpy/core/src/multiarray/flagsobject.c
@@ -276,8 +276,14 @@ arrayflags_maskna_get(PyArrayFlagsObject *self)
static int
arrayflags_maskna_set(PyArrayFlagsObject *self, PyObject *obj)
{
+ if (obj == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete flags maskna attribute");
+ return -1;
+ }
if (self->arr == NULL) {
- PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot set flags on array scalars.");
return -1;
}
@@ -287,7 +293,7 @@ arrayflags_maskna_set(PyArrayFlagsObject *self, PyObject *obj)
else {
if (self->flags & NPY_ARRAY_MASKNA) {
PyErr_SetString(PyExc_ValueError,
- "Cannot remove a NumPy array's NA mask");
+ "Cannot remove a NumPy array's NA mask");
return -1;
}
else {
@@ -313,8 +319,14 @@ arrayflags_ownmaskna_get(PyArrayFlagsObject *self)
static int
arrayflags_ownmaskna_set(PyArrayFlagsObject *self, PyObject *obj)
{
+ if (obj == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete flags ownmaskna attributes");
+ return -1;
+ }
if (self->arr == NULL) {
- PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot set flags on array scalars.");
return -1;
}
@@ -338,8 +350,15 @@ static int
arrayflags_updateifcopy_set(PyArrayFlagsObject *self, PyObject *obj)
{
PyObject *res;
+
+ if (obj == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete flags updateifcopy attribute");
+ return -1;
+ }
if (self->arr == NULL) {
- PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot set flags on array scalars.");
return -1;
}
res = PyObject_CallMethod(self->arr, "setflags", "OOO", Py_None, Py_None,
@@ -355,8 +374,15 @@ static int
arrayflags_aligned_set(PyArrayFlagsObject *self, PyObject *obj)
{
PyObject *res;
+
+ if (obj == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete flags aligned attribute");
+ return -1;
+ }
if (self->arr == NULL) {
- PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot set flags on array scalars.");
return -1;
}
res = PyObject_CallMethod(self->arr, "setflags", "OOO", Py_None,
@@ -373,8 +399,15 @@ static int
arrayflags_writeable_set(PyArrayFlagsObject *self, PyObject *obj)
{
PyObject *res;
+
+ if (obj == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete flags writeable attribute");
+ return -1;
+ }
if (self->arr == NULL) {
- PyErr_SetString(PyExc_ValueError, "Cannot set flags on array scalars.");
+ PyErr_SetString(PyExc_ValueError,
+ "Cannot set flags on array scalars.");
return -1;
}
res = PyObject_CallMethod(self->arr, "setflags", "OOO",
diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c
index 14042c9af..d3146dc5c 100644
--- a/numpy/core/src/multiarray/getset.c
+++ b/numpy/core/src/multiarray/getset.c
@@ -941,7 +941,7 @@ NPY_NO_EXPORT PyGetSetDef array_getsetlist[] = {
(getter)array_ctypes_get,
NULL,
NULL, NULL},
- { "T",
+ {"T",
(getter)array_transpose_get,
NULL,
NULL, NULL},
diff --git a/numpy/core/src/multiarray/iterators.c b/numpy/core/src/multiarray/iterators.c
index 2c173e3e9..44163a0bd 100644
--- a/numpy/core/src/multiarray/iterators.c
+++ b/numpy/core/src/multiarray/iterators.c
@@ -1037,6 +1037,12 @@ iter_ass_subscript(PyArrayIterObject *self, PyObject *ind, PyObject *val)
PyArray_CopySwapFunc *copyswap;
+ if (val == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot delete iterator elements");
+ return -1;
+ }
+
if (ind == Py_Ellipsis) {
ind = PySlice_New(NULL, NULL, NULL);
retval = iter_ass_subscript(self, ind, val);
diff --git a/numpy/core/src/multiarray/na_object.c b/numpy/core/src/multiarray/na_object.c
index ed319a348..45e199fbe 100644
--- a/numpy/core/src/multiarray/na_object.c
+++ b/numpy/core/src/multiarray/na_object.c
@@ -184,6 +184,12 @@ na_payload_set(NpyNA_fields *self, PyObject *value)
{
long payload;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete NA payload attribute");
+ return -1;
+ }
+
/* Don't allow changing the static singleton instance */
if (self->is_singleton) {
PyErr_SetString(PyExc_RuntimeError,
@@ -191,7 +197,7 @@ na_payload_set(NpyNA_fields *self, PyObject *value)
"make a new copy like 'numpy.NA(payload)'");
return -1;
}
- else if (value == NULL || value == Py_None) {
+ else if (value == Py_None) {
self->payload = NPY_NA_NOPAYLOAD;
}
else {
@@ -241,6 +247,11 @@ na_dtype_set(NpyNA_fields *self, PyObject *value)
{
PyArray_Descr *dtype = NULL;
+ if (value == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete NA dtype attribute");
+ return -1;
+ }
/* Don't allow changing the static singleton instance */
if (self->is_singleton) {
PyErr_SetString(PyExc_RuntimeError,
diff --git a/numpy/core/src/multiarray/nditer_pywrap.c b/numpy/core/src/multiarray/nditer_pywrap.c
index c0323c346..42d836633 100644
--- a/numpy/core/src/multiarray/nditer_pywrap.c
+++ b/numpy/core/src/multiarray/nditer_pywrap.c
@@ -1612,15 +1612,14 @@ npyiter_multi_index_set(NewNpyArrayIterObject *self, PyObject *value)
{
npy_intp idim, ndim, multi_index[NPY_MAXDIMS];
- if (self->iter == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "Iterator is invalid");
+ if (value == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete nditer multi_index");
return -1;
}
-
- if (value == NULL) {
+ if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
- "Cannot delete the multi_index");
+ "Iterator is invalid");
return -1;
}
@@ -1684,15 +1683,14 @@ static PyObject *npyiter_index_get(NewNpyArrayIterObject *self)
static int npyiter_index_set(NewNpyArrayIterObject *self, PyObject *value)
{
- if (self->iter == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "Iterator is invalid");
+ if (value == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete nditer index");
return -1;
}
-
- if (value == NULL) {
+ if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
- "Cannot delete index");
+ "Iterator is invalid");
return -1;
}
@@ -1737,15 +1735,14 @@ static int npyiter_iterindex_set(NewNpyArrayIterObject *self, PyObject *value)
{
npy_intp iterindex;
- if (self->iter == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "Iterator is invalid");
+ if (value == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete nditer iterindex");
return -1;
}
-
- if (value == NULL) {
+ if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
- "Cannot delete iterindex");
+ "Iterator is invalid");
return -1;
}
@@ -1799,15 +1796,14 @@ static int npyiter_iterrange_set(NewNpyArrayIterObject *self, PyObject *value)
long istart = 0, iend = 0;
#endif
- if (self->iter == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "Iterator is invalid");
+ if (value == NULL) {
+ PyErr_SetString(PyExc_AttributeError,
+ "Cannot delete nditer iterrange");
return -1;
}
-
- if (value == NULL) {
+ if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
- "Cannot delete iterrange");
+ "Iterator is invalid");
return -1;
}
@@ -2173,8 +2169,8 @@ npyiter_seq_ass_item(NewNpyArrayIterObject *self, Py_ssize_t i, PyObject *v)
if (v == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "can't delete iterator operands");
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot delete iterator elements");
return -1;
}
@@ -2271,8 +2267,8 @@ npyiter_seq_ass_slice(NewNpyArrayIterObject *self, Py_ssize_t ilow,
Py_ssize_t i;
if (v == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "cannot delete iterator elements");
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot delete iterator elements");
return -1;
}
@@ -2376,6 +2372,11 @@ static int
npyiter_ass_subscript(NewNpyArrayIterObject *self, PyObject *op,
PyObject *value)
{
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot delete iterator elements");
+ return -1;
+ }
if (self->iter == NULL || self->finished) {
PyErr_SetString(PyExc_ValueError,
"Iterator is past the end");
diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py
index 3625d58b4..ba9de32ba 100644
--- a/numpy/core/tests/test_dtype.py
+++ b/numpy/core/tests/test_dtype.py
@@ -401,5 +401,23 @@ class TestString(TestCase):
"dtype([('a', '<M8[D]'), ('b', '<m8[us]')])")
+class TestDtypeAttributeDeletion(object):
+
+ def test_dtype_non_writable_attributes_deletion(self):
+ dt = np.dtype(np.double)
+ attr = ["subdtype", "descr", "str", "name", "base", "shape",
+ "isbuiltin", "isnative", "isalignedstruct", "fields",
+ "metadata", "hasobject"]
+ for s in attr:
+ assert_raises(AttributeError, delattr, dt, s)
+
+
+ def test_dtype_writable_attributes_deletion(self):
+ dt = np.dtype(np.double)
+ attr = ["names"]
+ for s in attr:
+ assert_raises(AttributeError, delattr, dt, s)
+
+
if __name__ == "__main__":
run_module_suite()
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 6d402c3ec..086a38128 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -2309,14 +2309,51 @@ if sys.version_info >= (2, 6):
class TestArrayAttributeDeletion(object):
- """ticket #2046, should not seqfault, raise AttributeError"""
- def test_attribute_deletion(self):
+ def test_multiarray_writable_attributes_deletion(self):
+ """ticket #2046, should not seqfault, raise AttributeError"""
a = np.ones(2)
attr = ['shape', 'strides', 'data', 'dtype', 'real', 'imag', 'flat']
for s in attr:
assert_raises(AttributeError, delattr, a, s)
+ def test_multiarray_not_writable_attributes_deletion(self):
+ a = np.ones(2)
+ attr = ["ndim", "flags", "itemsize", "size", "nbytes", "base",
+ "ctypes", "T", "__array_interface__", "__array_struct__",
+ "__array_priority__", "__array_finalize__"]
+ for s in attr:
+ assert_raises(AttributeError, delattr, a, s)
+
+
+ def test_multiarray_flags_writable_attribute_deletion(self):
+ a = np.ones(2).flags
+ attr = ['updateifcopy', 'aligned', 'writeable', 'maskna',
+ 'ownmaskna']
+ for s in attr:
+ assert_raises(AttributeError, delattr, a, s)
+
+
+ def test_multiarray_flags_not_writable_attribute_deletion(self):
+ a = np.ones(2).flags
+ attr = ["contiguous", "c_contiguous", "f_contiguous", "fortran",
+ "owndata", "fnc", "forc", "behaved", "carray", "farray",
+ "num"]
+ for s in attr:
+ assert_raises(AttributeError, delattr, a, s)
+
+
+def test_flat_element_deletion():
+ it = np.ones(3).flat
+ try:
+ del it[1]
+ del it[1:2]
+ except TypeError:
+ pass
+ except:
+ raise AssertionError
+
+
if __name__ == "__main__":
run_module_suite()
diff --git a/numpy/core/tests/test_na.py b/numpy/core/tests/test_na.py
index 2950598f8..eb92a0035 100644
--- a/numpy/core/tests/test_na.py
+++ b/numpy/core/tests/test_na.py
@@ -186,5 +186,13 @@ def test_na_other_operations():
assert_equal((np.NA | False).dtype, np.array(False).dtype)
assert_equal((np.NA & True).dtype, np.array(True).dtype)
+
+def test_na_writable_attributes_deletion():
+ a = np.NA(2)
+ attr = ['payload', 'dtype']
+ for s in attr:
+ assert_raises(AttributeError, delattr, a, s)
+
+
if __name__ == "__main__":
run_module_suite()
diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py
index b0badc2d9..5bc3b8dee 100644
--- a/numpy/core/tests/test_nditer.py
+++ b/numpy/core/tests/test_nditer.py
@@ -2554,5 +2554,33 @@ def test_iter_maskna_default_use_maskna():
assert_(it.operands[2].flags.maskna)
assert_array_equal(it.operands[2], a+b+1)
+
+def test_iter_writable_attribute_deletion():
+ it = np.nditer(np.ones(2))
+ attr = ["value", "shape", "operands", "itviews", "has_delayed_bufalloc",
+ "iterationneedsapi", "has_multi_index", "has_index", "dtypes",
+ "ndim", "nop", "itersize", "finished"]
+ for s in attr:
+ assert_raises(AttributeError, delattr, it, s)
+
+
+def test_iter_non_writable_attribute_deletion():
+ it = np.nditer(np.ones(2))
+ attr = [ "multi_index", "index", "iterrange", "iterindex"]
+ for s in attr:
+ assert_raises(AttributeError, delattr, it, s)
+
+
+def test_iter_element_deletion():
+ it = np.nditer(np.ones(3))
+ try:
+ del it[1]
+ del it[1:2]
+ except TypeError:
+ pass
+ except:
+ raise AssertionError
+
+
if __name__ == "__main__":
run_module_suite()