Skip to content
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

fixes for warnings related to unit tests and nan comparisons #1657

Merged
merged 12 commits into from
Oct 29, 2017
5 changes: 5 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ Breaking changes
disk when calling ``repr`` (:issue:`1522`).
By `Guido Imperiale <https://github.com/crusaderky>`_.

- Suppress ``RuntimeWarning`` issued by ``numpy`` for "invalid value comparisons"
(e.g. NaNs). Xarray now behaves similarly to Pandas in its treatment of
binary and unary operations on objects with ``NaN``s (:issue:`1657`).
By `Joe Hamman <https://github.com/jhamman>`_.

- Several existing features have been deprecated and will change to new
behavior in xarray v0.11. If you use any of them with xarray v0.10, you
should see a ``FutureWarning`` that describes how to update your code:
Expand Down
4 changes: 3 additions & 1 deletion xarray/core/dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,9 @@ def __array_wrap__(self, obj, context=None):
def _unary_op(f):
@functools.wraps(f)
def func(self, *args, **kwargs):
return self.__array_wrap__(f(self.variable.data, *args, **kwargs))
with np.errstate(all='ignore'):
return self.__array_wrap__(f(self.variable.data, *args,
**kwargs))

return func

Expand Down
3 changes: 2 additions & 1 deletion xarray/core/pycompat.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def itervalues(d):
from functools import reduce
import builtins
from urllib.request import urlretrieve
from inspect import getfullargspec as getargspec
else: # pragma: no cover
# Python 2
basestring = basestring # noqa
Expand All @@ -43,7 +44,7 @@ def itervalues(d):
reduce = reduce
import __builtin__ as builtins
from urllib import urlretrieve

from inspect import getargspec
try:
from cyordereddict import OrderedDict
except ImportError: # pragma: no cover
Expand Down
13 changes: 8 additions & 5 deletions xarray/core/variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,8 @@ def __array_wrap__(self, obj, context=None):
def _unary_op(f):
@functools.wraps(f)
def func(self, *args, **kwargs):
return self.__array_wrap__(f(self.data, *args, **kwargs))
with np.errstate(all='ignore'):
return self.__array_wrap__(f(self.data, *args, **kwargs))
return func

@staticmethod
Expand All @@ -1364,9 +1365,10 @@ def func(self, other):
if isinstance(other, (xr.DataArray, xr.Dataset)):
return NotImplemented
self_data, other_data, dims = _broadcast_compat_data(self, other)
new_data = (f(self_data, other_data)
if not reflexive
else f(other_data, self_data))
with np.errstate(all='ignore'):
new_data = (f(self_data, other_data)
if not reflexive
else f(other_data, self_data))
result = Variable(dims, new_data)
return result
return func
Expand All @@ -1381,7 +1383,8 @@ def func(self, other):
if dims != self.dims:
raise ValueError('dimensions cannot change for in-place '
'operations')
self.values = f(self_data, other_data)
with np.errstate(all='ignore'):
self.values = f(self_data, other_data)
return self
return func

Expand Down
4 changes: 2 additions & 2 deletions xarray/plot/facetgrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
from __future__ import division
from __future__ import print_function

import inspect
import warnings
import itertools
import functools

import numpy as np

from ..core.pycompat import getargspec
from ..core.formatting import format_item
from .utils import (_determine_cmap_params, _infer_xy_labels,
import_matplotlib_pyplot)
Expand Down Expand Up @@ -228,7 +228,7 @@ def map_dataarray(self, func, x, y, **kwargs):
'filled': func.__name__ != 'contour',
}

cmap_args = inspect.getargspec(_determine_cmap_params).args
cmap_args = getargspec(_determine_cmap_params).args
cmap_kwargs.update((a, kwargs[a]) for a in cmap_args if a in kwargs)

cmap_params = _determine_cmap_params(**cmap_kwargs)
Expand Down
6 changes: 3 additions & 3 deletions xarray/tests/test_accessors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import numpy as np
import pandas as pd

from . import TestCase, requires_dask
from . import TestCase, requires_dask, raises_regex


