summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/buffer.c11
-rw-r--r--numpy/core/tests/test_multiarray.py7
2 files changed, 17 insertions, 1 deletions
diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c
index f64f7215a..9f1ddc1f7 100644
--- a/numpy/core/src/multiarray/buffer.c
+++ b/numpy/core/src/multiarray/buffer.c
@@ -220,6 +220,8 @@ _buffer_format_string(PyArray_Descr *descr, _tmp_string_t *str,
return ret;
}
else if (PyDataType_HASFIELDS(descr)) {
+ int base_offset = *offset;
+
_append_str(str, "T{");
for (k = 0; k < PyTuple_GET_SIZE(descr->names); ++k) {
PyObject *name, *item, *offset_obj, *tmp;
@@ -233,9 +235,16 @@ _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 = PyInt_AsLong(offset_obj);
+ new_offset = base_offset + PyInt_AsLong(offset_obj);
/* 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.");
+ return -1;
+ }
while (*offset < new_offset) {
_append_char(str, 'x');
++*offset;
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index 9582e5f2e..7cdd45eb0 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -1945,6 +1945,9 @@ if sys.version_info >= (2, 6):
dt = np.dtype([('a', 'b'), ('b', 'i'), ('sub', np.dtype('b,i')), ('c', 'i')], align=True)
self._check("T{b:a:xxxi:b:T{b:f0:=i:f1:}:sub:xxxi:c:}", dt)
+ dt = np.dtype([('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'), ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+ self._check("T{b:a:=i:b:b:c:b:d:b:e:T{b:f0:xxxi:f1:}:sub:}", dt)
+
def test_padding_with_array_inside_struct(self):
dt = np.dtype([('a', 'b'), ('b', 'i'), ('c', 'b', (3,)), ('d', 'i')], align=True)
self._check("T{b:a:xxxi:b:3b:c:xi:d:}", dt)
@@ -2153,5 +2156,9 @@ if sys.version_info >= (2, 6):
x2 = np.arange(dt2.itemsize, dtype=np.int8).view(dt2)
self._check_roundtrip(x2)
+ dt3 = np.dtype([('a', 'b'), ('b', 'i'), ('c', 'b'), ('d', 'b'), ('e', 'b'), ('sub', np.dtype('b,i', align=True))])
+ x3 = np.arange(dt3.itemsize, dtype=np.int8).view(dt3)
+ self._check_roundtrip(x3)
+
if __name__ == "__main__":
run_module_suite()