summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/src/multiarray/buffer.c16
-rw-r--r--numpy/core/tests/test_multiarray.py13
2 files changed, 24 insertions, 5 deletions
diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c
index e76d406de..f892cf6cd 100644
--- a/numpy/core/src/multiarray/buffer.c
+++ b/numpy/core/src/multiarray/buffer.c
@@ -12,6 +12,7 @@
#include "npy_pycompat.h"
#include "buffer.h"
+#include "common.h"
#include "numpyos.h"
#include "arrayobject.h"
@@ -243,14 +244,19 @@ _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str,
child = (PyArray_Descr*)PyTuple_GetItem(item, 0);
offset_obj = PyTuple_GetItem(item, 1);
- new_offset = base_offset + PyInt_AsLong(offset_obj);
+ new_offset = PyInt_AsLong(offset_obj);
+ if (error_converting(new_offset)) {
+ return -1;
+ }
+ new_offset += base_offset;
/* Insert padding manually */
if (*offset > new_offset) {
- PyErr_SetString(PyExc_RuntimeError,
- "This should never happen: Invalid offset in "
- "buffer format string generation. Please "
- "report a bug to the Numpy developers.");
+ PyErr_SetString(
+ PyExc_ValueError,
+ "dtypes with overlapping or out-of-order fields are not "
+ "representable as buffers. Consider reordering the fields."
+ );
return -1;
}
while (*offset < new_offset) {
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index e54d67a0d..c72009e7f 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -6453,6 +6453,19 @@ class TestNewBufferProtocol(object):
shape, strides = get_buffer_info(arr, ['C_CONTIGUOUS'])
assert_(strides[-1] == 8)
+ def test_out_of_order_fields(self):
+ dt = np.dtype(dict(
+ formats=['<i4', '<i4'],
+ names=['one', 'two'],
+ offsets=[4, 0],
+ itemsize=8
+ ))
+
+ # overlapping fields cannot be represented by PEP3118
+ arr = np.empty(1, dt)
+ with assert_raises(ValueError):
+ memoryview(arr)
+
class TestArrayAttributeDeletion(object):