Skip to content

Commit fe6cd5a

Browse files
committed
Allow _FillValue and missing_value to differ (Fixes pydata#1749)
The CF standard permits both values, and them to have different values, so we should not be treating this as an error--just mask out all of them.
1 parent 8e4231a commit fe6cd5a

File tree

2 files changed

+14
-24
lines changed

2 files changed

+14
-24
lines changed

xarray/coding/variables.py

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import numpy as np
88
import pandas as pd
99

10-
from ..core import dtypes, duck_array_ops, indexing, utils
10+
from ..core import dtypes, duck_array_ops, indexing
1111
from ..core.pycompat import dask_array_type
1212
from ..core.variable import Variable
1313

@@ -152,26 +152,12 @@ def encode(self, variable, name=None):
152152
def decode(self, variable, name=None):
153153
dims, data, attrs, encoding = unpack_for_decoding(variable)
154154

155-
if 'missing_value' in attrs:
156-
# missing_value is deprecated, but we still want to support it as
157-
# an alias for _FillValue.
158-
if ('_FillValue' in attrs and
159-
not utils.equivalent(attrs['_FillValue'],
160-
attrs['missing_value'])):
161-
raise ValueError("Conflicting _FillValue and missing_value "
162-
"attrs on a variable {!r}: {} vs. {}\n\n"
163-
"Consider opening the offending dataset "
164-
"using decode_cf=False, correcting the "
165-
"attrs and decoding explicitly using "
166-
"xarray.decode_cf()."
167-
.format(name, attrs['_FillValue'],
168-
attrs['missing_value']))
169-
attrs['_FillValue'] = attrs.pop('missing_value')
170-
171-
if '_FillValue' in attrs:
172-
raw_fill_value = pop_to(attrs, encoding, '_FillValue', name=name)
173-
encoded_fill_values = [
174-
fv for fv in np.ravel(raw_fill_value) if not pd.isnull(fv)]
155+
raw_fill_values = [pop_to(attrs, encoding, attr, name=name)
156+
for attr in ('missing_value', '_FillValue')]
157+
if raw_fill_values:
158+
encoded_fill_values = [fv for option in raw_fill_values
159+
for fv in np.ravel(option)
160+
if not pd.isnull(fv)]
175161

176162
if len(encoded_fill_values) > 1:
177163
warnings.warn("variable {!r} has multiple fill values {}, "

xarray/tests/test_conventions.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,16 @@ def test(self):
156156

157157

158158
def test_decode_cf_with_conflicting_fill_missing_value():
159-
var = Variable(['t'], np.arange(10),
159+
expected = Variable(['t'], [np.nan, np.nan, 2], {'units': 'foobar'})
160+
expected[[0, 1]] = np.nan
161+
var = Variable(['t'], np.arange(3),
160162
{'units': 'foobar',
161163
'missing_value': 0,
162164
'_FillValue': 1})
163-
with raises_regex(ValueError, "_FillValue and missing_value"):
164-
conventions.decode_cf_variable('t', var)
165+
with warnings.catch_warnings(record=True) as w:
166+
actual = conventions.decode_cf_variable('t', var)
167+
assert_identical(actual, expected)
168+
assert 'has multiple fill' in str(w[0].message)
165169

166170
expected = Variable(['t'], np.arange(10), {'units': 'foobar'})
167171

0 commit comments

Comments
 (0)