class TestDatetimeAccessor(TestCase):
Expand Down Expand Up @@ -45,7 +45,7 @@ def test_not_datetime_type(self):
nontime_data = self.data.copy()
int_data = np.arange(len(self.data.time)).astype('int8')
nontime_data['time'].values = int_data
with self.assertRaisesRegexp(TypeError, 'dt'):
with raises_regex(TypeError, 'dt'):
nontime_data.time.dt

@requires_dask
Expand Down Expand Up @@ -93,4 +93,4 @@ def test_seasons(self):
"SON", "SON", "SON", "DJF"]
seasons = xr.DataArray(seasons)

self.assertArrayEqual(seasons.values, dates.dt.season.values)
self.assertArrayEqual(seasons.values, dates.dt.season.values)
73 changes: 36 additions & 37 deletions xarray/tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
requires_scipy_or_netCDF4, requires_dask, requires_h5netcdf,
requires_pynio, requires_pathlib, has_netCDF4, has_scipy,
assert_allclose, flaky, network, requires_rasterio,
assert_identical)
assert_identical, raises_regex)
from .test_dataset import create_test_data

from xarray.tests import mock
Expand Down Expand Up @@ -113,7 +113,7 @@ def __getitem__(self, key):
return self.array[key]

array = UnreliableArray([0])
with self.assertRaises(UnreliableArrayFailure):
with pytest.raises(UnreliableArrayFailure):
array[0]
self.assertEqual(array[0], 0)

Expand Down Expand Up @@ -218,7 +218,7 @@ def assert_loads(vars=None):
self.assertTrue(v._in_memory)
self.assertDatasetIdentical(expected, actual)

with self.assertRaises(AssertionError):
with pytest.raises(AssertionError):
# make sure the contextmanager works!
with assert_loads() as ds:
pass
Expand Down Expand Up @@ -345,8 +345,7 @@ def test_roundtrip_datetime_data(self):
kwds = {'encoding': {'t0': {'units': 'days since 1950-01-01'}}}
with self.roundtrip(expected, save_kwargs=kwds) as actual:
self.assertDatasetIdentical(expected, actual)
self.assertEquals(actual.t0.encoding['units'],
'days since 1950-01-01')
assert actual.t0.encoding['units'] == 'days since 1950-01-01'

def test_roundtrip_timedelta_data(self):
time_deltas = pd.to_timedelta(['1h', '2h', 'NaT'])
Expand Down Expand Up @@ -528,7 +527,7 @@ def test_roundtrip_endian(self):

if type(self) is NetCDF4DataTest:
ds['z'].encoding['endian'] = 'big'
with self.assertRaises(NotImplementedError):
with pytest.raises(NotImplementedError):
with self.roundtrip(ds) as actual:
pass

Expand All @@ -539,7 +538,7 @@ def test_invalid_dataarray_names_raise(self):
da = xr.DataArray(data)
for name, e in zip([0, (4, 5), True, ''], [te, te, te, ve]):
ds = Dataset({name: da})
with self.assertRaisesRegexp(*e):
with raises_regex(*e):
with self.roundtrip(ds) as actual:
pass

Expand All @@ -551,17 +550,17 @@ def test_encoding_kwarg(self):
self.assertEqual(ds.x.encoding, {})

kwargs = dict(encoding={'x': {'foo': 'bar'}})
with self.assertRaisesRegexp(ValueError, 'unexpected encoding'):
with raises_regex(ValueError, 'unexpected encoding'):
with self.roundtrip(ds, save_kwargs=kwargs) as actual:
pass

kwargs = dict(encoding={'x': 'foo'})
with self.assertRaisesRegexp(ValueError, 'must be castable'):
with raises_regex(ValueError, 'must be castable'):
with self.roundtrip(ds, save_kwargs=kwargs) as actual:
pass

kwargs = dict(encoding={'invalid': {}})
with self.assertRaises(KeyError):
with pytest.raises(KeyError):
with self.roundtrip(ds, save_kwargs=kwargs) as actual:
pass

Expand Down Expand Up @@ -676,9 +675,9 @@ def test_open_group(self):
self.assertVariableEqual(actual['x'], expected['x'])

