diff --git a/xarray/backends/pynio_.py b/xarray/backends/pynio_.py index 075db5d4ccb..cf792bb699a 100644 --- a/xarray/backends/pynio_.py +++ b/xarray/backends/pynio_.py @@ -3,6 +3,7 @@ from __future__ import print_function import functools +import contextlib import numpy as np @@ -21,16 +22,18 @@ def __init__(self, variable_name, datastore): @property def array(self): - return self.datastore.ds.variables[self.variable_name] + with self.datastore.ensure_open(): + return self.datastore.ds.variables[self.variable_name] @property def dtype(self): return np.dtype(self.array.typecode()) def __getitem__(self, key): - if key == () and self.ndim == 0: - return self.array.get_value() - return self.array[key] + with self.datastore.ensure_open(): + if key == () and self.ndim == 0: + return self.array.get_value() + return self.array[key] class NioDataStore(AbstractDataStore, DataStorePickleMixin): @@ -40,22 +43,34 @@ def __init__(self, filename, mode='r'): import Nio opener = functools.partial(Nio.open_file, filename, mode=mode) self.ds = opener() + self._isopen = True self._opener = opener self._mode = mode + @contextlib.contextmanager + def ensure_open(self): + if not self._isopen: + self.ds = self._opener() + self._isopen = True + yield + def open_store_variable(self, name, var): data = indexing.LazilyIndexedArray(NioArrayWrapper(name, self)) return Variable(var.dimensions, data, var.attributes) def get_variables(self): - return FrozenOrderedDict((k, self.open_store_variable(k, v)) - for k, v in self.ds.variables.iteritems()) + with self.ensure_open(): + return FrozenOrderedDict((k, self.open_store_variable(k, v)) + for k, v in self.ds.variables.iteritems()) def get_attrs(self): - return Frozen(self.ds.attributes) + with self.ensure_open(): + return Frozen(self.ds.attributes) def get_dimensions(self): - return Frozen(self.ds.dimensions) + with self.ensure_open(): + return Frozen(self.ds.dimensions) def close(self): + self._isopen = False self.ds.close()