8000 BUG: raise error for erroneous structured array assignment by mbyt · Pull Request #4556 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: raise error for erroneous structured array assignment #4556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions numpy/core/src/multiarray/scalartypes.c.src
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,22 @@ voidtype_setfield(PyVoidScalarObject *self, PyObject *args, PyObject *kwds)
Py_DECREF(typecode);
}
else {
/* method voidtype_setfield sets per definition a void field,
* not an array or a broadcast to an array. */
if ((typecode->subarray != NULL) ||
#if defined(NPY_PY3K)
(!PyUString_Check(value) &&
#else
(!PyBytes_Check(value) && !PyUnicode_Check(value) &&
#endif
PySequence_Check(value) &&
PySequence_Length(value) > 1)) {
PyErr_Format(PyExc_ValueError,
"Incompatible assignment of sequence to numpy scalar. " \
"Left hand [:] for slice assignment might be missing.");
return NULL;
}

/* Copy data from value to correct place in dptr */
src = (PyArrayObject *)PyArray_FromAny(value, typecode,
0, 0, NPY_ARRAY_CARRAY, NULL);
Expand Down
51 changes: 50 additions & 1 deletion numpy/core/tests/test_multiarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,8 @@ def test_subarray_comparison(self):
assert_equal(a==b, [True, False])
assert_equal(a!=b, [False, True])
for i in range(3):
b[0].a = a[0].a
b[0].a[:] = a[0].a
assert_equal(b[0].a, a[0].a)
b[0].a[i] = 5
assert_equal(a==b, [False, False])
assert_equal(a!=b, [True, True])
Expand Down Expand Up @@ -3385,6 +3386,54 @@ def test_record_no_hash(self):
a = np.array([(1, 2), (1, 2)], dtype='i1,i2')
self.assertRaises(TypeError, hash, a[0])

def test_structured_array_assignment(self):
# see also #3126
struct_dt = np.dtype([('elem', 'i4', 5)])
dt = np.dtype([
('field', 'i4', 10),
('struct', struct_dt),
('field_of_struct', struct_dt, 3),
('elem', 'i4'),
])
# correct slice assignments
x = np.zeros(1, dt)
x[0]['field'][:] = np.ones(10, dtype='i4')
assert_array_equal(x[0]['field'], 1)
fos = np.ones(3, dtype=struct_dt)
x[0]['field_of_struct'][:] = fos
assert_array_equal(x[0]['field_of_struct'], fos)
# incorrect slice assignment
def f():
x[0]['field'][:] = np.ones(9, dtype='i4')
self.assertRaises(ValueError, f)
# no slice assignment
x = np.zeros(1, dt)
s = np.ones(1, dtype=struct_dt)
x[0]['struct'] = s
assert_array_equal(x[0]['struct'], s)
x['elem'] = 2
self.assertEqual(x['elem'], 2)
x[0]['elem'] = 3
self.assertEqual(x['elem'], 3)
# incorrect no slice assignment, #3126
def f():
x[0]['field'] = np.ones(10, dtype='i4')
self.assertRaises(ValueError, f)
def f():
x[0]['field'] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
self.assertRaises(ValueError, f)
# see #3561
def f():
x[0]['field'] = 1
self.assertRaises(ValueError, f)
def f():
x[0]['struct'] = np.ones(3, dtype=struct_dt)
self.assertRaises(ValueError, f)
y = x.copy()
def f():
x[0]['field'] = y[0]['field']
self.assertRaises(ValueError, f)

class TestView(TestCase):
def test_basic(self):
x = np.array([(1, 2, 3, 4), (5, 6, 7, 8)], dtype=[('r', np.int8), ('g', np.int8),
Expand Down
0