Thanks to visit codestin.com
Credit goes to github.com

Skip to content

BUG: revert trim_zeros changes from gh-16911 #17171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions doc/release/upcoming_changes/16911.deprecation.rst

This file was deleted.

21 changes: 0 additions & 21 deletions numpy/core/tests/test_deprecations.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,24 +707,3 @@ def test_deprecated(self):
self.assert_deprecated(lambda: np.array([arr, [0]], dtype=np.float64))
self.assert_deprecated(lambda: np.array([[0], arr], dtype=np.float64))


class TestTrimZeros(_DeprecationTestCase):
# Numpy 1.20.0, 2020-07-31
@pytest.mark.parametrize(
"arr,exc_type",
[(np.random.rand(10, 10).tolist(), ValueError),
(np.random.rand(10).astype(str), FutureWarning)]
)
def test_deprecated(self, arr, exc_type):
with warnings.catch_warnings():
warnings.simplefilter('error', DeprecationWarning)
try:
np.trim_zeros(arr)
except DeprecationWarning as ex:
ex_cause = ex.__cause__
assert_(isinstance(ex_cause, exc_type))
else:
raise AssertionError("No error raised during function call")

out = np.lib.function_base._trim_zeros_old(arr)
assert_array_equal(arr, out)
56 changes: 0 additions & 56 deletions numpy/lib/function_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1625,63 +1625,7 @@ def trim_zeros(filt, trim='fb'):
[1, 2]

"""
try:
return _trim_zeros_new(filt, trim)
except Exception as ex:
# Numpy 1.20.0, 2020-07-31
warning = DeprecationWarning(
"in the future trim_zeros will require a 1-D array as input "
"that supports elementwise comparisons with zero"
)
warning.__cause__ = ex

# Fall back to the old implementation if an exception is encountered
# Note that the same exception may or may not be raised here as well
ret = _trim_zeros_old(filt, trim)
warnings.warn(warning, stacklevel=3)
return ret


def _trim_zeros_new(filt, trim='fb'):
"""Newer optimized implementation of ``trim_zeros()``."""
arr_any = np.asanyarray(filt)
arr = arr_any != 0 if arr_any.dtype != bool else arr_any

if arr is False:
# not all dtypes support elementwise comparisons with `0` (e.g. str);
# they will return `False` instead
raise TypeError('elementwise comparison failed; unsupported data type')
elif arr.ndim != 1:
raise ValueError('trim_zeros requires an array of exactly one dimension')
elif not len(arr):
return filt

trim_upper = trim.upper()
first = last = None

if 'F' in trim_upper:
first = arr.argmax()
# If `arr[first] is False` then so are all other elements
if not arr[first]:
return filt[:0]

if 'B' in trim_upper:
last = len(arr) - arr[::-1].argmax()
# If `arr[last - 1] is False` then so are all other elements
if not arr[last - 1]:
return filt[:0]

return filt[first:last]


def _trim_zeros_old(filt, trim='fb'):
"""
Older unoptimized implementation of ``trim_zeros()``.

Used as fallback in case an exception is encountered
in ``_trim_zeros_new()``.

"""
first = 0
trim = trim.upper()
if 'F' in trim:
Expand Down
4 changes: 4 additions & 0 deletions numpy/lib/tests/test_function_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,10 @@ def test_no_trim(self):
assert_array_equal(arr, res)


def test_list_to_list(self):
res = trim_zeros(self.a.tolist())
assert isinstance(res, list)
Comment on lines +1228 to +1230
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this test does not pass on master?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does as self.a is just a normal 1D array of integers.

However, there is currently no test which checks the return type so I feel this is a nice addition.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to work out whether this is a case of @mattip generally wishing to reseal the can of worms, or if there was a specific worm that we knew was an incompatibility.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly seal the can of worms. I am a bit dubious if the new implementation actually achieves what it promises, personally. (Depending on the use-case, you may be stripping only one value from a very large array, making the old code much faster. OTOH, maybe that use-case doesn't actually matter since in almost all cases the work done on the result will be much slower anyway.)

If you are fairly certain the updated version seals it well, I think we can go with that as well. I had never looked very carefully, but it seemed a bit hard to be sure previously, and trim_zeros seemed a bit niche to worry about much...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR reverts the code to its state before the first PR gh-16911. I added the passing test to cover a use case that previously was not tested.


class TestExtins:

def test_basic(self):
Expand Down