diff --git a/doc/whats-new.rst b/doc/whats-new.rst index f17bb8f0d49..988e47511fa 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -126,6 +126,9 @@ Bug fixes - Compatibility fixes to plotting module for Numpy 1.14 and Pandas 0.22 (:issue:`1813`). By `Joe Hamman `_. +- Bug fix in encoding coordinates with ``{'_FillValue': None}`` in netCDF + metadata (:issue:`1865`). + By `Chris Roth `_. - Fix indexing with lists for arrays loaded from netCDF files with ``engine='h5netcdf`` (:issue:`1864`). By `Stephan Hoyer `_. diff --git a/xarray/backends/netCDF4_.py b/xarray/backends/netCDF4_.py index b3cb1d8e49f..3f3364dec56 100644 --- a/xarray/backends/netCDF4_.py +++ b/xarray/backends/netCDF4_.py @@ -160,7 +160,7 @@ def _extract_nc4_variable_encoding(variable, raise_on_invalid=False, safe_to_drop = set(['source', 'original_shape']) valid_encodings = set(['zlib', 'complevel', 'fletcher32', 'contiguous', - 'chunksizes', 'shuffle']) + 'chunksizes', 'shuffle', '_FillValue']) if lsd_okay: valid_encodings.add('least_significant_digit') diff --git a/xarray/backends/scipy_.py b/xarray/backends/scipy_.py index dba2e5672a2..a608cff8eb5 100644 --- a/xarray/backends/scipy_.py +++ b/xarray/backends/scipy_.py @@ -188,8 +188,9 @@ def encode_variable(self, variable): def prepare_variable(self, name, variable, check_encoding=False, unlimited_dims=None): if check_encoding and variable.encoding: - raise ValueError('unexpected encoding for scipy backend: %r' - % list(variable.encoding)) + if variable.encoding != {'_FillValue': None}: + raise ValueError('unexpected encoding for scipy backend: %r' + % list(variable.encoding)) data = variable.data # nb. this still creates a numpy array in all memory, even though we diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 85b6bdea346..e88fc790571 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -704,6 +704,26 @@ def test_explicitly_omit_fill_value(self): with self.roundtrip(ds) as actual: assert '_FillValue' not in actual.x.encoding + def test_explicitly_omit_fill_value_via_encoding_kwarg(self): + ds = Dataset({'x': ('y', [np.pi, -np.pi])}) + kwargs = dict(encoding={'x': {'_FillValue': None}}) + with self.roundtrip(ds, save_kwargs=kwargs) as actual: + assert '_FillValue' not in actual.x.encoding + self.assertEqual(ds.y.encoding, {}) + + def test_explicitly_omit_fill_value_in_coord(self): + ds = Dataset({'x': ('y', [np.pi, -np.pi])}, coords={'y': [0.0, 1.0]}) + ds.y.encoding['_FillValue'] = None + with self.roundtrip(ds) as actual: + assert '_FillValue' not in actual.y.encoding + + def test_explicitly_omit_fill_value_in_coord_via_encoding_kwarg(self): + ds = Dataset({'x': ('y', [np.pi, -np.pi])}, coords={'y': [0.0, 1.0]}) + kwargs = dict(encoding={'y': {'_FillValue': None}}) + with self.roundtrip(ds, save_kwargs=kwargs) as actual: + assert '_FillValue' not in actual.y.encoding + self.assertEqual(ds.y.encoding, {}) + def test_encoding_same_dtype(self): ds = Dataset({'x': ('y', np.arange(10.0, dtype='f4'))}) kwargs = dict(encoding={'x': {'dtype': 'f4'}})