From b570f73d39505926478fda1b1a496ac3e707d33d Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 31 Mar 2020 17:46:05 +0100 Subject: MAINT: Introduce PyArray_OptionalIntpConverter for shape arguments which can be None --- numpy/core/src/multiarray/conversion_utils.c | 14 ++++++++++++++ numpy/core/src/multiarray/conversion_utils.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c index 484a13134..260ae7080 100644 --- a/numpy/core/src/multiarray/conversion_utils.c +++ b/numpy/core/src/multiarray/conversion_utils.c @@ -137,6 +137,20 @@ PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq) return NPY_SUCCEED; } +/* + * Like PyArray_IntpConverter, but leaves `seq` untouched if `None` is passed + * rather than treating `None` as `()`. + */ +NPY_NO_EXPORT int +PyArray_OptionalIntpConverter(PyObject *obj, PyArray_Dims *seq) +{ + if (obj == Py_None) { + return NPY_SUCCEED; + } + + return PyArray_IntpConverter(obj, seq); +} + /*NUMPY_API * Get buffer chunk from object * diff --git a/numpy/core/src/multiarray/conversion_utils.h b/numpy/core/src/multiarray/conversion_utils.h index 9bf712c3b..bee0c6064 100644 --- a/numpy/core/src/multiarray/conversion_utils.h +++ b/numpy/core/src/multiarray/conversion_utils.h @@ -6,6 +6,9 @@ NPY_NO_EXPORT int PyArray_IntpConverter(PyObject *obj, PyArray_Dims *seq); +NPY_NO_EXPORT int +PyArray_OptionalIntpConverter(PyObject *obj, PyArray_Dims *seq); + NPY_NO_EXPORT int PyArray_BufferConverter(PyObject *obj, PyArray_Chunk *buf); -- cgit v1.2.1 From b88415edf288cff6ab89b19bb7f7ca55ec1e6ade Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 31 Mar 2020 17:58:15 +0100 Subject: BUG: Do not ignore empty tuple of strides in ndarray.__new__ Previously this was treated as though an empty set of strides were passed. Now this is treated as a request for `.strides == ()`. --- doc/release/upcoming_changes/15882.compatibility.rst | 5 +++++ numpy/core/src/multiarray/arrayobject.c | 7 ++++--- numpy/core/tests/test_multiarray.py | 6 ++++++ 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 doc/release/upcoming_changes/15882.compatibility.rst diff --git a/doc/release/upcoming_changes/15882.compatibility.rst b/doc/release/upcoming_changes/15882.compatibility.rst new file mode 100644 index 000000000..5790c081c --- /dev/null +++ b/doc/release/upcoming_changes/15882.compatibility.rst @@ -0,0 +1,5 @@ +The ``numpy.ndarray`` constructor no longer interprets ``strides=()`` as ``strides=None`` +----------------------------------------------------------------------------------------- +The former has changed to have the expected meaning of setting +`numpy.ndarray.strides` to ``()``, while the latter continues to result in +strides being chosen automatically. diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index 16896aa12..dedaf38eb 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -41,6 +41,7 @@ maintainer email: oliphant.travis@ieee.org #include "arraytypes.h" #include "scalartypes.h" #include "arrayobject.h" +#include "conversion_utils.h" #include "ctors.h" #include "methods.h" #include "descriptor.h" @@ -1624,7 +1625,7 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) PyArray_Descr *descr = NULL; int itemsize; PyArray_Dims dims = {NULL, 0}; - PyArray_Dims strides = {NULL, 0}; + PyArray_Dims strides = {NULL, -1}; PyArray_Chunk buffer; npy_longlong offset = 0; NPY_ORDER order = NPY_CORDER; @@ -1645,7 +1646,7 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) PyArray_BufferConverter, &buffer, &offset, - &PyArray_IntpConverter, + &PyArray_OptionalIntpConverter, &strides, &PyArray_OrderConverter, &order)) { @@ -1660,7 +1661,7 @@ array_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) itemsize = descr->elsize; - if (strides.ptr != NULL) { + if (strides.len != -1) { npy_intp nb, off; if (strides.len != dims.len) { PyErr_SetString(PyExc_ValueError, diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 829679dab..470df6986 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -686,6 +686,12 @@ class TestZeroRank: y[()] = 6 assert_equal(x[()], 6) + # strides and shape must be the same length + with pytest.raises(ValueError): + np.ndarray((2,), strides=()) + with pytest.raises(ValueError): + np.ndarray((), strides=(2,)) + def test_output(self): x = np.array(2) assert_raises(ValueError, np.add, x, [1], x) -- cgit v1.2.1