diff --git a/doc/release/1.15.0-notes.rst b/doc/release/1.15.0-notes.rst index b76b68a19d62..4c6c184096a1 100644 --- a/doc/release/1.15.0-notes.rst +++ b/doc/release/1.15.0-notes.rst @@ -89,6 +89,12 @@ longer possible, and objects expecting the old API are respected. The silent suc by removing the interception of an otherwise-normal Exception when ``axis`` was provided to an object using the old API. +unstructured void array's ``.item`` method now returns a bytes object +--------------------------------------------------------------------- +``.item`` now returns a ``bytes`` object instead of a buffer or byte array. +This may affect code which assumed the return value was mutable, which is no +longer the case. + C API changes ============= diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index 5e6804a5cba3..42f8761250a3 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -655,9 +655,7 @@ VOID_getitem(void *input, void *vap) { PyArrayObject *ap = vap; char *ip = input; - PyArrayObject *u = NULL; PyArray_Descr* descr; - int itemsize; descr = PyArray_DESCR(ap); if (PyDataType_HASFIELDS(descr)) { @@ -731,68 +729,7 @@ VOID_getitem(void *input, void *vap) return (PyObject *)ret; } - /* 2017-11-26, 1.14 */ - if (DEPRECATE_FUTUREWARNING( - "the `.item()` method of unstructured void types will return an " - "immutable `bytes` object in the near future, the same as " - "returned by `bytes(void_obj)`, instead of the mutable memoryview " - "or integer array returned in numpy 1.13.") < 0) { - return NULL; - } - /* - * In the future all the code below will be replaced by - * - * For unstructured void types like V4, return a bytes object (copy). - * return PyBytes_FromStringAndSize(PyArray_DATA(ap), descr->elsize); - */ - - if (PyDataType_FLAGCHK(descr, NPY_ITEM_HASOBJECT) - || PyDataType_FLAGCHK(descr, NPY_ITEM_IS_POINTER)) { - PyErr_SetString(PyExc_ValueError, - "tried to get void-array with object members as buffer."); - return NULL; - } - itemsize = PyArray_DESCR(ap)->elsize; - -#if defined(NPY_PY3K) - /* - * Return a byte array; there are no plain buffer objects on Py3 - */ - { - npy_intp dims[1], strides[1]; - dims[0] = itemsize; - strides[0] = 1; - descr = PyArray_DescrNewFromType(NPY_BYTE); - u = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, - descr, 1, dims, strides, ip, - PyArray_ISWRITEABLE(ap) ? NPY_ARRAY_WRITEABLE : 0, - NULL); - Py_INCREF(ap); - if (PyArray_SetBaseObject(u, (PyObject *)ap) < 0) { - Py_DECREF(u); - return NULL; - } - } -#else - /* - * default is to return buffer object pointing to - * current item a view of it - */ - if (PyArray_ISWRITEABLE(ap)) { - if (array_might_be_written(ap) < 0) { - return NULL; - } - u = (PyArrayObject *)PyBuffer_FromReadWriteMemory(ip, itemsize); - } - else { - u = (PyArrayObject *)PyBuffer_FromMemory(ip, itemsize); - } -#endif - - if (u == NULL) { - return NULL; - } - return (PyObject *)u; + return PyBytes_FromStringAndSize(PyArray_DATA(ap), descr->elsize); } diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index b3cb3e61074e..d6dcaa982199 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -2325,13 +2325,10 @@ def test_scalar_copy(self): def test_void_item_memview(self): va = np.zeros(10, 'V4') - # for now, there is just a futurewarning - assert_warns(FutureWarning, va[:1].item) - # in the future, test we got a bytes copy: - #x = va[:1].item() - #va[0] = b'\xff\xff\xff\xff' - #del va - #assert_equal(x, b'\x00\x00\x00\x00') + x = va[:1].item() + va[0] = b'\xff\xff\xff\xff' + del va + assert_equal(x, b'\x00\x00\x00\x00') def test_structarray_title(self): # The following used to segfault on pypy, due to NPY_TITLE_KEY