Skip to content

Commit cc37747

Browse files
committed
Fixes too many files open error: pynio backend
1 parent d510aa8 commit cc37747

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

xarray/backends/pynio_.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
from __future__ import print_function
44

55
import functools
6+
import contextlib
67

78
import numpy as np
89

910
from .. import Variable
11+
from .netCDF4_ import VariableWrapper
1012
from ..core.utils import FrozenOrderedDict, Frozen, NDArrayMixin
1113
from ..core import indexing
1214

@@ -21,16 +23,18 @@ def __init__(self, variable_name, datastore):
2123

2224
@property
2325
def array(self):
24-
return self.datastore.ds.variables[self.variable_name]
26+
with self.datastore.ensure_open():
27+
return VariableWrapper(self.datastore, self.variable_name)
2528

2629
@property
2730
def dtype(self):
2831
return np.dtype(self.array.typecode())
2932

3033
def __getitem__(self, key):
31-
if key == () and self.ndim == 0:
32-
return self.array.get_value()
33-
return self.array[key]
34+
with self.datastore.ensure_open():
35+
if key == () and self.ndim == 0:
36+
return self.array.get_value()
37+
return self.array[key]
3438

3539

3640
class NioDataStore(AbstractDataStore, DataStorePickleMixin):
@@ -40,22 +44,39 @@ def __init__(self, filename, mode='r'):
4044
import Nio
4145
opener = functools.partial(Nio.open_file, filename, mode=mode)
4246
self.ds = opener()
47+
self._isopen = True
4348
self._opener = opener
4449
self._mode = mode
4550

51+
@contextlib.contextmanager
52+
def ensure_open(self, autoclose=True):
53+
if not self._isopen:
54+
try:
55+
self.ds = self._opener()
56+
self._isopen = True
57+
yield
58+
finally:
59+
if autoclose:
60+
self.close()
61+
else:
62+
yield
63+
4664
def open_store_variable(self, name, var):
4765
data = indexing.LazilyIndexedArray(NioArrayWrapper(name, self))
4866
return Variable(var.dimensions, data, var.attributes)
4967

5068
def get_variables(self):
51-
return FrozenOrderedDict((k, self.open_store_variable(k, v))
52-
for k, v in self.ds.variables.iteritems())
69+
with self.ensure_open():
70+
return FrozenOrderedDict((k, self.open_store_variable(k, v))
71+
for k, v in self.ds.variables.iteritems())
5372

5473
def get_attrs(self):
55-
return Frozen(self.ds.attributes)
74+
with self.ensure_open():
75+
return Frozen(self.ds.attributes)
5676

5777
def get_dimensions(self):
58-
return Frozen(self.ds.dimensions)
78+
with self.ensure_open():
79+
return Frozen(self.ds.dimensions)
5980

6081
def get_encoding(self):
6182
encoding = {}
@@ -64,4 +85,6 @@ def get_encoding(self):
6485
return encoding
6586

6687
def close(self):
67-
self.ds.close()
88+
if self._isopen:
89+
self.ds.close()
90+
self._isopen = False

0 commit comments

Comments
 (0)