diff --git a/test/test_config.py b/test/test_config.py index 43e2714..0eb220f 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -202,6 +202,7 @@ def test_config_impl_get_opt_by_path(): assert config.cfgimpl_get_description().impl_get_opt_by_path('bool') == boo assert config.cfgimpl_get_description().impl_get_opt_by_path('gc.dummy') == dummy raises(AttributeError, "config.cfgimpl_get_description().impl_get_opt_by_path('gc.unknown')") + raises(ConfigError, "config.gc.cfgimpl_get_description().impl_get_opt_by_path('gc.unknown')") def test_information_display(): diff --git a/test/test_dyn_optiondescription.py b/test/test_dyn_optiondescription.py index 64c82bf..1c2192c 100644 --- a/test/test_dyn_optiondescription.py +++ b/test/test_dyn_optiondescription.py @@ -46,6 +46,10 @@ def return_wrong_list(): return ['---', ' '] +def return_raise(): + raise Exception('error') + + def test_build_dyndescription(): st = StrOption('st', '') dod = DynOptionDescription('dod', '', [st], callback=return_list) @@ -57,6 +61,14 @@ def test_build_dyndescription(): assert str(cfg.dodval2) == "stval2 = None" +def test_build_dyndescription_raise(): + st = StrOption('st', '') + dod = DynOptionDescription('dod', '', [st], callback=return_raise) + od = OptionDescription('od', '', [dod]) + cfg = Config(od) + raises(ConfigError, "str(cfg)") + + def test_subpath_dyndescription(): st = StrOption('st', '') dod = DynOptionDescription('dod', '', [st], callback=return_list) @@ -221,6 +233,14 @@ def test_prop_dyndescription(): assert str(cfg.cfgimpl_get_settings()[dodval2]) == str([]) +def test_prop_dyndescription_force_store_value(): + st = StrOption('st', '', properties=('force_store_value',)) + dod = DynOptionDescription('dod', '', [st], callback=return_list) + od = OptionDescription('od', '', [dod]) + od2 = OptionDescription('od', '', [od]) + raises(ConfigError, "Config(od2)") + + def test_callback_dyndescription(): st = StrOption('st', '', callback=return_dynval) dod = DynOptionDescription('dod', '', [st], callback=return_list) diff --git a/test/test_metaconfig.py b/test/test_metaconfig.py index e1034bc..ebbc891 100644 --- a/test/test_metaconfig.py +++ b/test/test_metaconfig.py @@ -28,6 +28,11 @@ def make_description(): i6 = IntOption('i6', '', properties=('disabled',)) od1 = OptionDescription('od1', '', [i1, i2, i3, i4, i5, i6]) od2 = OptionDescription('od2', '', [od1]) + return od2 + + +def make_metaconfig(): + od2 = make_description() conf1 = Config(od2, session_id='conf3') conf2 = Config(od2, session_id='conf4') meta = MetaConfig([conf1, conf2], session_id='meta') @@ -40,7 +45,7 @@ def make_description(): #FIXME ne pas mettre 2 OD differents dans un meta #FIXME serialization def test_none(): - meta = make_description() + meta = make_metaconfig() conf1, conf2 = meta.cfgimpl_get_children() assert conf1.od1.i3 is conf2.od1.i3 is None assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default @@ -69,7 +74,7 @@ def test_none(): def test_default(): - meta = make_description() + meta = make_metaconfig() conf1, conf2 = meta.cfgimpl_get_children() assert conf1.od1.i2 == conf2.od1.i2 == 1 assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default @@ -98,18 +103,19 @@ def test_default(): def test_contexts(): - meta = make_description() + meta = make_metaconfig() conf1, conf2 = meta.cfgimpl_get_children() assert conf1.od1.i2 == conf2.od1.i2 == 1 assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default - meta.set_value('od1.i2', 6, only_config=True) + errors = meta.set_value('od1.i2', 6, only_config=True) assert meta.od1.i2 == 1 assert conf1.od1.i2 == conf2.od1.i2 == 6 assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user + assert len(errors) == 0 def test_find(): - meta = make_description() + meta = make_metaconfig() i2 = meta.unwrap_from_path('od1.i2') assert [i2] == meta.find(byname='i2') assert i2 == meta.find_first(byname='i2') @@ -123,8 +129,11 @@ def test_group_error(): def test_meta_meta(): - meta1 = make_description() + meta1 = make_metaconfig() meta2 = MetaConfig([meta1]) + assert str(meta1) == """(conf3) +(conf4) +[od1]""" meta2.cfgimpl_get_settings().setowner(owners.meta) conf1, conf2 = meta1.cfgimpl_get_children() assert conf1.od1.i2 == conf2.od1.i2 == 1 @@ -156,14 +165,38 @@ def test_meta_meta(): assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta +def test_meta_config_name(): + od = make_description() + meta = MetaConfig(['name1', 'name2'], optiondescription=od) + assert len(meta.cfgimpl_get_children()) == 2 + assert meta.name1 + assert meta.name2 + + +def test_meta_new_config(): + meta = make_metaconfig() + assert len(meta.cfgimpl_get_children()) == 2 + meta.new_config('newconf1') + assert len(meta.cfgimpl_get_children()) == 3 + + +def test_meta_new_config_wrong_name(): + meta = make_metaconfig() + assert len(meta.cfgimpl_get_children()) == 2 + raises(ConflictError, "meta.new_config('conf4')") + assert len(meta.cfgimpl_get_children()) == 2 + + def test_meta_meta_set(): - meta1 = make_description() + meta1 = make_metaconfig() meta2 = MetaConfig([meta1]) meta2.cfgimpl_get_settings().setowner(owners.meta) meta2.read_write() conf1, conf2 = meta1.cfgimpl_get_children() - meta2.set_value('od1.i1', 7, only_config=True) - meta2.set_value('od1.i6', 7, only_config=True) + errors1 = meta2.set_value('od1.i1', 7, only_config=True) + errors2 = meta2.set_value('od1.i6', 7, only_config=True) + assert len(errors1) == 0 + assert len(errors2) == 2 assert conf1.od1.i1 == conf2.od1.i1 == 7 assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user assert [conf1, conf2] == meta2.find_firsts(byname='i1', byvalue=7).cfgimpl_get_children() @@ -189,7 +222,7 @@ def test_not_meta(): conf3 = Config(od2) try: conf4 = Config(od2, session_id='conf2') - except ValueError: + except ConflictError: pass else: conf3, conf4 @@ -199,7 +232,8 @@ def test_not_meta(): grp = GroupConfig([conf1, conf2]) raises(ConfigError, 'grp.od1.i1') conf1, conf2 = grp.cfgimpl_get_children() - grp.set_value('od1.i1', 7) + errors = grp.set_value('od1.i1', 7) + assert len(errors) == 0 assert grp.conf1.od1.i1 == conf2.od1.i1 == 7 assert grp.conf1.getowner(grp.conf1.unwrap_from_path('od1.i1')) is grp.conf2.getowner(grp.conf2.unwrap_from_path('od1.i1')) is owners.user @@ -211,6 +245,9 @@ def test_group_find_firsts(): conf1 = Config(od2, session_id='conf1') conf2 = Config(od2, session_id='conf2') grp = GroupConfig([conf1, conf2]) + assert str(grp) == """(conf1) +(conf2) +""" assert [conf1, conf2] == grp.find_firsts(byname='i1').cfgimpl_get_children() @@ -222,13 +259,14 @@ def test_group_group(): conf2 = Config(od2, session_id='conf10') grp = GroupConfig([conf1, conf2], 'grp') grp2 = GroupConfig([grp]) - grp2.set_value('od1.i1', 2) + errors = grp2.set_value('od1.i1', 2) assert grp2.grp.conf9.od1.i1 == 2 assert grp2.grp.conf9.getowner(i1) == owners.user + assert len(errors) == 0 def test_meta_path(): - meta = make_description() + meta = make_metaconfig() assert meta._impl_path is None assert meta.od1._impl_path == 'od1' @@ -265,6 +303,7 @@ def test_meta_master_slaves(): conf2 = Config(interface1, session_id='conf2') meta = MetaConfig([conf1, conf2]) meta.read_only() + assert [conf1, conf2] == meta.find_firsts(byname='ip_admin_eth0').cfgimpl_get_children() assert [conf1, conf2] == meta.find_firsts(byname='netmask_admin_eth0').cfgimpl_get_children() meta.read_write() raises(AttributeError, "meta.find_firsts(byname='netmask_admin_eth0')") @@ -361,19 +400,22 @@ def test_meta_force_default(): assert meta.ip_admin_eth0 == [] assert meta.conf1.ip_admin_eth0 == [] assert meta.conf2.ip_admin_eth0 == [] - meta.set_value('ip_admin_eth0', ['192.168.1.1']) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.1']) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.1'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.1'] assert meta.conf2.ip_admin_eth0 == ['192.168.1.1'] - meta.conf1.ip_admin_eth0 = ['192.168.1.2'] + errors = meta.conf1.ip_admin_eth0 = ['192.168.1.2'] assert meta.ip_admin_eth0 == ['192.168.1.1'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.2'] assert meta.conf2.ip_admin_eth0 == ['192.168.1.1'] - meta.set_value('ip_admin_eth0', ['192.168.1.3']) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.3']) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.3'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.2'] assert meta.conf2.ip_admin_eth0 == ['192.168.1.3'] - meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_default=True) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_default=True) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf2.ip_admin_eth0 == ['192.168.1.4'] @@ -399,7 +441,8 @@ def test_meta_force_dont_change_value(): assert meta.conf2.ip_admin_eth0 == [] assert conf1.getowner(ip_admin_eth0) is owners.user assert conf2.getowner(ip_admin_eth0) is owners.default - meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_dont_change_value=True) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_dont_change_value=True) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf2.ip_admin_eth0 == [] @@ -429,7 +472,8 @@ def test_meta_force_default_if_same(): assert meta.conf2.ip_admin_eth0 == [] assert conf1.getowner(ip_admin_eth0) is owners.user assert conf2.getowner(ip_admin_eth0) is owners.default - meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf2.ip_admin_eth0 == ['192.168.1.4'] @@ -441,7 +485,8 @@ def test_meta_force_default_if_same(): assert meta.conf2.ip_admin_eth0 == ['192.168.1.4'] assert conf1.getowner(ip_admin_eth0) is owners.user assert conf2.getowner(ip_admin_eth0) is owners.meta - meta.set_value('ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.5'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.3'] assert meta.conf2.ip_admin_eth0 == ['192.168.1.5'] @@ -471,7 +516,8 @@ def test_meta_force_default_if_same_and_dont_change(): assert meta.conf2.ip_admin_eth0 == [] assert conf1.getowner(ip_admin_eth0) is owners.user assert conf2.getowner(ip_admin_eth0) is owners.default - meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True, force_dont_change_value=True) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.4'], force_default_if_same=True, force_dont_change_value=True) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.4'] assert meta.conf2.ip_admin_eth0 == [] @@ -483,7 +529,8 @@ def test_meta_force_default_if_same_and_dont_change(): assert meta.conf2.ip_admin_eth0 == [] assert conf1.getowner(ip_admin_eth0) is owners.user assert conf2.getowner(ip_admin_eth0) is owners.user - meta.set_value('ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True, force_dont_change_value=True) + errors = meta.set_value('ip_admin_eth0', ['192.168.1.5'], force_default_if_same=True, force_dont_change_value=True) + assert len(errors) == 0 assert meta.ip_admin_eth0 == ['192.168.1.5'] assert meta.conf1.ip_admin_eth0 == ['192.168.1.3'] assert meta.conf2.ip_admin_eth0 == [] @@ -640,3 +687,33 @@ def test_meta_properties_meta_set_value(): ret = meta.set_value('ip_admin_eth0', '255.255.255.255', force_default_if_same=True) assert len(ret) == 1 assert isinstance(ret[0], ValueError) + + +def test_meta_reset(): + ip_admin_eth0 = StrOption('ip_admin_eth0', "ip", multi=True) + netmask_admin_eth0 = StrOption('netmask_admin_eth0', "mask", multi=True, properties=('hidden',)) + interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0]) + interface1.impl_set_group_type(groups.master) + conf1 = Config(interface1, session_id='conf1') + conf1.read_write() + conf2 = Config(interface1, session_id='conf2') + conf2.read_write() + meta = MetaConfig([conf1, conf2]) + meta.read_write() + meta.cfgimpl_get_settings().setowner(owners.meta) + assert meta.ip_admin_eth0 == [] + assert meta.conf1.ip_admin_eth0 == [] + assert meta.conf2.ip_admin_eth0 == [] + errors = meta.set_value('ip_admin_eth0', ['192.168.1.1']) + assert len(errors) == 0 + assert meta.ip_admin_eth0 == ['192.168.1.1'] + assert meta.conf1.ip_admin_eth0 == ['192.168.1.1'] + assert meta.conf2.ip_admin_eth0 == ['192.168.1.1'] + meta.conf1.ip_admin_eth0 = ['192.168.1.2'] + assert meta.ip_admin_eth0 == ['192.168.1.1'] + assert meta.conf1.ip_admin_eth0 == ['192.168.1.2'] + assert meta.conf2.ip_admin_eth0 == ['192.168.1.1'] + meta.reset('ip_admin_eth0') + assert meta.ip_admin_eth0 == [] + assert meta.conf1.ip_admin_eth0 == [] + assert meta.conf2.ip_admin_eth0 == [] diff --git a/test/test_option_consistency.py b/test/test_option_consistency.py index 3761cf2..f46b499 100644 --- a/test/test_option_consistency.py +++ b/test/test_option_consistency.py @@ -215,7 +215,6 @@ def test_consistency_not_equal_submulti(): a = IntOption('a', '', multi=submulti) b = IntOption('b', '', multi=submulti) od = OptionDescription('a', '', [a, b]) - od.impl_set_group_type(groups.master) raises(ConfigError, 'a.impl_add_consistency("not_equal", b)') @@ -250,6 +249,42 @@ def test_consistency_not_equal_masterslave(): raises(ValueError, "c.b[1] = 3") +def test_consistency_not_equal_masterslave_error_multi1(): + a = IPOption('a', '', multi=True) + b = NetmaskOption('b', '', multi=True) + c = NetmaskOption('c', '', multi=True) + od = OptionDescription('a', '', [a, b]) + od.impl_set_group_type(groups.master) + od2 = OptionDescription('b', '', [od, c]) + c.impl_add_consistency('ip_netmask', a) + raises(ConfigError, "Config(od2)") + + +def test_consistency_not_equal_masterslave_error_multi2(): + a = IPOption('a', '', multi=True) + b = NetmaskOption('b', '', multi=True) + c = IPOption('c', '', multi=True) + od = OptionDescription('a', '', [a, b]) + od.impl_set_group_type(groups.master) + od2 = OptionDescription('b', '', [od, c]) + b.impl_add_consistency('ip_netmask', c) + raises(ConfigError, "Config(od2)") + + +def test_consistency_not_equal_masterslave_error_othermaster(): + a = IPOption('a', '', multi=True) + b = NetmaskOption('b', '', multi=True) + c = IPOption('c', '', multi=True) + d = NetmaskOption('d', '', multi=True) + od = OptionDescription('a', '', [a, b]) + od.impl_set_group_type(groups.master) + od2 = OptionDescription('c', '', [c, d]) + od2.impl_set_group_type(groups.master) + od3 = OptionDescription('b', '', [od, od2]) + d.impl_add_consistency('ip_netmask', a) + raises(ConfigError, "Config(od2)") + + def test_consistency_not_equal_masterslaves_default(): a = IntOption('a', '', multi=True) b = IntOption('b', '', multi=True, default_multi=1) diff --git a/test/test_option_setting.py b/test/test_option_setting.py index 55a6dbd..84f26fd 100644 --- a/test/test_option_setting.py +++ b/test/test_option_setting.py @@ -5,7 +5,7 @@ do_autopath() from py.test import raises from tiramisu.i18n import _ -from tiramisu.error import display_list +from tiramisu.error import display_list, ConfigError from tiramisu.setting import owners, groups from tiramisu.config import Config from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \ @@ -431,8 +431,11 @@ def test_append_properties(): assert tuple(option._properties) == tuple() assert not 'test' in setting[option] setting[option].append('test') + raises(ConfigError, "setting[option].append('force_store_value')") + raises(ConfigError, "setting.append('force_store_value')") assert tuple(option._properties) == tuple() assert 'test' in setting[option] + assert setting[option].get() == ('test',) def test_reset_properties(): diff --git a/test/test_permissive.py b/test/test_permissive.py index 7caf61d..ad82466 100644 --- a/test/test_permissive.py +++ b/test/test_permissive.py @@ -154,6 +154,65 @@ def test_permissive_option(): assert props == ['disabled'] +def test_permissive_option_cache(): + descr = make_description() + u1 = descr.u1 + config = Config(descr) + setting = config.cfgimpl_get_settings() + config.read_write() + setting.remove('expire') + + props = [] + try: + config.u1 + except PropertiesOptionError as err: + props = err.proptype + assert props == ['disabled'] + props = [] + try: + config.u2 + except PropertiesOptionError as err: + props = err.proptype + assert props == ['disabled'] + + setting.setpermissive(('disabled',), u1) + props = [] + try: + config.u1 + except PropertiesOptionError as err: + props = err.proptype + assert props == [] + props = [] + try: + config.u2 + except PropertiesOptionError as err: + props = err.proptype + assert props == ['disabled'] + + setting.append('permissive') + config.u1 + props = [] + try: + config.u2 + except PropertiesOptionError as err: + props = err.proptype + assert props == ['disabled'] + + setting.remove('permissive') + props = [] + try: + config.u1 + except PropertiesOptionError as err: + props = err.proptype + assert props == [] + props = [] + try: + config.u2 + except PropertiesOptionError as err: + props = err.proptype + assert props == ['disabled'] + + def test_permissive_option_mandatory(): descr = make_description() u1 = descr.u1 diff --git a/test/test_requires.py b/test/test_requires.py index 7dc3ef2..23b310a 100644 --- a/test/test_requires.py +++ b/test/test_requires.py @@ -324,6 +324,30 @@ def test_requires_transitive_hidden_disabled(): raises(RequirementError, 'c.ip_address_service_web') +def test_requires_transitive_hidden_disabled_multiple(): + a = BoolOption('activate_service', '', True) + b = BoolOption('activate_service_web', '', True, + requires=[{'option': a, 'expected': False, 'action': 'hidden'}, + {'option': a, 'expected': False, 'action': 'disabled'}]) + d = IPOption('ip_address_service_web', '', + requires=[{'option': b, 'expected': False, 'action': 'mandatory'}]) + od = OptionDescription('service', '', [a, b, d]) + c = Config(od) + c.read_write() + c.activate_service + c.activate_service_web + c.ip_address_service_web + c.activate_service = False + # + props = [] + try: + c.activate_service_web + except PropertiesOptionError as err: + props = err.proptype + assert set(props) == {'disabled', 'hidden'} + raises(RequirementError, 'c.ip_address_service_web') + + def test_requires_not_transitive(): a = BoolOption('activate_service', '', True) b = BoolOption('activate_service_web', '', True, diff --git a/tiramisu/config.py b/tiramisu/config.py index e76c221..bdcac56 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -35,7 +35,7 @@ from .value import Values, Multi from .i18n import _ -if sys.version_info[0] >= 3: # pragma: optional cover +if sys.version_info[0] >= 3: # pragma: no cover xrange = range @@ -482,7 +482,7 @@ class SubConfig(object): # if value and/or check_properties are set, need all avalaible option # If first one has no good value or not good property check second one # and so on - only_first = first is True and byvalue is None and \ + only_first = first is True and byvalue is undefined and \ check_properties is None if only_path is not undefined: options = [(only_path, only_option)] @@ -752,7 +752,7 @@ class _CommonConfig(SubConfig): self._impl_context = weakref.ref(self) self._impl_settings.context = weakref.ref(self) self._impl_values.context = weakref.ref(self) - storage = get_storage('config', test=self._impl_test, **state['_storage']) + storage = get_storage(test=self._impl_test, **state['_storage']) self._impl_values._impl_setstate(storage) self._impl_settings._impl_setstate(storage) self._impl_meta = None @@ -836,8 +836,6 @@ class GroupConfig(_CommonConfig): if not isinstance(child, _CommonConfig): raise ValueError(_("groupconfig's children must be Config, MetaConfig or GroupConfig")) name_ = child._impl_name - if name_ is None: - raise ValueError(_('name must be set to config before creating groupconfig')) names.append(name_) if len(names) != len(set(names)): for idx in xrange(1, len(names) + 1): @@ -923,16 +921,16 @@ class GroupConfig(_CommonConfig): else: return GroupConfig(self._find_return_results(ret, raise_if_not_found)) - def __repr__(self): - return object.__repr__(self) - def __str__(self): ret = '' for child in self._impl_children: ret += '({0})\n'.format(child._impl_name) - ret += super(GroupConfig, self).__str__() + if self._impl_descr is not None: + ret += super(GroupConfig, self).__str__() return ret + __repr__ = __str__ + def getattr(self, name, force_permissive=False, validate=True, _setting_properties=undefined, _self_properties=undefined, index=None, returns_raise=False): @@ -951,14 +949,14 @@ class MetaConfig(GroupConfig): __slots__ = tuple() def __init__(self, children, session_id=None, persistent=False, - optiondescription=None): + optiondescription=None, _force_store_values=True): descr = None if optiondescription is not None: new_children = [] for child_session_id in children: #FIXME _force_store_values doit etre a true si inexistant ! - new_children.append(Config(optiondescription, persistent=True, - session_id=child_session_id, _force_store_values=False)) + new_children.append(Config(optiondescription, persistent=persistent, + session_id=child_session_id, _force_store_values=_force_store_values)) children = new_children for child in children: if not isinstance(child, _CommonConfig): @@ -1004,12 +1002,10 @@ class MetaConfig(GroupConfig): else: child_value = child.getattr(path) if force_default or value == child_value: - childret = child.cfgimpl_get_values().reset(opt, path=path, - validate=False, - _setting_properties=setting_properties, - _commit=False) - if childret is not None: - ret.append(childret) + child.cfgimpl_get_values().reset(opt, path=path, + validate=False, + _setting_properties=setting_properties, + _commit=False) continue if force_dont_change_value: child_value = child.getattr(path, _setting_properties=setting_properties, @@ -1018,7 +1014,7 @@ class MetaConfig(GroupConfig): ret.append(child_value) elif value != child_value: childret = child.setattr(path, child_value, _commit=False, not_raises=True) - if childret is not None: + if childret is not None: # pragma: no cover ret.append(childret) setret = self.setattr(path, value, _commit=_commit, not_raises=True) @@ -1038,6 +1034,13 @@ class MetaConfig(GroupConfig): validate=False, _setting_properties=setting_properties) - def new_config(self, session_id=None, persistent=False): - return Config(self._impl_descr, session_id=session_id, - persistent=persistent) + def new_config(self, session_id, persistent=False): + config = Config(self._impl_descr, session_id=session_id, + persistent=persistent) + + if config._impl_name in [child._impl_name for child in self._impl_children]: # pragma: no cover + raise ConflictError(_('config name must be uniq in ' + 'groupconfig for {0}').format(config._impl_name)) + config._impl_meta = weakref.ref(self) + self._impl_children.append(config) + return config diff --git a/tiramisu/option/baseoption.py b/tiramisu/option/baseoption.py index ff4b4d6..cfb6429 100644 --- a/tiramisu/option/baseoption.py +++ b/tiramisu/option/baseoption.py @@ -554,7 +554,7 @@ class Option(OnlyOption): return opt_value else: opt_value = None - else: + else: # pragma: no cover return opt_value elif index is None: opt_value = opt.impl_getdefault() @@ -719,7 +719,7 @@ class Option(OnlyOption): ' must be a list').format( value, self.impl_get_display_name())) for idx, val in enumerate(value): - if isinstance(val, list): + if isinstance(val, list): # pragma: no cover return ValueError(_('invalid value "{}" for "{}" ' 'which must not be a list').format(val, self.impl_get_display_name())) diff --git a/tiramisu/option/optiondescription.py b/tiramisu/option/optiondescription.py index 00f4a4f..c40ff74 100644 --- a/tiramisu/option/optiondescription.py +++ b/tiramisu/option/optiondescription.py @@ -36,7 +36,7 @@ StorageOptionDescription = get_storages_option('optiondescription') name_regexp = re.compile(r'^[a-zA-Z\d\-_]*$') import sys -if sys.version_info[0] >= 3: # pragma: optional cover +if sys.version_info[0] >= 3: # pragma: no cover xrange = range del(sys) @@ -141,18 +141,18 @@ class OptionDescription(BaseOption, StorageOptionDescription): if func not in allowed_const_list and is_multi: is_masterslaves = option.impl_is_master_slaves() if not is_masterslaves: - raise ValueError(_('malformed consistency option "{0}" ' + raise ConfigError(_('malformed consistency option "{0}" ' 'must be a master/slaves').format( option.impl_getname())) masterslaves = option.impl_get_master_slaves() for opt in all_cons_opts: if func not in allowed_const_list and is_multi: if not opt.impl_is_master_slaves(): - raise ValueError(_('malformed consistency option "{0}" ' + raise ConfigError(_('malformed consistency option "{0}" ' 'must not be a multi for "{1}"').format( option.impl_getname(), opt.impl_getname())) elif masterslaves != opt.impl_get_master_slaves(): - raise ValueError(_('malformed consistency option "{0}" ' + raise ConfigError(_('malformed consistency option "{0}" ' 'must be in same master/slaves for "{1}"').format( option.impl_getname(), opt.impl_getname())) _consistencies.setdefault(opt, @@ -318,8 +318,6 @@ class OptionDescription(BaseOption, StorageOptionDescription): values = carry_out_calculation(self, context=context, callback=callback, callback_params=callback_params) - if isinstance(values, Exception): - raise values if len(values) > len(set(values)): raise ConfigError(_('DynOptionDescription callback return not unique value')) for val in values: @@ -327,16 +325,14 @@ class OptionDescription(BaseOption, StorageOptionDescription): raise ValueError(_("invalid suffix: {0} for option").format(val)) return values - def _impl_search_dynchild(self, name=undefined, context=undefined): + def _impl_search_dynchild(self, name, context): ret = [] for child in self._impl_st_getchildren(context, only_dyn=True): cname = child.impl_getname() - if name is undefined or name.startswith(cname): + if name.startswith(cname): path = cname for value in child._impl_get_suffixes(context): - if name is undefined: - ret.append(SynDynOptionDescription(child, cname + value, path + value, value)) - elif name == cname + value: + if name == cname + value: return SynDynOptionDescription(child, name, path + value, value) return ret @@ -388,9 +384,6 @@ class DynOptionDescription(OptionDescription): if isinstance(child, SymLinkOption): raise ConfigError(_('cannot set symlinkoption in a ' 'dynoptiondescription')) - if isinstance(child, SymLinkOption): - raise ConfigError(_('cannot set symlinkoption in a ' - 'dynoptiondescription')) child._impl_setsubdyn(self) self.impl_set_callback(callback, callback_params) diff --git a/tiramisu/setting.py b/tiramisu/setting.py index ce8ed05..e302678 100644 --- a/tiramisu/setting.py +++ b/tiramisu/setting.py @@ -732,7 +732,7 @@ class Settings(object): # transitive action, force expected value = expected[0] inverse = False - else: + else: # pragma: no cover raise value else: orig_value = value diff --git a/tiramisu/storage/__init__.py b/tiramisu/storage/__init__.py index e5dc61c..a6f5d51 100644 --- a/tiramisu/storage/__init__.py +++ b/tiramisu/storage/__init__.py @@ -49,7 +49,7 @@ class StorageType(object): mod = None def set(self, name): # pragma: optional cover - if self.storage_type is not None: + if self.storage_type is not None: # pragma: no cover if self.storage_type == name: return raise ConfigError(_('storage_type is already set, cannot rebind it')) @@ -65,7 +65,7 @@ class StorageType(object): modulepath = '{0}.storage.{1}'.format(MODULE_PATH, self.storage_type) try: mod = __import__(modulepath) - except ImportError: + except ImportError: # pragma: no cover raise SystemError(_('cannot import the storage {0}').format( self.default_storage)) for token in modulepath.split(".")[1:]: @@ -81,7 +81,7 @@ default_validation = StorageType() default_validation.set(DEFAULT_STORAGE) -def set_storage(type_, name, **kwargs): # pragma: optional cover +def set_storage(type_, name): # pragma: optional cover """Change storage's configuration :params name: is the storage name. If storage is already set, cannot @@ -89,19 +89,8 @@ def set_storage(type_, name, **kwargs): # pragma: optional cover Other attributes are differents according to the selected storage's name """ - if type_ == 'option': - storage_option_type.set(name) - setting = storage_option_type.get().setting - else: - storage_type.set(name) - setting = storage_type.get().setting - for option, value in kwargs.items(): - try: - getattr(setting, option) - setattr(setting, option, value) - except AttributeError: - raise ValueError(_('option {0} not already exists in storage {1}' - '').format(option, name)) + storage_type.set(name) + setting = storage_type.get().setting def _impl_getstate_setting(): @@ -113,16 +102,10 @@ def _impl_getstate_setting(): return state -def get_storage(type_, session_id, persistent, test): # pragma: optional cover +def get_storage(session_id, persistent, test): # pragma: optional cover """all used when __setstate__ a Config """ - #FIXME ca sert ??? - if type_ == 'option': - return storage_option_type.get().Storage(session_id, persistent, test) - elif type_ == 'config': - return storage_type.get().Storage(session_id, persistent, test) - else: - return default_validation.get().Storage(session_id, persistent, test) + return storage_type.get().Storage(session_id, persistent, test) def get_storages(context, session_id, persistent): diff --git a/tiramisu/storage/dictionary/option.py b/tiramisu/storage/dictionary/option.py index 4a8799b..f58aedc 100644 --- a/tiramisu/storage/dictionary/option.py +++ b/tiramisu/storage/dictionary/option.py @@ -402,12 +402,6 @@ class StorageOptionDescription(StorageBase): __slots__ = ('_children', '_cache_paths', '_cache_consistencies', '_group_type', '_state_group_type', '_cache_force_store_values') - def __init__(self, name, multi, warnings_only, doc, extra): - super(StorageOptionDescription, self).__init__(name, multi, - warnings_only, doc, - None, undefined, - undefined, undefined) - def _add_children(self, child_names, children): _setattr = object.__setattr__ _setattr(self, '_children', (tuple(child_names), tuple(children))) @@ -550,7 +544,7 @@ class StorageOptionDescription(StorageBase): if _filter(path, option) is False: continue if only_first: - return find_results[0] + return find_results return find_results def _impl_st_getchildren(self, context, only_dyn=False): diff --git a/tiramisu/storage/dictionary/setting.py b/tiramisu/storage/dictionary/setting.py index 07f6787..bfa00ff 100644 --- a/tiramisu/storage/dictionary/setting.py +++ b/tiramisu/storage/dictionary/setting.py @@ -36,9 +36,6 @@ class Properties(Cache): def getproperties(self, path, default_properties): return self._properties.get(path, set(default_properties)) - def hasproperties(self, path): - return path in self._properties - def reset_all_properties(self): self._properties.clear() diff --git a/tiramisu/storage/dictionary/storage.py b/tiramisu/storage/dictionary/storage.py index e356b07..99edeaa 100644 --- a/tiramisu/storage/dictionary/storage.py +++ b/tiramisu/storage/dictionary/storage.py @@ -15,7 +15,7 @@ # along with this program. If not, see . # ____________________________________________________________ from ...i18n import _ -from ...error import ConfigError +from ...error import ConfigError, ConflictError from ..util import SerializeObject @@ -45,7 +45,7 @@ class Storage(object): def __init__(self, session_id, persistent, test=False): if not test and session_id in _list_sessions: # pragma: optional cover - raise ValueError(_('session already used')) + raise ConflictError(_('session already used')) if persistent: # pragma: optional cover raise ValueError(_('a dictionary cannot be persistent')) self.session_id = session_id diff --git a/tiramisu/storage/dictionary/value.py b/tiramisu/storage/dictionary/value.py index 18c2eb2..4cd9c7f 100644 --- a/tiramisu/storage/dictionary/value.py +++ b/tiramisu/storage/dictionary/value.py @@ -85,12 +85,6 @@ class Values(Cache): self._setvalue_info(3, idx, owner, values, index, vidx) self._values = tuple(values) - def getvalue(self, path, session, index=None): - """get value for a path - return: only value, not the owner - """ - return self._getvalue(path, 2, index) - def hasvalue(self, path, index=None): """if path has a value return: boolean diff --git a/tiramisu/storage/sqlite3/setting.py b/tiramisu/storage/sqlite3/setting.py index 2923538..b39dd1e 100644 --- a/tiramisu/storage/sqlite3/setting.py +++ b/tiramisu/storage/sqlite3/setting.py @@ -49,12 +49,6 @@ class Properties(Sqlite3DB): else: return set(self._sqlite_decode(value[0])) - def hasproperties(self, path): - path = self._sqlite_encode_path(path) - return self._storage.select("SELECT properties FROM property WHERE " - "path = ? AND session_id = ? LIMIT 1", (path, self._session_id) - ) is not None - def reset_all_properties(self): self._storage.execute("DELETE FROM property WHERE session_id = ?", (self._session_id,)) diff --git a/tiramisu/storage/sqlite3/value.py b/tiramisu/storage/sqlite3/value.py index e9f5344..c381976 100644 --- a/tiramisu/storage/sqlite3/value.py +++ b/tiramisu/storage/sqlite3/value.py @@ -72,16 +72,6 @@ class Values(Sqlite3DB): self._session_id), commit=commit) - def getvalue(self, path, session, index=None): - """get value for an option - return: only value, not the owner - """ - path = self._sqlite_encode_path(path) - values = self._sqlite_select(path, index) - if values is None: - return values - return self._sqlite_decode(values[0]) - def hasvalue(self, path, index=None): """if opt has a value return: boolean diff --git a/tiramisu/value.py b/tiramisu/value.py index 1ea7fb1..52b0d59 100644 --- a/tiramisu/value.py +++ b/tiramisu/value.py @@ -73,21 +73,13 @@ class Values(object): raise value else: if isinstance(value, Multi): - if index is not None: - value = value[index] - if isinstance(value, SubMulti): - if submulti_index is not undefined: - value = value[submulti_index] - else: - value = list(value) - else: - new_value = [] - for val in value: - if isinstance(val, SubMulti): - val = list(val) - new_value.append(val) - value = new_value - del new_value + new_value = [] + for val in value: + if isinstance(val, SubMulti): + val = list(val) + new_value.append(val) + value = new_value + del new_value return value # if value has callback and is not set if opt.impl_has_callback(): @@ -230,12 +222,6 @@ class Values(object): "enables us to use the pythonic dictionary-like access to values" return self._get_cached_value(opt) - def getitem(self, opt, validate=True, force_permissive=False): - """ - """ - return self._get_cached_value(opt, validate=validate, - force_permissive=force_permissive) - def _get_cached_value(self, opt, path=None, validate=True, force_permissive=False, trusted_cached_properties=True, validate_properties=True, @@ -411,8 +397,6 @@ class Values(object): # user didn't change value, so not write # valid opt context = self._getcontext() - if _setting_properties is undefined: - _setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=False) if 'validator' in _setting_properties: session = context.cfgimpl_get_values()._p_.getsession() if opt._has_consistencies(): @@ -476,12 +460,8 @@ class Values(object): if valid_masterslave and opt.impl_is_master_slaves(): if session is None: session = self._p_.getsession() - if index is not None: - len_value = index - setitem = False - else: - len_value = len(value) - setitem = True + len_value = len(value) + setitem = True val = opt.impl_get_master_slaves().validate(self, opt, len_value, path, session, setitem=setitem) if isinstance(val, Exception): return val @@ -502,8 +482,6 @@ class Values(object): context = self._getcontext() setting = context.cfgimpl_get_settings() self_properties = setting._getproperties(opt, path, read_write=False) - if 'frozen' in self_properties and 'force_default_on_freeze' in self_properties: - return False if self._p_.getowner(path, owners.default, session, only_default=True) is not owners.default: return False if context.cfgimpl_get_meta() is not None: @@ -834,8 +812,6 @@ class Multi(list): session = context.cfgimpl_get_values()._p_.getsession() fake_context = context._gen_fake_values(session) fake_multi = Multi(list(self), weakref.ref(fake_context), self.opt, self.path) - if isinstance(fake_multi, Exception): - raise fake_multi fake_multi.append(value, validate=False, force=True, setitem=setitem) self._validate(value, fake_context, index, True)