From 9951000e3244ecb756a18deec2fbe00ec038a38e Mon Sep 17 00:00:00 2001 From: Ryan May Date: Fri, 25 Oct 2024 15:50:44 -0600 Subject: [PATCH] BUG: Fix xarray support with decode_coords='all' This support was added in pydata/xarray#2844 and handles converting the grid_mapping variable to a coordinate in xarray itself, which was incompatible with some assumptions in parse_cf(). Add some handling for the case where the grid_mapping. Also add decode_coords='all' to our full test suite and adjust a few tests as necessary. --- src/metpy/xarray.py | 7 ++++--- tests/test_xarray.py | 15 ++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/metpy/xarray.py b/src/metpy/xarray.py index b6650b4caa2..2c8aa6413aa 100644 --- a/src/metpy/xarray.py +++ b/src/metpy/xarray.py @@ -835,9 +835,10 @@ def parse_cf(self, varname=None, coordinates=None): # Attempt to build the crs coordinate crs = None - if 'grid_mapping' in var.attrs: - # Use given CF grid_mapping - proj_name = var.attrs['grid_mapping'] + + # Check both raw attribute and xarray-handled and moved to encoding + proj_name = var.encoding.get('grid_mapping', var.attrs.get('grid_mapping')) + if proj_name is not None: try: proj_var = self._dataset.variables[proj_name] except KeyError: diff --git a/tests/test_xarray.py b/tests/test_xarray.py index 2571944f80f..7a5513ad257 100644 --- a/tests/test_xarray.py +++ b/tests/test_xarray.py @@ -18,10 +18,11 @@ grid_deltas_from_dataarray, preprocess_and_wrap) -@pytest.fixture -def test_ds(): +@pytest.fixture(params=[True, 'all']) +def test_ds(request): """Provide an xarray dataset for testing.""" - return xr.open_dataset(get_test_data('narr_example.nc', as_file_obj=False)) + return xr.open_dataset(get_test_data('narr_example.nc', as_file_obj=False), + decode_coords=request.param) @pytest.fixture @@ -47,7 +48,8 @@ def test_var(test_ds): def test_var_multidim_full(test_ds): """Provide a variable with x/y coords and multidimensional lat/lon auxiliary coords.""" return (test_ds[{'isobaric': [6, 12], 'y': [95, 96], 'x': [122, 123]}] - .squeeze().set_coords(['lat', 'lon'])['Temperature']) + .squeeze().drop_vars('Lambert_Conformal') + .set_coords(['lat', 'lon'])['Temperature']) @pytest.fixture @@ -676,11 +678,6 @@ def test_find_axis_number_bad_identifier(test_var): assert 'axis is not valid' in str(exc.value) -def test_cf_parse_with_grid_mapping(test_var): - """Test cf_parse dont delete grid_mapping attribute.""" - assert test_var.grid_mapping == 'Lambert_Conformal' - - def test_data_array_loc_get_with_units(test_var): """Test the .loc indexer on the metpy accessor.""" truth = test_var.loc[:, 850.]