diff options
author | Pauli Virtanen <pav@iki.fi> | 2010-10-10 20:09:20 +0200 |
---|---|---|
committer | Pauli Virtanen <pav@iki.fi> | 2010-10-10 20:09:20 +0200 |
commit | a16ee31eab9d75d86b2fde2ea4d6787b5f61ea9e (patch) | |
tree | 446496fedd5cf66fa69a692f9695858f7927fe50 /numpy | |
parent | 2be89147998f59371077b684096ae226f7294ab2 (diff) | |
download | numpy-a16ee31eab9d75d86b2fde2ea4d6787b5f61ea9e.tar.gz |
BUG: core: fix duplicate name problems in dtype.names setting (#1598)
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 27 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 6 |
2 files changed, 26 insertions, 7 deletions
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 74cb7da7a..f635e1c48 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -1828,6 +1828,7 @@ arraydescr_names_set(PyArray_Descr *self, PyObject *val) int N = 0; int i; PyObject *new_names; + PyObject *new_fields; if (self->names == NULL) { PyErr_SetString(PyExc_ValueError, "there are no fields defined"); @@ -1857,26 +1858,38 @@ arraydescr_names_set(PyArray_Descr *self, PyObject *val) } /* Update dictionary keys in fields */ new_names = PySequence_Tuple(val); + new_fields = PyDict_New(); for (i = 0; i < N; i++) { PyObject *key; PyObject *item; PyObject *new_key; + int ret; key = PyTuple_GET_ITEM(self->names, i); - /* Borrowed reference to item */ + /* Borrowed references to item and new_key */ item = PyDict_GetItem(self->fields, key); - /* Hold on to it even through DelItem */ - Py_INCREF(item); new_key = PyTuple_GET_ITEM(new_names, i); - PyDict_DelItem(self->fields, key); - PyDict_SetItem(self->fields, new_key, item); - /* self->fields now holds reference */ - Py_DECREF(item); + /* Check for duplicates */ + ret = PyDict_Contains(new_fields, new_key); + if (ret != 0) { + if (ret < 0) { + PyErr_Clear(); + } + PyErr_SetString(PyExc_ValueError, "Duplicate field names given."); + Py_DECREF(new_names); + Py_DECREF(new_fields); + return -1; + } + PyDict_SetItem(new_fields, new_key, item); } /* Replace names */ Py_DECREF(self->names); self->names = new_names; + /* Replace fields */ + Py_DECREF(self->fields); + self->fields = new_fields; + return 0; } diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 249a0a3a6..52548ca1a 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -1420,5 +1420,11 @@ class TestRegression(TestCase): x = 2**64 - 1 assert_equal(int(np.uint64(x)), x) + def test_duplicate_field_names_assign(self): + ra = np.fromiter(((i*3, i*2) for i in xrange(10)), dtype='i8,f8') + ra.dtype.names = ('f1', 'f2') + rep = repr(ra) # should not cause a segmentation fault + assert_raises(ValueError, setattr, ra.dtype, 'names', ('f1', 'f1')) + if __name__ == "__main__": run_module_suite() |