# check that missing group raises appropriate exception
with self.assertRaises(IOError):
with pytest.raises(IOError):
open_dataset(tmp_file, group='bar')
with self.assertRaisesRegexp(ValueError, 'must be a string'):
with raises_regex(ValueError, 'must be a string'):
open_dataset(tmp_file, group=(1, 2, 3))

def test_open_subgroup(self):
Expand Down Expand Up @@ -1019,7 +1018,7 @@ def create_store(self):

def test_array_attrs(self):
ds = Dataset(attrs={'foo': [[1, 2], [3, 4]]})
with self.assertRaisesRegexp(ValueError, 'must be 1-dimensional'):
with raises_regex(ValueError, 'must be 1-dimensional'):
with self.roundtrip(ds) as roundtripped:
pass

Expand All @@ -1036,11 +1035,11 @@ def test_netcdf3_endianness(self):

@requires_netCDF4
def test_nc4_scipy(self):
with create_tmp_file() as tmp_file:
with create_tmp_file(allow_cleanup_failure=True) as tmp_file:
with nc4.Dataset(tmp_file, 'w', format='NETCDF4') as rootgrp:
rootgrp.createGroup('foo')

with self.assertRaisesRegexp(TypeError, 'pip install netcdf4'):
with raises_regex(TypeError, 'pip install netcdf4'):
open_dataset(tmp_file, engine='scipy')
Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Well, we aren't closing this file properly, so I'm not too surprised that Windows is complaining. I don't know why it's only showing up now, though.

For now, just add allow_cleanup_failure=True to the create_tmp_file() call. We'll tackle this later in #1668.



Expand Down Expand Up @@ -1096,18 +1095,18 @@ def test_write_store(self):

def test_engine(self):
data = create_test_data()
with self.assertRaisesRegexp(ValueError, 'unrecognized engine'):
with raises_regex(ValueError, 'unrecognized engine'):
data.to_netcdf('foo.nc', engine='foobar')
with self.assertRaisesRegexp(ValueError, 'invalid engine'):
with raises_regex(ValueError, 'invalid engine'):
data.to_netcdf(engine='netcdf4')

with create_tmp_file() as tmp_file:
data.to_netcdf(tmp_file)
with self.assertRaisesRegexp(ValueError, 'unrecognized engine'):
with raises_regex(ValueError, 'unrecognized engine'):
open_dataset(tmp_file, engine='foobar')

netcdf_bytes = data.to_netcdf()
with self.assertRaisesRegexp(ValueError, 'can only read'):
with raises_regex(ValueError, 'can only read'):
open_dataset(BytesIO(netcdf_bytes), engine='foobar')

def test_cross_engine_read_write_netcdf3(self):
Expand Down Expand Up @@ -1389,12 +1388,12 @@ def test_common_coord_when_datavars_minimal(self):
def test_invalid_data_vars_value_should_fail(self):

with self.setup_files_and_datasets() as (files, _):
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
with open_mfdataset(files, data_vars='minimum'):
pass

# test invalid coord parameter
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
with open_mfdataset(files, coords='minimum'):
pass

Expand Down Expand Up @@ -1452,7 +1451,7 @@ def test_open_mfdataset(self):
self.assertEqual(actual.foo.variable.data.chunks,
((3, 2, 3, 2),))

with self.assertRaisesRegexp(IOError, 'no files to open'):
with raises_regex(IOError, 'no files to open'):
open_mfdataset('foo-bar-baz-*.nc', autoclose=self.autoclose)

