Skip to content

FIX Don't raise a deprecation warning for xarray.ufuncs.{angle,iscomplex} #2615

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 2 commits into from
Dec 20, 2018
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
35 changes: 35 additions & 0 deletions xarray/tests/test_ufuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,41 @@ def test_xarray_ufuncs_deprecation():
with pytest.warns(PendingDeprecationWarning, match='xarray.ufuncs'):
xu.cos(xr.DataArray([0, 1]))

with pytest.warns(None) as record:
xu.angle(xr.DataArray([0, 1]))
record = [el.message for el in record
if el.category == PendingDeprecationWarning]
assert len(record) == 0


@requires_np113
@pytest.mark.filterwarnings('ignore::RuntimeWarning')
@pytest.mark.parametrize(
'name',
[name for name in dir(xu)
if (not name.startswith('_') and hasattr(np, name)
and name not in ['print_function', 'absolute_import', 'division'])]
Copy link
Contributor Author

@rth rth Dec 17, 2018

Choose a reason for hiding this comment

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

Here we list all functions defined in xarray.ufuncs, but there are some functions that need to be filtered out.

)
def test_numpy_ufuncs(name, request):
x = xr.DataArray([1, 1])

np_func = getattr(np, name)
if hasattr(np_func, 'nin') and np_func.nin == 2:
args = (x, x)
else:
args = (x,)

y = np_func(*args)

if name in ['angle', 'iscomplex']:
# these functions need to be handled with __array_function__ protocol
assert isinstance(y, np.ndarray)
elif name in ['frexp']:
# np.frexp returns a tuple
assert not isinstance(y, xr.DataArray)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The output is a tuple of len 2, it's a bit of a special case, not sure if it's really worth adding specific tests for it.

else:
assert isinstance(y, xr.DataArray)


def test_xarray_ufuncs_pickle():
a = 1.0
Expand Down
10 changes: 6 additions & 4 deletions xarray/ufuncs.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ def __init__(self, name):
self._name = name

def __call__(self, *args, **kwargs):
_warnings.warn(
'xarray.ufuncs will be deprecated when xarray no longer supports '
'versions of numpy older than v1.13. Instead, use numpy ufuncs '
'directly.', PendingDeprecationWarning, stacklevel=2)
if self._name not in ['angle', 'iscomplex']:
_warnings.warn(
'xarray.ufuncs will be deprecated when xarray no longer '
'supports versions of numpy older than v1.17. Instead, use '
'numpy ufuncs directly.',
PendingDeprecationWarning, stacklevel=2)
Copy link
Member

Choose a reason for hiding this comment

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

It might be better to say: "xarray.ufuncs will be deprecated when xarray no longer supports versions of numpy older than v1.17." We'll need __array_function__ from 1.17 to override angle and iscomplex.

Or perhaps we should just drop the pending deprecation warning entirely given how far away this is (NumPy hasn't even released 1.16 yet, nevermind 1.17)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated the warning message as you suggested.

I think independently of when xarray.ufuncs is going to be deprecated, it is good to let the user know that they can use numpy ufuncs now (for most functions except a few for which this warning is not raised)


new_args = args
f = _dask_or_eager_func(self._name, array_args=slice(len(args)))
Expand Down