Add ListSetting and IntegerListSetting types.
authorW. Trevor King <wking@drexel.edu>
Thu, 15 Mar 2012 17:31:14 +0000 (13:31 -0400)
committerW. Trevor King <wking@drexel.edu>
Thu, 15 Mar 2012 17:31:14 +0000 (13:31 -0400)
Also add the storage instance to test assertion error.  Peering
through the logs looking for 'testing {}' wasn't cutting it ;).

h5config/config.py
h5config/storage/hdf5.py
h5config/storage/yaml.py
h5config/test.py

index 4aa9e91f637211863accd362e97f634aa83297d0..478ac3f44939f3ef38c160c4fb5486f73d1ae6dd 100644 (file)
@@ -178,28 +178,28 @@ class FloatSetting (NumericSetting):
         return float(value)
 
 
-class FloatListSetting (Setting):
-    """A named setting with a list of floating point values.
+class ListSetting(Setting):
+    """A named setting with a list of string values.
 
-    >>> s = FloatListSetting(name='floatlist')
+    >>> s = ListSetting(name='list')
     >>> s.default
     []
-    >>> s.convert_to_text([1, 2.3])
-    '1, 2.3'
-    >>> s.convert_from_text('4.5, -6.7')  # doctest: +ELLIPSIS
-    [4.5, -6.7...]
+    >>> s.convert_to_text(['abc', 'def'])
+    'abc,def'
+    >>> s.convert_from_text('uvw, xyz')
+    ['uvw', ' xyz']
     >>> s.convert_to_text([])
     ''
     >>> s.convert_from_text('')
     []
     """
-    def __init__(self, default=[], **kwargs):
-        super(FloatListSetting, self).__init__(default=default, **kwargs)
+    def __init__(self, default=None, **kwargs):
+        if default is None:
+            default = []
+        super(ListSetting, self).__init__(default=default, **kwargs)
 
     def _convert_from_text(self, value):
-        if value is None:
-            return value
-        return float(value)
+        return value
 
     def convert_from_text(self, value):
         if value is None:
@@ -211,7 +211,48 @@ class FloatListSetting (Setting):
     def convert_to_text(self, value):
         if value is None:
             return None
-        return ', '.join([str(x) for x in value])
+        return ','.join([str(x) for x in value])
+
+class IntegerListSetting (ListSetting):
+    """A named setting with a list of integer point values.
+
+    >>> s = IntegerListSetting(name='integerlist')
+    >>> s.default
+    []
+    >>> s.convert_to_text([1, 3])
+    '1,3'
+    >>> s.convert_from_text('4, -6')
+    [4, -6]
+    >>> s.convert_to_text([])
+    ''
+    >>> s.convert_from_text('')
+    []
+    """
+    def _convert_from_text(self, value):
+        if value is None:
+            return value
+        return int(value)
+
+
+class FloatListSetting (ListSetting):
+    """A named setting with a list of floating point values.
+
+    >>> s = FloatListSetting(name='floatlist')
+    >>> s.default
+    []
+    >>> s.convert_to_text([1, 2.3])
+    '1,2.3'
+    >>> s.convert_from_text('4.5, -6.7')  # doctest: +ELLIPSIS
+    [4.5, -6.7...]
+    >>> s.convert_to_text([])
+    ''
+    >>> s.convert_from_text('')
+    []
+    """
+    def _convert_from_text(self, value):
+        if value is None:
+            return value
+        return float(value)
 
 
 class ConfigSetting (Setting):
index 238b9baaf72a8ec0fead7d22be8d4d9632736acb..b8384bcbd2d9f533f66eb3cd279f9c67f30e2900 100644 (file)
@@ -96,7 +96,7 @@ class HDF5_Storage (_FileStorage):
     >>> c['alive'] = True
     >>> group = f.create_group('base')
     >>> c.save(group=group)
-    >>> pprint_HDF5(filename)  # doctest: +REPORT_UDIFF
+    >>> pprint_HDF5(filename)  # doctest: +REPORT_UDIFF, +ELLIPSIS
     /
       /base
         <HDF5 dataset "age": shape (), type "<f8">
@@ -107,7 +107,9 @@ class HDF5_Storage (_FileStorage):
           [ 5.4  3.2  1. ]
         <HDF5 dataset "children": shape (), type "|S1">
     <BLANKLINE>
-        <HDF5 dataset "daisies": shape (), type "<i4">
+        <HDF5 dataset "claws": shape (2,), type "<i8">
+          [1 2]
+        <HDF5 dataset "daisies": shape (), type "<i...">
           13
         <HDF5 dataset "name": shape (), type "|S1">
     <BLANKLINE>
@@ -115,6 +117,8 @@ class HDF5_Storage (_FileStorage):
           Norwegian Blue
         <HDF5 dataset "spouse": shape (), type "|S1">
     <BLANKLINE>
+        <HDF5 dataset "words": shape (2,), type "|S7">
+          ['cracker' 'wants']
     >>> c.clear()
     >>> c['alive']
     False
@@ -188,19 +192,25 @@ class HDF5_Storage (_FileStorage):
                     except Exception, e:
                         _LOG.error('Could not access {}/{}: {}'.format(
                                 group.name, s.name, e))
-                        raise
+                        raise 
                     if isinstance(v, _numpy.ndarray):
                         if isinstance(s, _config.BooleanSetting):
                             v = bool(v)  # array(True, dtype=bool) -> True
                         elif v.dtype.type == _numpy.string_:
-                            v = str(v)  # array('abc', dtype='|S3') -> 'abc'
+                            if isinstance(s, _config.ListSetting):
+                                try:
+                                    v = list(v)
+                                except TypeError:
+                                    v = []
+                            else:
+                                v = str(v) # array('abc', dtype='|S3') -> 'abc'
                         elif isinstance(s, _config.IntegerSetting):
                             v = int(v)  # array(3, dtpe='int32') -> 3
                         elif isinstance(s, _config.FloatSetting):
                             v = float(v)  # array(1.2, dtype='float64') -> 1.2
                         elif isinstance(s, _config.NumericSetting):
                             raise NotImplementedError(type(s))
-                        elif isinstance(s, _config.FloatListSetting):
+                        elif isinstance(s, _config.ListSetting):
                             v = list(v)  # convert from numpy array
                     if isinstance(v, _types.StringTypes):
                         # convert back from None, etc.
@@ -221,7 +231,7 @@ class HDF5_Storage (_FileStorage):
                 value = None
                 if isinstance(s, (_config.BooleanSetting,
                                   _config.NumericSetting,
-                                  _config.FloatListSetting)):
+                                  _config.ListSetting)):
                     value = config[s.name]
                     if value in [None, []]:
                         value = s.convert_to_text(value)
index 676333ddf2a7e9931caaf143623b0e2776425cf9..61200d418d8925d59aeae8664e90f2711b9c951c 100644 (file)
@@ -69,10 +69,16 @@ class YAML_Storage (_FileStorage):
     - 3.2
     - 1
     children: ''
+    claws:
+    - 1
+    - 2
     daisies: 13
     name: ''
     species: Norwegian Blue
     spouse: ''
+    words:
+    - cracker
+    - wants
     <BLANKLINE>
 
     Loading reads the config files from disk.
@@ -107,6 +113,8 @@ class YAML_Storage (_FileStorage):
             setting = settings[key]
             if isinstance(setting, (_config.BooleanSetting,
                                     _config.NumericSetting,
+                                    _config.ListSetting,
+                                    _config.IntegerListSetting,
                                     _config.FloatListSetting)):
                 if isinstance(value, _types.StringTypes):
                     # older versions of h5config
@@ -140,6 +148,8 @@ class YAML_Storage (_FileStorage):
                 setting = settings[key]
                 if isinstance(setting, (_config.BooleanSetting,
                                         _config.NumericSetting,
+                                        _config.ListSetting,
+                                        _config.IntegerListSetting,
                                         _config.FloatListSetting)):
                     v = value
                 elif isinstance(setting, _config.ConfigListSetting) and value:
index d49bdcce6abe7708960a5478a8e1589998d18fa7..7da3af47d3751604e8b1b0c7a363e3ca8af6eb3c 100644 (file)
@@ -40,7 +40,7 @@ Saving fills in all the config values.
 
 >>> c['syslog'] = True
 >>> c.save()
->>> pprint_HDF5(filename)  # doctest: +REPORT_UDIFF
+>>> pprint_HDF5(filename)  # doctest: +REPORT_UDIFF, +ELLIPSIS
 /
   /base
     <HDF5 dataset "age": shape (), type "<f8">
@@ -51,7 +51,9 @@ Saving fills in all the config values.
       [ 5.4  3.2  1. ]
     <HDF5 dataset "children": shape (), type "|S1">
 <BLANKLINE>
-    <HDF5 dataset "daisies": shape (), type "<i4">
+    <HDF5 dataset "claws": shape (2,), type "<i8">
+      [1 2]
+    <HDF5 dataset "daisies": shape (), type "<i...">
       13
     <HDF5 dataset "name": shape (), type "|S1">
 <BLANKLINE>
@@ -59,6 +61,8 @@ Saving fills in all the config values.
       Norwegian Blue
     <HDF5 dataset "spouse": shape (), type "|S1">
 <BLANKLINE>
+    <HDF5 dataset "words": shape (2,), type "|S7">
+      ['cracker' 'wants']
 
 If you want more details, you can dump with help strings.
 
@@ -70,7 +74,9 @@ alive: no                (The parrot is alive.  Default: no.  Choices: yes, no)
 daisies: 13              (Number of daisies pushed up by the parrot.
                           Default: 13.)
 age: 1.3                 (Parrot age in years  Default: 1.3.)
-bids: 5.4, 3.2, 1        (Prices offered for parrot.  Default: 5.4, 3.2, 1.)
+words: cracker,wants     (Words known by the parrot.  Default: cracker,wants.)
+claws: 1,2               (Claws on each foot.  Default: 1,2.)
+bids: 5.4,3.2,1          (Prices offered for parrot.  Default: 5.4,3.2,1.)
 spouse:                  (This parrot's significant other.  Default: .)
 children:                (This parrot's children.  Default: .)
 
@@ -116,6 +122,14 @@ class TestConfig (_config.Config):
             name='age',
             help='Parrot age in years',
             default=1.3),
+        _config.ListSetting(
+            name='words',
+            help='Words known by the parrot.',
+            default=['cracker', 'wants']),
+        _config.IntegerListSetting(
+            name='claws',
+            help='Claws on each foot.',
+            default=[1, 2]),
         _config.FloatListSetting(
             name='bids',
             help='Prices offered for parrot.',
@@ -145,6 +159,8 @@ _ALTERNATIVES = {  # alternative settings for testing
     'alive': True,
     'daisies': None,
     'age': None,
+    'words': ['arrrr', 'matey'],
+    'claws': [3, 0],
     'bids': [],
     'spouse': _alternative_test_config(name='Lory'),
     'children': [_alternative_test_config(name=n)
@@ -176,19 +192,19 @@ def _file_storage_tests(storage):
         c.save()
         c.load()
         nd = list(_non_defaults(c))
-        assert not nd, nd
+        assert not nd, (storage, nd)
         for key,value in _ALTERNATIVES.items():
             c[key] = value
         c.dump()
         c.save()
         na = dict(_non_alternatives(c))
-        assert not na, na
+        assert not na, (storage, na)
         c.clear()
         nd = list(_non_defaults(c))
-        assert not nd, nd
+        assert not nd, (storage, nd)
         c.load()
         na = dict(_non_alternatives(c))
-        assert not na, na
+        assert not na, (storage, na)
     finally:
         _os.remove(filename)