@requires_pathlib
Expand Down Expand Up @@ -1483,7 +1482,7 @@ def test_attrs_mfdataset(self):
# first dataset loaded
self.assertEqual(actual.test1, ds1.test1)
# attributes from ds2 are not retained, e.g.,
with self.assertRaisesRegexp(AttributeError,
with raises_regex(AttributeError,
'no attribute'):
actual.test2

Expand Down Expand Up @@ -1513,15 +1512,15 @@ def test_save_mfdataset_roundtrip(self):

def test_save_mfdataset_invalid(self):
ds = Dataset()
with self.assertRaisesRegexp(ValueError, 'cannot use mode'):
with raises_regex(ValueError, 'cannot use mode'):
save_mfdataset([ds, ds], ['same', 'same'])
with self.assertRaisesRegexp(ValueError, 'same length'):
with raises_regex(ValueError, 'same length'):
save_mfdataset([ds, ds], ['only one path'])

def test_save_mfdataset_invalid_dataarray(self):
# regression test for GH1555
da = DataArray([1, 2])
with self.assertRaisesRegexp(TypeError, 'supports writing Dataset'):
with raises_regex(TypeError, 'supports writing Dataset'):
save_mfdataset([da], ['dataarray'])


Expand Down Expand Up @@ -1846,11 +1845,11 @@ def test_indexing(self):
# but on x and y only windowed operations are allowed, more
# exotic slicing should raise an error
err_msg = 'not valid on rasterio'
with self.assertRaisesRegexp(IndexError, err_msg):
with raises_regex(IndexError, err_msg):
actual.isel(x=[2, 4], y=[1, 3]).values
with self.assertRaisesRegexp(IndexError, err_msg):
with raises_regex(IndexError, err_msg):
actual.isel(x=[4, 2]).values
with self.assertRaisesRegexp(IndexError, err_msg):
with raises_regex(IndexError, err_msg):
actual.isel(x=slice(5, 2, -1)).values

# Integer indexing
Expand Down Expand Up @@ -1916,7 +1915,7 @@ def test_caching(self):

# Without cache an error is raised
err_msg = 'not valid on rasterio'
with self.assertRaisesRegexp(IndexError, err_msg):
with raises_regex(IndexError, err_msg):
actual.isel(x=[2, 4]).values

# This should cache everything
Expand Down Expand Up @@ -1976,7 +1975,7 @@ class TestEncodingInvalid(TestCase):

def test_extract_nc4_variable_encoding(self):
var = xr.Variable(('x',), [1, 2, 3], {}, {'foo': 'bar'})
with self.assertRaisesRegexp(ValueError, 'unexpected encoding'):
with raises_regex(ValueError, 'unexpected encoding'):
_extract_nc4_variable_encoding(var, raise_on_invalid=True)

var = xr.Variable(('x',), [1, 2, 3], {}, {'chunking': (2, 1)})
Expand All @@ -1992,7 +1991,7 @@ def test_extract_h5nc_encoding(self):
# not supported with h5netcdf (yet)
var = xr.Variable(('x',), [1, 2, 3], {},
{'least_sigificant_digit': 2})
with self.assertRaisesRegexp(ValueError, 'unexpected encoding'):
with raises_regex(ValueError, 'unexpected encoding'):
_extract_nc4_variable_encoding(var, raise_on_invalid=True)


Expand Down Expand Up @@ -2025,17 +2024,17 @@ def new_dataset_and_coord_attrs():
ds, attrs = new_dataset_and_attrs()

attrs[123] = 'test'
with self.assertRaisesRegexp(TypeError, 'Invalid name for attr'):
with raises_regex(TypeError, 'Invalid name for attr'):
ds.to_netcdf('test.nc')

ds, attrs = new_dataset_and_attrs()
attrs[MiscObject()] = 'test'
with self.assertRaisesRegexp(TypeError, 'Invalid name for attr'):
with raises_regex(TypeError, 'Invalid name for attr'):
ds.to_netcdf('test.nc')

ds, attrs = new_dataset_and_attrs()
attrs[''] = 'test'
with self.assertRaisesRegexp(ValueError, 'Invalid name for attr'):
with raises_regex(ValueError, 'Invalid name for attr'):
ds.to_netcdf('test.nc')

# This one should work
Expand All @@ -2046,12 +2045,12 @@ def new_dataset_and_coord_attrs():

ds, attrs = new_dataset_and_attrs()
attrs['test'] = {'a': 5}
with self.assertRaisesRegexp(TypeError, 'Invalid value for attr'):
with raises_regex(TypeError, 'Invalid value for attr'):
ds.to_netcdf('test.nc')

ds, attrs = new_dataset_and_attrs()
attrs['test'] = MiscObject()
with self.assertRaisesRegexp(TypeError, 'Invalid value for attr'):
with raises_regex(TypeError, 'Invalid value for attr'):
ds.to_netcdf('test.nc')

ds, attrs = new_dataset_and_attrs()
Expand Down
Loading