2
2
from __future__ import division
3
3
from __future__ import print_function
4
4
import functools
5
+ import contextlib
5
6
6
7
from .. import Variable
7
8
from ..core import indexing
@@ -36,6 +37,11 @@ def _read_attributes(h5netcdf_var):
36
37
_extract_h5nc_encoding = functools .partial (_extract_nc4_encoding ,
37
38
lsd_okay = False , backend = 'h5netcdf' )
38
39
40
+ def _close_ds (ds ):
41
+ # netCDF4 only allows closing the root group
42
+ while ds .parent is not None :
43
+ ds = ds .parent
44
+ ds .close ()
39
45
40
46
def _open_h5netcdf_group (filename , mode , group ):
41
47
import h5netcdf .legacyapi
@@ -54,12 +60,20 @@ def __init__(self, filename, mode='r', format=None, group=None,
54
60
opener = functools .partial (_open_h5netcdf_group , filename , mode = mode ,
55
61
group = group )
56
62
self .ds = opener ()
63
+ self ._isopen = True
57
64
self .format = format
58
65
self ._opener = opener
59
66
self ._filename = filename
60
67
self ._mode = mode
61
68
super (H5NetCDFStore , self ).__init__ (writer )
62
69
70
+ @contextlib .contextmanager
71
+ def ensure_open (self ):
72
+ if not self ._isopen :
73
+ self .ds = self ._opener ()
74
+ self ._isopen = True
75
+ yield
76
+
63
77
def open_store_variable (self , name , var ):
64
78
dimensions = var .dimensions
65
79
data = indexing .LazilyIndexedArray (BaseNetCDF4Array (name , self ))
@@ -77,20 +91,25 @@ def open_store_variable(self, name, var):
77
91
return Variable (dimensions , data , attrs , encoding )
78
92
79
93
def get_variables (self ):
80
- return FrozenOrderedDict ((k , self .open_store_variable (k , v ))
81
- for k , v in iteritems (self .ds .variables ))
94
+ with self .ensure_open ():
95
+ return FrozenOrderedDict ((k , self .open_store_variable (k , v ))
96
+ for k , v in iteritems (self .ds .variables ))
82
97
83
98
def get_attrs (self ):
84
- return Frozen (_read_attributes (self .ds ))
99
+ with self .ensure_open ():
100
+ return Frozen (_read_attributes (self .ds ))
85
101
86
102
def get_dimensions (self ):
87
- return self .ds .dimensions
103
+ with self .ensure_open ():
104
+ return self .ds .dimensions
88
105
89
106
def set_dimension (self , name , length ):
90
- self .ds .createDimension (name , size = length )
107
+ with self .ensure_open ():
108
+ self .ds .createDimension (name , size = length )
91
109
92
110
def set_attribute (self , key , value ):
93
- self .ds .setncattr (key , value )
111
+ with self .ensure_open ():
112
+ self .ds .setncattr (key , value )
94
113
95
114
def prepare_variable (self , name , variable , check_encoding = False ):
96
115
import h5py
@@ -123,12 +142,11 @@ def prepare_variable(self, name, variable, check_encoding=False):
123
142
return nc4_var , variable .data
124
143
125
144
def sync (self ):
126
- super (H5NetCDFStore , self ).sync ()
127
- self .ds .sync ()
145
+ with self .ensure_open ():
146
+ super (H5NetCDFStore , self ).sync ()
147
+ self .ds .sync ()
128
148
129
149
def close (self ):
130
- ds = self .ds
131
- # netCDF4 only allows closing the root group
132
- while ds .parent is not None :
133
- ds = ds .parent
134
- ds .close ()
150
+ if self ._isopen :
151
+ self ._isopen = False
152
+ _close_ds (self .ds )
0 commit comments