diff options
author | seberg <sebastian@sipsolutions.net> | 2015-12-18 13:21:03 +0100 |
---|---|---|
committer | seberg <sebastian@sipsolutions.net> | 2015-12-18 13:21:03 +0100 |
commit | 3af5f0574740611076df9dc905330defab70a6dc (patch) | |
tree | 918a324b3ffb9b1abff63ee7c35d668783667cbc | |
parent | f7b07521ca811baa2fcc649a6dc5cf56f5c65fd0 (diff) | |
parent | 088e20e272389395fb3fd24fed144ed19bae8cdb (diff) | |
download | numpy-3af5f0574740611076df9dc905330defab70a6dc.tar.gz |
Merge pull request #6823 from gfyoung/order_arg_validate
Stricter Argument Checking for Flatten Methods
-rw-r--r-- | doc/release/1.11.0-notes.rst | 8 | ||||
-rw-r--r-- | numpy/add_newdocs.py | 12 | ||||
-rw-r--r-- | numpy/core/src/multiarray/conversion_utils.c | 21 | ||||
-rw-r--r-- | numpy/core/tests/test_deprecations.py | 30 | ||||
-rw-r--r-- | numpy/lib/function_base.py | 10 | ||||
-rw-r--r-- | numpy/matrixlib/defmatrix.py | 14 |
6 files changed, 81 insertions, 14 deletions
diff --git a/doc/release/1.11.0-notes.rst b/doc/release/1.11.0-notes.rst index b3ddae604..7c078eed9 100644 --- a/doc/release/1.11.0-notes.rst +++ b/doc/release/1.11.0-notes.rst @@ -133,3 +133,11 @@ c_contiguous arrays at some future time. A work around that is backward compatible is to use `a.T.view(...).T` instead. A parameter will also be added to the view method to explicitly ask for Fortran order views, but that will not be backward compatible. + +Invalid arguments for array ordering +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +It is currently possible to pass in arguments for the ```order``` +parameter in methods like ```array.flatten``` or ```array.ravel``` +that were not one of the following: 'C', 'F', 'A', 'K' (note that +all of these possible values are unicode- and case-insensitive). +Such behaviour will not be allowed in future releases. diff --git a/numpy/add_newdocs.py b/numpy/add_newdocs.py index c14036089..01ef24a5b 100644 --- a/numpy/add_newdocs.py +++ b/numpy/add_newdocs.py @@ -3567,10 +3567,14 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('flatten', Parameters ---------- - order : {'C', 'F', 'A'}, optional - Whether to flatten in row-major (C-style) or - column-major (Fortran-style) order or preserve the - C/Fortran ordering from `a`. The default is 'C'. + order : {'C', 'F', 'A', 'K'}, optional + 'C' means to flatten in row-major (C-style) order. + 'F' means to flatten in column-major (Fortran- + style) order. 'A' means to flatten in column-major + order if `a` is Fortran *contiguous* in memory, + row-major order otherwise. 'K' means to flatten + `a` in the order the elements occur in memory. + The default is 'C'. Returns ------- diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c index 88064c1d6..d7a617875 100644 --- a/numpy/core/src/multiarray/conversion_utils.c +++ b/numpy/core/src/multiarray/conversion_utils.c @@ -540,6 +540,15 @@ PyArray_OrderConverter(PyObject *object, NPY_ORDER *val) return ret; } else if (!PyBytes_Check(object) || PyBytes_GET_SIZE(object) < 1) { + /* 2015-12-14, 1.11 */ + int ret = DEPRECATE("Non-string object detected for " + "the array ordering. Please pass " + "in 'C', 'F', 'A', or 'K' instead"); + + if (ret < 0) { + return -1; + } + if (PyObject_IsTrue(object)) { *val = NPY_FORTRANORDER; } @@ -553,6 +562,18 @@ PyArray_OrderConverter(PyObject *object, NPY_ORDER *val) } else { str = PyBytes_AS_STRING(object); + if (strlen(str) != 1) { + /* 2015-12-14, 1.11 */ + int ret = DEPRECATE("Non length-one string passed " + "in for the array ordering. " + "Please pass in 'C', 'F', 'A', " + "or 'K' instead"); + + if (ret < 0) { + return -1; + } + } + if (str[0] == 'C' || str[0] == 'c') { *val = NPY_CORDER; } diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index f6dc3d842..65ddc1e77 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -400,6 +400,36 @@ class TestNonCContiguousViewDeprecation(_DeprecationTestCase): self.assert_deprecated(np.ones((2,2)).T.view, args=(np.int8,)) +class TestInvalidOrderParameterInputForFlattenArrayDeprecation(_DeprecationTestCase): + """Invalid arguments to the ORDER parameter in array.flatten() should not be + allowed and should raise an error. However, in the interests of not breaking + code that may inadvertently pass invalid arguments to this parameter, a + DeprecationWarning will be issued instead for the time being to give developers + time to refactor relevant code. + """ + + def test_flatten_array_non_string_arg(self): + x = np.zeros((3, 5)) + self.message = ("Non-string object detected for " + "the array ordering. Please pass " + "in 'C', 'F', 'A', or 'K' instead") + self.assert_deprecated(x.flatten, args=(np.pi,)) + + def test_flatten_array_invalid_string_arg(self): + # Tests that a DeprecationWarning is raised + # when a string of length greater than one + # starting with "C", "F", "A", or "K" (case- + # and unicode-insensitive) is passed in for + # the ORDER parameter. Otherwise, a TypeError + # will be raised! + + x = np.zeros((3, 5)) + self.message = ("Non length-one string passed " + "in for the array ordering. Please " + "pass in 'C', 'F', 'A', or 'K' instead") + self.assert_deprecated(x.flatten, args=("FACK",)) + + class TestTestDeprecated(object): def test_assert_deprecated(self): test_case_instance = _DeprecationTestCase() diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index 3298789ee..541ad079c 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -3966,6 +3966,7 @@ def delete(arr, obj, axis=None): arr = asarray(arr) ndim = arr.ndim + arrorder = 'F' if arr.flags.fnc else 'C' if axis is None: if ndim != 1: arr = arr.ravel() @@ -4003,7 +4004,7 @@ def delete(arr, obj, axis=None): stop = xr[0] + 1 newshape[axis] -= numtodel - new = empty(newshape, arr.dtype, arr.flags.fnc) + new = empty(newshape, arr.dtype, arrorder) # copy initial chunk if start == 0: pass @@ -4054,7 +4055,7 @@ def delete(arr, obj, axis=None): if (obj < 0): obj += N newshape[axis] -= 1 - new = empty(newshape, arr.dtype, arr.flags.fnc) + new = empty(newshape, arr.dtype, arrorder) slobj[axis] = slice(None, obj) new[slobj] = arr[slobj] slobj[axis] = slice(obj, None) @@ -4197,6 +4198,7 @@ def insert(arr, obj, values, axis=None): arr = asarray(arr) ndim = arr.ndim + arrorder = 'F' if arr.flags.fnc else 'C' if axis is None: if ndim != 1: arr = arr.ravel() @@ -4265,7 +4267,7 @@ def insert(arr, obj, values, axis=None): values = np.rollaxis(values, 0, (axis % values.ndim) + 1) numnew = values.shape[axis] newshape[axis] += numnew - new = empty(newshape, arr.dtype, arr.flags.fnc) + new = empty(newshape, arr.dtype, arrorder) slobj[axis] = slice(None, index) new[slobj] = arr[slobj] slobj[axis] = slice(index, index+numnew) @@ -4298,7 +4300,7 @@ def insert(arr, obj, values, axis=None): old_mask = ones(newshape[axis], dtype=bool) old_mask[indices] = False - new = empty(newshape, arr.dtype, arr.flags.fnc) + new = empty(newshape, arr.dtype, arrorder) slobj2 = [slice(None)]*ndim slobj[axis] = indices slobj2[axis] = old_mask diff --git a/numpy/matrixlib/defmatrix.py b/numpy/matrixlib/defmatrix.py index ffd4578ba..170db87c8 100644 --- a/numpy/matrixlib/defmatrix.py +++ b/numpy/matrixlib/defmatrix.py @@ -277,9 +277,9 @@ class matrix(N.ndarray): elif ndim == 1: shape = (1, shape[0]) - order = False + order = 'C' if (ndim == 2) and arr.flags.fortran: - order = True + order = 'F' if not (order or arr.flags.contiguous): arr = arr.copy() @@ -519,10 +519,12 @@ class matrix(N.ndarray): Parameters ---------- - order : {'C', 'F', 'A'}, optional - Whether to flatten in C (row-major), Fortran (column-major) order, - or preserve the C/Fortran ordering from `m`. - The default is 'C'. + order : {'C', 'F', 'A', 'K'}, optional + 'C' means to flatten in row-major (C-style) order. 'F' means to + flatten in column-major (Fortran-style) order. 'A' means to + flatten in column-major order if `m` is Fortran *contiguous* in + memory, row-major order otherwise. 'K' means to flatten `m` in + the order the elements occur in memory. The default is 'C'. Returns ------- |