Skip to content

Use explicit type check in as_compatible_data instead of blanket access to values attribute #2905

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

4 changes: 4 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ New Features

Bug fixes
~~~~~~~~~
- Use specific type checks in
:py:func:`~xarray.core.variable.as_compatible_data` instead of blanket
access to ``values`` attribute (:issue:`2097`)
By `Yunus Sevinchan <https://github.com/blsqr>`_.
- :py:meth:`DataArray.resample` and :py:meth:`Dataset.resample` do not trigger computations anymore if :py:meth:`Dataset.weighted` or :py:meth:`DataArray.weighted` are applied (:issue:`4625`, :pull:`4668`). By `Julius Busecke <https://github.com/jbusecke>`_.
- :py:func:`merge` with ``combine_attrs='override'`` makes a copy of the attrs (:issue:`4627`).
- By default, when possible, xarray will now always use values of type ``int64`` when encoding
Expand Down
3 changes: 2 additions & 1 deletion xarray/core/variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ def as_compatible_data(data, fastpath=False):
data = np.timedelta64(getattr(data, "value", data), "ns")

# we don't want nested self-described arrays
data = getattr(data, "values", data)
if isinstance(data, (pd.Series, pd.Index, pd.DataFrame)):
data = data.values

if isinstance(data, np.ma.MaskedArray):
mask = np.ma.getmaskarray(data)
Expand Down
9 changes: 9 additions & 0 deletions xarray/tests/test_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2300,6 +2300,11 @@ def __init__(self, array):
class CustomIndexable(CustomArray, indexing.ExplicitlyIndexed):
pass

# Type with data stored in values attribute
class CustomWithValuesAttr:
def __init__(self, array):
self.values = array

array = CustomArray(np.arange(3))
orig = Variable(dims=("x"), data=array, attrs={"foo": "bar"})
assert isinstance(orig._data, np.ndarray) # should not be CustomArray
Expand All @@ -2308,6 +2313,10 @@ class CustomIndexable(CustomArray, indexing.ExplicitlyIndexed):
orig = Variable(dims=("x"), data=array, attrs={"foo": "bar"})
assert isinstance(orig._data, CustomIndexable)

array = CustomWithValuesAttr(np.arange(3))
orig = Variable(dims=(), data=array)
assert isinstance(orig._data.item(), CustomWithValuesAttr)


def test_raise_no_warning_for_nan_in_binary_ops():
with pytest.warns(None) as record:
Expand Down