Numeric types are now stored in native format (vs. old strings).
[h5config.git] / h5config / storage / hdf5.py
index b488c370ea3c4f572c63299bd578cdb2bb11b244..93913d6598eaeeb9b94fe757815729a4fb4602bf 100644 (file)
@@ -18,6 +18,8 @@
 """HDF5 backend implementation
 """
 
+import types as _types
+
 import h5py as _h5py
 
 from .. import LOG as _LOG
@@ -75,8 +77,6 @@ def h5_create_group(cwg, path, force=False):
 class HDF5_Storage (_FileStorage):
     """Back a `Config` class with an HDF5 file.
 
-    TODO: Special handling for Choice (enums), FloatList (arrays), etc.?
-
     The `.save` and `.load` methods have an optional `group` argument
     that allows you to save and load settings from an externally
     opened HDF5 file.  This can make it easier to stash several
@@ -98,15 +98,15 @@ class HDF5_Storage (_FileStorage):
     >>> pprint_HDF5(filename)  # doctest: +REPORT_UDIFF
     /
       /base
-        <HDF5 dataset "age": shape (), type "|S3">
+        <HDF5 dataset "age": shape (), type "<f8">
           1.3
-        <HDF5 dataset "alive": shape (), type "|S3">
-          yes
-        <HDF5 dataset "bids": shape (), type "|S11">
-          5.4, 3.2, 1
+        <HDF5 dataset "alive": shape (), type "|b1">
+          True
+        <HDF5 dataset "bids": shape (3,), type "<f8">
+          [ 5.4  3.2  1. ]
         <HDF5 dataset "children": shape (), type "|S1">
     <BLANKLINE>
-        <HDF5 dataset "daisies": shape (), type "|S2">
+        <HDF5 dataset "daisies": shape (), type "<i4">
           13
         <HDF5 dataset "name": shape (), type "|S1">
     <BLANKLINE>
@@ -155,6 +155,16 @@ class HDF5_Storage (_FileStorage):
             for s in config.settings:
                 if s.name not in group.keys():
                     continue
+                elif isinstance(s, (_config.BooleanSetting,
+                                    _config.NumericSetting,
+                                    _config.FloatListSetting)):
+                    v = group[s.name][...]
+                    if isinstance(v, _types.StringTypes):
+                        # convert back from None, etc.
+                        v = s.convert_from_text(v)
+                    elif isinstance(s, _config.FloatListSetting):
+                        v = list(v)  # convert from numpy array
+                    config[s.name] = v
                 elif isinstance(s, _config.ConfigListSetting):
                     try:
                         cwg = h5_create_group(group, s.name)
@@ -195,7 +205,14 @@ class HDF5_Storage (_FileStorage):
                 f = _h5py.File(self._filename, 'a')
                 group = f[self.group]
             for s in config.settings:
-                if isinstance(s, _config.ConfigListSetting):
+                value = None
+                if isinstance(s, (_config.BooleanSetting,
+                                    _config.NumericSetting,
+                                    _config.FloatListSetting)):
+                    value = config[s.name]
+                    if value in [None, []]:
+                        value = s.convert_to_text(value)
+                elif isinstance(s, _config.ConfigListSetting):
                     configs = config[s.name]
                     if configs:
                         cwg = h5_create_group(group, s.name, force=True)
@@ -209,7 +226,8 @@ class HDF5_Storage (_FileStorage):
                         cwg = h5_create_group(group, s.name, force=True)
                         self._save(config=cfg, group=cwg)
                         continue
-                value = s.convert_to_text(config[s.name])
+                if value is None:  # not set yet, or invalid
+                    value = s.convert_to_text(config[s.name])
                 try:
                     del group[s.name]
                 except KeyError: