From fd0e1151f481bb28e205db3c03dc40f57947bf42 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 15 Mar 2012 13:31:14 -0400 Subject: [PATCH] Add ListSetting and IntegerListSetting types. Also add the storage instance to test assertion error. Peering through the logs looking for 'testing {}' wasn't cutting it ;). --- h5config/config.py | 67 ++++++++++++++++++++++++++++++++-------- h5config/storage/hdf5.py | 22 +++++++++---- h5config/storage/yaml.py | 10 ++++++ h5config/test.py | 30 +++++++++++++----- 4 files changed, 103 insertions(+), 26 deletions(-) diff --git a/h5config/config.py b/h5config/config.py index 4aa9e91..478ac3f 100644 --- a/h5config/config.py +++ b/h5config/config.py @@ -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): diff --git a/h5config/storage/hdf5.py b/h5config/storage/hdf5.py index 238b9ba..b8384bc 100644 --- a/h5config/storage/hdf5.py +++ b/h5config/storage/hdf5.py @@ -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 @@ -107,7 +107,9 @@ class HDF5_Storage (_FileStorage): [ 5.4 3.2 1. ] - + + [1 2] + 13 @@ -115,6 +117,8 @@ class HDF5_Storage (_FileStorage): Norwegian Blue + + ['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) diff --git a/h5config/storage/yaml.py b/h5config/storage/yaml.py index 676333d..61200d4 100644 --- a/h5config/storage/yaml.py +++ b/h5config/storage/yaml.py @@ -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 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: diff --git a/h5config/test.py b/h5config/test.py index d49bdcc..7da3af4 100644 --- a/h5config/test.py +++ b/h5config/test.py @@ -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 @@ -51,7 +51,9 @@ Saving fills in all the config values. [ 5.4 3.2 1. ] - + + [1 2] + 13 @@ -59,6 +61,8 @@ Saving fills in all the config values. Norwegian Blue + + ['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) -- 2.26.2