Skip to content

Commit

Permalink
Fixes too many files open error: pynio backend
Browse files Browse the repository at this point in the history
  • Loading branch information
pwolfram committed Feb 5, 2017
1 parent 4ec6f4c commit 095fd6a
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions xarray/backends/pynio_.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
from __future__ import print_function

import functools
import contextlib

import numpy as np

from .. import Variable
from .netCDF4_ import VariableWrapper
from ..core.utils import FrozenOrderedDict, Frozen, NDArrayMixin
from ..core import indexing

Expand All @@ -21,16 +23,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 VariableWrapper(self.datastore, 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):
Expand All @@ -40,22 +44,39 @@ 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, autoclose=True):
if not self._isopen:
try:
self.ds = self._opener()
self._isopen = True
yield
finally:
if autoclose:
self.close()
else:
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 get_encoding(self):
encoding = {}
Expand All @@ -64,4 +85,6 @@ def get_encoding(self):
return encoding

def close(self):
self.ds.close()
if self._isopen:
self.ds.close()
self._isopen = False

0 comments on commit 095fd6a

Please sign in to comment.