diff options
author | Pauli Virtanen <pav@iki.fi> | 2011-04-02 10:18:29 +0200 |
---|---|---|
committer | Pauli Virtanen <pav@iki.fi> | 2011-04-02 10:46:06 +0200 |
commit | 89db53b1f437d846829a3c387ea61001b3b66383 (patch) | |
tree | 09209c832c9aef7a15ba0a75f8d8e58e46d6f658 | |
parent | f04bacb635ff9b90e8be6bb66ecd55b56b857073 (diff) | |
download | numpy-89db53b1f437d846829a3c387ea61001b3b66383.tar.gz |
BUG: core/buffer: fix another offset counting bug in pep-3118 format string generation
-rw-r--r-- | numpy/core/src/multiarray/buffer.c | 11 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 7 |
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() |