Skip to content

Commit 88651d5

Browse files
authored
Rework getitem (#65)
1. If passes a scalar key, there must be only one variable that matches the key 2. To get back all variables, pass a list ds.cf[["longitude"]] for example. I think this is more consistent with xarray semantics.
1 parent be1f4a0 commit 88651d5

File tree

5 files changed

+159
-87
lines changed

5 files changed

+159
-87
lines changed

cf_xarray/accessor.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,11 @@ def _get_axis_coord_single(var: Union[DataArray, Dataset], key: str,) -> List[st
174174
""" Helper method for when we really want only one result per key. """
175175
results = _get_axis_coord(var, key)
176176
if len(results) > 1:
177-
raise ValueError(
177+
raise KeyError(
178178
f"Multiple results for {key!r} found: {results!r}. Is this valid CF? Please open an issue."
179179
)
180180
elif len(results) == 0:
181-
raise ValueError(f"No results found for {key!r}.")
181+
raise KeyError(f"No results found for {key!r}.")
182182
return results
183183

184184

@@ -895,14 +895,17 @@ def __getitem__(self, key: Union[str, List[str]]):
895895
)
896896

897897
if scalar_key:
898+
axis_coord_mapper = _get_axis_coord_single
898899
key = (key,) # type: ignore
900+
else:
901+
axis_coord_mapper = _get_axis_coord
899902

900903
varnames: List[Hashable] = []
901904
coords: List[Hashable] = []
902905
successful = dict.fromkeys(key, False)
903906
for k in key:
904907
if k in _AXIS_NAMES + _COORD_NAMES:
905-
names = _get_axis_coord(self._obj, k)
908+
names = axis_coord_mapper(self._obj, k)
906909
successful[k] = bool(names)
907910
coords.extend(names)
908911
elif k in _CELL_MEASURES:
@@ -919,6 +922,7 @@ def __getitem__(self, key: Union[str, List[str]]):
919922
# these are not special names but could be variable names in underlying object
920923
# we allow this so that we can return variables with appropriate CF auxiliary variables
921924
varnames.extend([k for k, v in successful.items() if not v])
925+
allnames = varnames + coords
922926

923927
try:
924928
for name in varnames:
@@ -929,8 +933,10 @@ def __getitem__(self, key: Union[str, List[str]]):
929933
else:
930934
ds = self._obj
931935

932-
if scalar_key and len(varnames) == 1:
933-
da: DataArray = ds[varnames[0]].reset_coords(drop=True) # type: ignore
936+
if scalar_key and len(allnames) == 1:
937+
da: DataArray = ds.reset_coords()[allnames[0]] # type: ignore
938+
if allnames[0] in coords:
939+
coords.remove(allnames[0])
934940
failed = []
935941
for k1 in coords:
936942
if k1 not in ds.variables:

cf_xarray/tests/test_accessor.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def test_getitem_ancillary_variables():
105105
def test_rename_like():
106106
original = popds.copy(deep=True)
107107

108-
with pytest.raises(ValueError):
108+
with pytest.raises(KeyError):
109109
popds.cf.rename_like(airds)
110110

111111
renamed = popds.cf["TEMP"].cf.rename_like(airds)
@@ -310,8 +310,6 @@ def test_getitem(obj, key, expected_key):
310310
assert key in obj.cf
311311

312312
actual = obj.cf[key]
313-
if isinstance(obj, xr.Dataset):
314-
expected_key = [expected_key]
315313
expected = obj[expected_key]
316314
assert_identical(actual, expected)
317315

@@ -329,10 +327,11 @@ def test_getitem_uses_coordinates():
329327
# POP-like dataset
330328
ds = popds
331329
assert_identical(
332-
ds.cf["X"], ds.reset_coords()[["ULONG", "TLONG"]].set_coords(["ULONG", "TLONG"])
330+
ds.cf[["X"]],
331+
ds.reset_coords()[["ULONG", "TLONG"]].set_coords(["ULONG", "TLONG"]),
333332
)
334333
assert_identical(
335-
ds.cf["Y"], ds.reset_coords()[["ULAT", "TLAT"]].set_coords(["ULAT", "TLAT"])
334+
ds.cf[["Y"]], ds.reset_coords()[["ULAT", "TLAT"]].set_coords(["ULAT", "TLAT"])
336335
)
337336
assert_identical(ds.UVEL.cf["X"], ds["ULONG"].reset_coords(drop=True))
338337
assert_identical(ds.TEMP.cf["X"], ds["TLONG"].reset_coords(drop=True))

doc/contributing.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ Primarily for developer reference. Some of these could become public API if nece
5555
~accessor._getattr
5656
~accessor._get_axis_coord
5757
~accessor._get_axis_coord_single
58-
~accessor._get_list_standard_names
5958
~accessor._get_measure
6059
~accessor._get_measure_variable
6160
accessor._CFWrappedPlotMethods._plot_decorator

0 commit comments

Comments
 (0)