diff --git a/test/test_cache.py b/test/test_cache.py index e7b615b..f2b0b9d 100644 --- a/test/test_cache.py +++ b/test/test_cache.py @@ -439,9 +439,9 @@ def test_cache_master_and_slaves_master(): assert cfg._config.cfgimpl_get_values()._p_.get_cached() == {} else: compare(cfg._config.cfgimpl_get_settings()._p_.get_cached(), {None: {None: (global_props, None)}, - 'val1': {None: (val1_props, None)}, - 'val1.val1': {None: (val1_val1_props, None)}, - 'val1.val2': {idx_val2: (val1_val2_props, None)}}) + 'val1': {None: (val1_props, None)}, + 'val1.val1': {None: (val1_val1_props, None)}, + 'val1.val2': {idx_val2: (val1_val2_props, None)}}) # len is 0 so don't get any value compare(cfg._config.cfgimpl_get_values()._p_.get_cached(), {'val1.val1': {None: ([], None)}}) # diff --git a/test/test_requires.py b/test/test_requires.py index f07e4dc..07ccd0d 100644 --- a/test/test_requires.py +++ b/test/test_requires.py @@ -948,10 +948,26 @@ def test_master_slave_requires(): assert api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() is None api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.set('255.255.255.255') assert api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get() == '255.255.255.255' + assert api.option.make_dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.2'], + 'ip_admin_eth0.netmask_admin_eth0': [None, '255.255.255.255']} # api.option('ip_admin_eth0.ip_admin_eth0').value.set(['192.168.1.2', '192.168.1.1']) assert api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get() is None raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()") + ret = api.option.make_dict() + assert set(ret.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) + assert ret['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1'] + assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2 + assert ret['ip_admin_eth0.netmask_admin_eth0'][0] == None + assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError) + # + api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.set('255.255.255.255') + ret = api.option.make_dict() + assert set(ret.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0']) + assert ret['ip_admin_eth0.ip_admin_eth0'] == ['192.168.1.2', '192.168.1.1'] + assert len(ret['ip_admin_eth0.netmask_admin_eth0']) == 2 + assert ret['ip_admin_eth0.netmask_admin_eth0'][0] == '255.255.255.255' + assert isinstance(ret['ip_admin_eth0.netmask_admin_eth0'][1], PropertiesOptionError) def test_master_slave_requires_no_master(): @@ -981,3 +997,4 @@ def test_master_slave_requires_no_master(): api.option('activate').value.set(False) raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()") raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()") + assert api.option.make_dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.1'], 'activate': False} diff --git a/tiramisu/config.py b/tiramisu/config.py index 54b8b4a..7f2124e 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -473,13 +473,32 @@ class SubConfig(object): :returns: dict of Option's name (or path) and values """ - pathsvalues = [] + pathsvalues = {} if _currpath is None: _currpath = [] if withoption is None and withvalue is not undefined: raise ValueError(_("make_dict can't filtering with value without " "option")) context = self.cfgimpl_get_context() + self._make_dict(context, + config_bag, + flatten, + _currpath, + withoption, + withvalue, + fullpath, + pathsvalues) + return pathsvalues + + def _make_dict(self, + context, + config_bag, + flatten, + _currpath, + withoption, + withvalue, + fullpath, + pathsvalues): if withoption is not None: mypath = self.cfgimpl_get_path() for path in context.find(bytype=None, @@ -519,7 +538,10 @@ class SubConfig(object): _currpath, flatten, soption_bag, - fullpath=fullpath) + fullpath, + context, + withvalue) + #withoption can be set to None below ! if withoption is None: for opt in self.cfgimpl_get_description().impl_getchildren(config_bag, context): @@ -530,16 +552,14 @@ class SubConfig(object): path, None, config_bag) - #path = self._get_subpath(name) self._make_sub_dict(name, pathsvalues, _currpath, flatten, soption_bag, - fullpath=fullpath) - if _currpath == []: - options = dict(pathsvalues) - return options + fullpath, + context, + withvalue) return pathsvalues def _make_sub_dict(self, @@ -548,45 +568,60 @@ class SubConfig(object): _currpath, flatten, option_bag, - fullpath=False): - try: - option = option_bag.option - if not option.impl_is_optiondescription(): - if option.impl_is_master_slaves('slave'): - ret = [] + fullpath, + context, + withvalue): + option = option_bag.option + if option.impl_is_optiondescription(): + try: + self.cfgimpl_get_settings().validate_properties(option_bag) + subconfig = SubConfig(option_bag.option, + self._impl_context, + option_bag.config_bag, + option_bag.path) + subconfig._make_dict(context, + option_bag.config_bag, + flatten, + _currpath + [name], + None, + withvalue, + fullpath, + pathsvalues) + except PropertiesOptionError: + pass + else: + if option.impl_is_master_slaves('slave'): + ret = [] + try: + self.cfgimpl_get_settings().validate_properties(option_bag) length = self.cfgimpl_get_length_slave(option_bag) - if length: - for idx in range(length): - soption_bag = OptionBag() - soption_bag.set_option(option, - option_bag.path, - idx, - option_bag.config_bag) + except PropertiesOptionError: + return + if length: + for idx in range(length): + soption_bag = OptionBag() + soption_bag.set_option(option, + option_bag.path, + idx, + option_bag.config_bag) + try: ret.append(self.getattr(name, soption_bag)) - self.cfgimpl_get_settings().validate_properties(option_bag) - else: + except PropertiesOptionError as err: + ret.append(err) + else: + try: ret = self.getattr(name, option_bag) + except PropertiesOptionError: + return + if flatten: + name_ = option.impl_getname() + elif fullpath: + name_ = self._get_subpath(name) else: - ret = self.get_subconfig(name, - option_bag) - except PropertiesOptionError: - pass - else: - if option.impl_is_optiondescription(): - pathsvalues += ret.make_dict(option_bag.config_bag, - flatten=flatten, - _currpath=_currpath + [name], - fullpath=fullpath) - else: - if flatten: - name = option.impl_getname() - elif fullpath: - name = self._get_subpath(name) - else: - name = '.'.join(_currpath + [name]) - pathsvalues.append((name, ret)) + name_ = '.'.join(_currpath + [name]) + pathsvalues[name_] = ret def cfgimpl_get_path(self, dyn=True): diff --git a/tiramisu/setting.py b/tiramisu/setting.py index ba1411c..5951c73 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -498,7 +498,7 @@ class Settings(object): is_indexed = False if option.impl_is_master_slaves('slave'): idx = option_bag.index - elif option.impl_is_multi(): + elif option.impl_is_multi() and option_bag.index is not None: is_indexed = True config_bag = option_bag.config_bag.copy() config_bag.set_permissive() @@ -514,8 +514,7 @@ class Settings(object): try: value = context.getattr(reqpath, soption_bag) - #if is_indexed: - if is_indexed and option_bag.index is not None: + if is_indexed: value = value[option_bag.index] except PropertiesOptionError as err: properties = err.proptype