Skip to content

Commit e8f9dad

Browse files
authored
Fix resource leak from unclosed dataset (#529)
1 parent 28fec72 commit e8f9dad

File tree

1 file changed

+38
-34
lines changed

1 file changed

+38
-34
lines changed

virtualizarr/readers/common.py

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -54,46 +54,50 @@ def replace_virtual_with_loadable_vars(
5454
).open_file()
5555

5656
# TODO replace with only opening specific variables via `open_zarr(ManifestStore)` in #473
57-
loadable_ds = xr.open_dataset(
57+
with xr.open_dataset(
5858
fpath, # type: ignore[arg-type]
5959
group=group,
6060
decode_times=decode_times,
61-
)
62-
63-
var_names_to_load: list[Hashable]
64-
if isinstance(loadable_variables, list):
65-
var_names_to_load = list(loadable_variables)
66-
elif loadable_variables is None:
67-
# If `loadable_variables`` is None then we have to explicitly match default behaviour of xarray
68-
# i.e. load and create indexes only for dimension coordinate variables.
69-
# We already have all the indexes and variables we should be keeping - we just need to distinguish them.
70-
var_names_to_load = [
71-
name for name, var in loadable_ds.variables.items() if var.dims == (name,)
72-
]
73-
else:
74-
raise ValueError(
75-
f"loadable_variables must be an iterable of string variable names, or None, but got type {type(loadable_variables)}"
61+
) as loadable_ds:
62+
var_names_to_load: list[Hashable]
63+
64+
if isinstance(loadable_variables, list):
65+
var_names_to_load = list(loadable_variables)
66+
elif loadable_variables is None:
67+
# If `loadable_variables` is None, then we have to explicitly match default
68+
# behaviour of xarray, i.e., load and create indexes only for dimension
69+
# coordinate variables. We already have all the indexes and variables
70+
# we should be keeping - we just need to distinguish them.
71+
var_names_to_load = [
72+
name
73+
for name, var in loadable_ds.variables.items()
74+
if var.dims == (name,)
75+
]
76+
else:
77+
raise ValueError(
78+
"loadable_variables must be an iterable of string variable names,"
79+
f" or None, but got type {type(loadable_variables)}"
80+
)
81+
82+
# this will automatically keep any IndexVariables needed for loadable 1D coordinates
83+
loadable_var_names_to_drop = set(loadable_ds.variables).difference(
84+
var_names_to_load
85+
)
86+
ds_loadable_to_keep = loadable_ds.drop_vars(
87+
loadable_var_names_to_drop, errors="ignore"
7688
)
7789

78-
# this will automatically keep any IndexVariables needed for loadable 1D coordinates
79-
loadable_var_names_to_drop = set(loadable_ds.variables).difference(
80-
var_names_to_load
81-
)
82-
ds_loadable_to_keep = loadable_ds.drop_vars(
83-
loadable_var_names_to_drop, errors="ignore"
84-
)
85-
86-
ds_virtual_to_keep = fully_virtual_dataset.drop_vars(
87-
var_names_to_load, errors="ignore"
88-
)
90+
ds_virtual_to_keep = fully_virtual_dataset.drop_vars(
91+
var_names_to_load, errors="ignore"
92+
)
8993

90-
# we don't need `compat` or `join` kwargs here because there should be no variables with the same name in both datasets
91-
return xr.merge(
92-
[
93-
ds_loadable_to_keep,
94-
ds_virtual_to_keep,
95-
],
96-
)
94+
# we don't need `compat` or `join` kwargs here because there should be no variables with the same name in both datasets
95+
return xr.merge(
96+
[
97+
ds_loadable_to_keep,
98+
ds_virtual_to_keep,
99+
],
100+
)
97101

98102

99103
# TODO this probably doesn't need to actually support indexes != {}

0 commit comments

Comments
 (0)