diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-04-06 16:08:30 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-06 16:08:30 -0600 |
commit | 1f9c30ef0f4f7a0c3e0227c3de681a11fcc24861 (patch) | |
tree | 0f69a88b9e69636bb034a50f4ebdacff1357f7cf | |
parent | a3c28010ca5427cf67346c928f7319c111d84fd8 (diff) | |
parent | 2ee7c72e56b5ef16f3838f86de8ad0d435b9b4e0 (diff) | |
download | numpy-1f9c30ef0f4f7a0c3e0227c3de681a11fcc24861.tar.gz |
Merge pull request #10826 from tylerjereddy/issue_10779_squeeze
BUG: np.squeeze() now respects older API axis expectation
-rw-r--r-- | doc/release/1.15.0-notes.rst | 10 | ||||
-rw-r--r-- | numpy/core/fromnumeric.py | 9 | ||||
-rw-r--r-- | numpy/core/tests/test_regression.py | 61 |
3 files changed, 74 insertions, 6 deletions
diff --git a/doc/release/1.15.0-notes.rst b/doc/release/1.15.0-notes.rst index 2a8c57351..cff75c477 100644 --- a/doc/release/1.15.0-notes.rst +++ b/doc/release/1.15.0-notes.rst @@ -55,6 +55,16 @@ All downstream users seem to use detect the `None` result from ``flatnotmasked_contiguous`` and replace it with ``[]``. These callers will continue to work as before. +``np.squeeze`` now respects the API expectation of objects that do not handle an ``axis`` argument +-------------------------------------------------------------------------------------------------- +Prior to version ``1.7.0`` ``np.squeeze`` did not have an ``axis`` argument and all empty axes were removed +by default. After incorporation of an ``axis`` argument, it was possible to selectively squeeze single +or multiple empty axes, but the old API expectation was not respected because the axes could still be +selectively removed (silent success) in an object depending on the old API. The silent success is no +longer possible, and objects expecting the old API are respected. The silent success was prevented +by removing the interception of an otherwise-normal Exception when ``axis`` was provided to an object +using the old API. + C API changes ============= diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py index 63279ffb3..5f1aadbf5 100644 --- a/numpy/core/fromnumeric.py +++ b/numpy/core/fromnumeric.py @@ -1280,13 +1280,10 @@ def squeeze(a, axis=None): squeeze = a.squeeze except AttributeError: return _wrapit(a, 'squeeze') - try: - # First try to use the new axis= parameter - return squeeze(axis=axis) - except TypeError: - # For backwards compatibility + if axis is None: return squeeze() - + else: + return squeeze(axis=axis) def diagonal(a, offset=0, axis1=0, axis2=1): """ diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index 016b720f3..119594668 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -1675,6 +1675,67 @@ class TestRegression(object): assert_(a.flags.f_contiguous) assert_(b.flags.f_contiguous) + def test_squeeze_axis_handling(self): + # Issue #10779 + # Ensure proper handling of objects + # that don't support axis specification + # when squeezing + + class OldSqueeze(np.ndarray): + + def __new__(cls, + input_array): + obj = np.asarray(input_array).view(cls) + return obj + + # it is perfectly reasonable that prior + # to numpy version 1.7.0 a subclass of ndarray + # might have been created that did not expect + # squeeze to have an axis argument + # NOTE: this example is somewhat artificial; + # it is designed to simulate an old API + # expectation to guard against regression + def squeeze(self): + return super(OldSqueeze, self).squeeze() + + oldsqueeze = OldSqueeze(np.array([[1],[2],[3]])) + + # if no axis argument is specified the old API + # expectation should give the correct result + assert_equal(np.squeeze(oldsqueeze), + np.array([1,2,3])) + + # likewise, axis=None should work perfectly well + # with the old API expectation + assert_equal(np.squeeze(oldsqueeze, axis=None), + np.array([1,2,3])) + + # however, specification of any particular axis + # should raise a TypeError in the context of the + # old API specification, even when using a valid + # axis specification like 1 for this array + with assert_raises(TypeError): + # this would silently succeed for array + # subclasses / objects that did not support + # squeeze axis argument handling before fixing + # Issue #10779 + np.squeeze(oldsqueeze, axis=1) + + # check for the same behavior when using an invalid + # axis specification -- in this case axis=0 does not + # have size 1, but the priority should be to raise + # a TypeError for the axis argument and NOT a + # ValueError for squeezing a non-empty dimension + with assert_raises(TypeError): + np.squeeze(oldsqueeze, axis=0) + + # the new API knows how to handle the axis + # argument and will return a ValueError if + # attempting to squeeze an axis that is not + # of length 1 + with assert_raises(ValueError): + np.squeeze(np.array([[1],[2],[3]]), axis=0) + def test_reduce_contiguous(self): # GitHub issue #387 a = np.add.reduce(np.zeros((2, 1, 2)), (0, 1)) |