id,node_id,number,title,user,state,locked,assignee,milestone,comments,created_at,updated_at,closed_at,author_association,active_lock_reason,draft,pull_request,body,reactions,performed_via_github_app,state_reason,repo,type 936305081,MDU6SXNzdWU5MzYzMDUwODE=,5570,assert_equal does not handle wrapped duck arrays well,35968931,open,0,,,0,2021-07-03T18:27:11Z,2021-07-03T18:49:57Z,,MEMBER,,,,"Whilst trying to fix #5559 I noticed that `xarray.testing.assert_equal` (and `xarray.testing.assert_equal`) don't behave well with wrapped duck-typed arrays. Firstly, they can give unhelpful `AssertionError` messages: ```python In [5]: a = np.array([1,2,3]) In [6]: q = pint.Quantity([1,2,3], units='m') In [7]: da_np = xr.DataArray(a, dims='x') In [8]: da_p = xr.DataArray(q, dims='x') In [9]: da_np Out[9]: array([1, 2, 3]) Dimensions without coordinates: x In [10]: da_p Out[10]: Dimensions without coordinates: x In [11]: from xarray.testing import assert_equal In [12]: assert_equal(da_np, da_p) /home/tegn500/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/xarray/core/duck_array_ops.py:265: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray. flag_array = (arr1 == arr2) | (isnull(arr1) & isnull(arr2)) /home/tegn500/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/xarray/core/duck_array_ops.py:265: DeprecationWarning: elementwise comparison failed; this will raise an error in the future. flag_array = (arr1 == arr2) | (isnull(arr1) & isnull(arr2)) /home/tegn500/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/xarray/core/duck_array_ops.py:265: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray. flag_array = (arr1 == arr2) | (isnull(arr1) & isnull(arr2)) /home/tegn500/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/xarray/core/duck_array_ops.py:265: DeprecationWarning: elementwise comparison failed; this will raise an error in the future. flag_array = (arr1 == arr2) | (isnull(arr1) & isnull(arr2)) /home/tegn500/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/numpy/core/_asarray.py:102: UnitStrippedWarning: The unit of the quantity is stripped when downcasting to ndarray. return array(a, dtype, copy=False, order=order) --------------------------------------------------------------------------- AssertionError Traceback (most recent call last) in ----> 1 assert_equal(da_np, da_p) [... skipping hidden 1 frame] ~/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/xarray/testing.py in assert_equal(a, b) 79 assert type(a) == type(b) 80 if isinstance(a, (Variable, DataArray)): ---> 81 assert a.equals(b), formatting.diff_array_repr(a, b, ""equals"") 82 elif isinstance(a, Dataset): 83 assert a.equals(b), formatting.diff_dataset_repr(a, b, ""equals"") AssertionError: Left and right DataArray objects are not equal Differing values: L array([1, 2, 3]) R array([1, 2, 3]) ``` These are different, but not because the array values are different. At the moment `.values` is converting the wrapped array type by stripping the units too - it might be better to check the type of the wrapped array first, then use `.values` to compare. Or could we even do duck-typed testing by delegating via `expected.data.equals(actual.data)`? (EDIT: I don't think a `.equals()` method exists in the numpy API, but you could do the equivalent of `assert all(expected.data == actual.data)` Secondly, given that we coerce before comparison, I think it's possible that `assert_equal` could say two different wrapped duck-type arrays are equal when they are not, just because `np.asarray()` coerces them to the same values. EDIT2: Looks like there is some discussion [here](https://github.com/pydata/xarray/pull/3706#issuecomment-583259053)","{""url"": ""https://api.github.com/repos/pydata/xarray/issues/5570/reactions"", ""total_count"": 1, ""+1"": 1, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,,13221727,issue