Skip to content

Commit 7bdb033

Browse files
aulemahaldcherian
andauthored
Allow hashable keys (not only strings) (#271)
Co-authored-by: Deepak Cherian <[email protected]>
1 parent 3b5ac13 commit 7bdb033

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

cf_xarray/accessor.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
def apply_mapper(
7777
mappers: Union[Mapper, Tuple[Mapper, ...]],
7878
obj: Union[DataArray, Dataset],
79-
key: Any,
79+
key: Hashable,
8080
error: bool = True,
8181
default: Any = None,
8282
) -> List[Any]:
@@ -88,9 +88,11 @@ def apply_mapper(
8888
results for a good key.
8989
"""
9090

91-
if not isinstance(key, str):
91+
if not isinstance(key, Hashable):
9292
if default is None:
93-
raise ValueError("`default` must be provided when `key` is not a string.")
93+
raise ValueError(
94+
"`default` must be provided when `key` is not not a valid DataArray name (of hashable type)."
95+
)
9496
return list(always_iterable(default))
9597

9698
default = [] if default is None else list(always_iterable(default))

cf_xarray/tests/test_accessor.py

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,38 @@ def test_repr():
134134
# Flag DataArray
135135
assert "CF Flag variable" in repr(basin.cf)
136136

137+
# "Temp" dataset
138+
actual = airds["air"]._to_temp_dataset().cf.__repr__()
139+
expected = """\
140+
Coordinates:
141+
- CF Axes: * X: ['lon']
142+
* Y: ['lat']
143+
* T: ['time']
144+
Z: n/a
145+
146+
- CF Coordinates: * longitude: ['lon']
147+
* latitude: ['lat']
148+
* time: ['time']
149+
vertical: n/a
150+
151+
- Cell Measures: area: ['cell_area']
152+
volume: n/a
153+
154+
- Standard Names: * latitude: ['lat']
155+
* longitude: ['lon']
156+
* time: ['time']
157+
158+
- Bounds: n/a
159+
160+
Data Variables:
161+
- Cell Measures: area, volume: n/a
162+
163+
- Standard Names: air_temperature: [<this-array>]
164+
165+
- Bounds: n/a
166+
"""
167+
assert actual == dedent(expected)
168+
137169

138170
def test_axes():
139171
expected = dict(T=["time"], X=["lon"], Y=["lat"])
@@ -1078,7 +1110,7 @@ def test_drop_vars_and_set_coords(obj, attr):
10781110
# Cell measure
10791111
assert_identical(expected("cell_area"), actual("area"))
10801112
# Variables
1081-
if isinstance(obj, Dataset):
1113+
if isinstance(obj, Dataset) and "air" in obj.data_vars:
10821114
assert_identical(expected("air"), actual("air_temperature"))
10831115
assert_identical(expected(obj.variables), actual(obj.cf.keys()))
10841116

@@ -1094,7 +1126,7 @@ def test_drop_sel_and_reset_coords(obj):
10941126
# Cell measure
10951127
assert_identical(obj.reset_coords("cell_area"), obj.cf.reset_coords("area"))
10961128
# Variable
1097-
if isinstance(obj, Dataset):
1129+
if isinstance(obj, Dataset) and "air" in obj.data_vars:
10981130
assert_identical(
10991131
obj.reset_coords("air"), obj.cf.reset_coords("air_temperature")
11001132
)
@@ -1118,7 +1150,11 @@ def test_rename(obj):
11181150
cf_dict = {
11191151
"air_temperature" if isinstance(obj, Dataset) else "longitude": "renamed"
11201152
}
1121-
xr_dict = {"air" if isinstance(obj, Dataset) else "lon": "renamed"}
1153+
xr_dict = {
1154+
"air"
1155+
if isinstance(obj, Dataset) and "air" in obj.data_vars
1156+
else "lon": "renamed"
1157+
}
11221158
assert_identical(obj.rename(xr_dict), obj.cf.rename(cf_dict))
11231159
assert_identical(obj.rename(**xr_dict), obj.cf.rename(**cf_dict))
11241160

0 commit comments

Comments
 (0)