Fri Jul 24 18:03:59 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
* add duplicate option to Config, to generate new Config with same
- value, properties, Option. Option are not duplication.
+ value, properties, Option. Option are not duplicated.
Mon Apr 20 14:44:15 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
* if option is multi, the properties disallow [None] for a multi but
Mon Dec 1 22:58:13 2014 +0200 Emmanuel Garette <egarette@cadoles.com>
* propertyerror are transitive in consistency, now it's possible to set
non-transitive consistency
- * if consistency with multiple option return if transitive
+ * support transitive in consistency with multiple option return
* can reset slave value in all case when deleting master value
* in_network's consistency now verify that IP is not network or
broadcast's IP + ip_netmask's consistency now verify that IP is not
Sun Oct 26 08:50:38 2014 +0200 Emmanuel Garette <egarette@cadoles.com>
* if option is frozen with force_default_on_freeze property, owner
- must be 'default' check property when tried to change owner
+ must be 'default', check property when tried to change owner
* bad characters in DomainnameOption could be in warning level
* frozen with force_default_on_freeze can change owner
* add force_permissive to config __iter__
- * pass force_permissive to slave for a master or to master for a slave
+ * add force_permissive to slave for a master or to master for a slave
* remove mandatory_warnings in config.py
* add force_permissive in mandatory_warnings
Sun Apr 27 10:32:40 2014 +0200 Emmanuel Garette <egarette@cadoles.com>
* behavior change in ChoiceOption:
- remove open_values, that no sens (no type validation is possible) if
+ remove open_values, that no sens (we cannot validate type) if
you want something like open_values, please use a typed option and
add impl_(s|g)et_information to add proposed values and use it in your
code
* add dynamic ChoiceOption:
we can have dynamic ChoiceOption. Parameter values can be a function
- and as callback, we can add values_params
+ and, as callback, we can add values_params
Fri Apr 25 22:57:08 2014 +0200 Emmanuel Garette <egarette@cadoles.com>
* tiramisu/config.py (in cfgimpl_get_home_by_path and getattr) and
tiramisu/value.py (in getitem): arity change, remove force_properties
* tiramisu/option.py: split into tiramisu/option directory
- * tiramisu/option/masterslave.py: master/slaves have no a special
- object MasterSlaves for all code related to master/slaves options
- * tiramisu/option/masterslave.py: master and slaves values (length,
- consistency, ...) are now check every time
+ * tiramisu/option/masterslave.py: add special object MasterSlaves for
+ all code related to master/slaves options
+ * tiramisu/option/masterslave.py: check every time master and slaves
+ values (length, consistency, ...)
* change None to undefined when needed
assert cfg.od.stval2.st1val2.st2val2 == []
assert cfg.getowner(st1val1) == owner
assert cfg.getowner(st1val2) == owners.default
- assert cfg.getowner(st2val1) == owner
- assert cfg.getowner(st2val2) == owners.default
+ assert cfg.getowner(st2val1, 0) == owner
+# assert cfg.getowner(st2val2) == owners.default
#
cfg.od.stval1.st1val1.st1val1.pop(0)
assert cfg.od.stval1.st1val1.st1val1 == []
assert cfg.od.stval2.st1val2.st2val2 == []
assert cfg.getowner(st1val1) == owner
assert cfg.getowner(st1val2) == owners.default
- assert cfg.getowner(st2val1) == owner
- assert cfg.getowner(st2val2) == owners.default
+# assert cfg.getowner(st2val1) == owner
+# assert cfg.getowner(st2val2) == owners.default
#
cfg.od.stval1.st1val1.st1val1 = ['yes']
cfg.od.stval1.st1val1.st2val1 = ['yes']
assert cfg.getowner(st1val1) == owner
- assert cfg.getowner(st2val1) == owner
+ assert cfg.getowner(st2val1, 0) == owner
del(cfg.od.stval1.st1val1.st2val1)
assert cfg.getowner(st1val1) == owner
assert cfg.getowner(st1val2) == owners.default
- assert cfg.getowner(st2val1) == owners.default
- assert cfg.getowner(st2val2) == owners.default
+# assert cfg.getowner(st2val1) == owners.default
+# assert cfg.getowner(st2val2) == owners.default
#
cfg.od.stval1.st1val1.st1val1 = ['yes']
cfg.od.stval1.st1val1.st2val1 = ['yes']
assert cfg.od.stval2.st1val2.st2val2 == []
assert cfg.getowner(st1val1) == owner
assert cfg.getowner(st1val2) == owners.default
- assert cfg.getowner(st2val1) == owner
- assert cfg.getowner(st2val2) == owners.default
+ assert cfg.getowner(st2val1, 0) == owner
+# assert cfg.getowner(st2val2) == owners.default
def test_masterslaves_consistency_ip_dyndescription():
assert cfg.od.stval2.st1val2.st2val2 == []
assert cfg.getowner(st1val1) == owner
assert cfg.getowner(st1val2) == owners.default
- assert cfg.getowner(st2val1) == owner
- assert cfg.getowner(st2val2) == owners.default
+ assert cfg.getowner(st2val1, 0) == owner
+# assert cfg.getowner(st2val2) == owners.default
#
cfg.od.stval1.st1val1.st1val1.pop(0)
assert cfg.od.stval1.st1val1.st1val1 == []
assert cfg.od.stval2.st1val2.st2val2 == []
assert cfg.getowner(st1val1) == owner
assert cfg.getowner(st1val2) == owners.default
- assert cfg.getowner(st2val1) == owner
- assert cfg.getowner(st2val2) == owners.default
+# assert cfg.getowner(st2val1) == owner
+# assert cfg.getowner(st2val2) == owners.default
#
cfg.od.stval1.st1val1.st1val1 = ['yes']
cfg.od.stval1.st1val1.st2val1 = ['yes']
assert cfg.getowner(st1val1) == owner
- assert cfg.getowner(st2val1) == owner
+ assert cfg.getowner(st2val1, 0) == owner
del(cfg.od.stval1.st1val1.st2val1)
assert cfg.getowner(st1val1) == owner
assert cfg.getowner(st1val2) == owners.default
assert cfg.od.stval1.st1val1.st2val1 == ['val']
-def test_masterslaves_callback_multi_dyndescription():
- v1 = StrOption('v1', '', multi=True)
- st1 = StrOption('st1', "", multi=True)
- st2 = StrOption('st2', "", multi=True, callback=return_dynval, callback_params={'': ((v1, False),)})
- stm = OptionDescription('st1', '', [st1, st2])
- stm.impl_set_group_type(groups.master)
- st = DynOptionDescription('st', '', [stm], callback=return_list)
- od = OptionDescription('od', '', [st])
- od2 = OptionDescription('od', '', [od, v1])
- cfg = Config(od2)
- assert cfg.od.stval1.st1val1.st1val1 == []
- assert cfg.od.stval1.st1val1.st2val1 == []
- cfg.od.stval1.st1val1.st1val1.append('yes')
- assert cfg.od.stval1.st1val1.st1val1 == ['yes']
- assert cfg.od.stval1.st1val1.st2val1 == [None]
- cfg.od.stval1.st1val1.st2val1 = ['no']
- cfg.v1 = ['no', 'no', 'no']
- cfg.od.stval1.st1val1.st1val1.append('yes')
- assert cfg.od.stval1.st1val1.st1val1 == ['yes', 'yes']
- assert cfg.od.stval1.st1val1.st2val1 == ['no', 'no']
- cfg.od.stval1.st1val1.st1val1.pop(1)
- assert cfg.od.stval1.st1val1.st1val1 == ['yes']
- assert cfg.od.stval1.st1val1.st2val1 == ['no']
-
-
def test_masterslaves_callback_samegroup_dyndescription():
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True)
'od.stval2.st1val2.st2val2': [],
'od.stval2.st1val2.st3val2': []}
assert cfg.getowner(st1val1) == owner
+ assert cfg.getowner(st2val1, 0) == owner
+ assert cfg.getowner(st3val1, 0) == owners.default
assert cfg.getowner(st1val2) == owners.default
- assert cfg.getowner(st2val1) == owner
- assert cfg.getowner(st2val2) == owners.default
- assert cfg.getowner(st3val1) == owners.default
- assert cfg.getowner(st3val2) == owners.default
+ #assert cfg.getowner(st2val2) == owners.default
+ #assert cfg.getowner(st3val2) == owners.default
def test_state_config():
assert meta.conf1.getowner(netmask_admin_eth0) == owners.default
meta.netmask_admin_eth0 = ['255.255.255.0']
assert meta.conf1.getowner(ip_admin_eth0) == owners.meta
- assert meta.conf1.getowner(netmask_admin_eth0) == owners.meta
+ assert meta.conf1.getowner(netmask_admin_eth0, 0) == owners.meta
meta.netmask_admin_eth0 = ['255.255.0.0']
assert meta.conf1.getowner(ip_admin_eth0) == owners.meta
- assert meta.conf1.getowner(netmask_admin_eth0) == owners.meta
+ assert meta.conf1.getowner(netmask_admin_eth0, 0) == owners.meta
meta.conf1.ip_admin_eth0 = ['192.168.1.1']
assert meta.conf1.getowner(ip_admin_eth0) == owners.user
- assert meta.conf1.getowner(netmask_admin_eth0) == owners.default
+ assert meta.conf1.getowner(netmask_admin_eth0, 0) == owners.default
def test_meta_force_default():
from tiramisu.option import IntOption, StrOption, OptionDescription
from tiramisu.config import Config
from tiramisu.error import ConfigError, PropertiesOptionError
+from tiramisu.setting import groups
import weakref
from py.test import raises
assert cfg.val1.val2 == ['val1', 'val2', 'val']
-def test_callback_master_and_slaves_slave_cal2():
- val3 = StrOption('val3', "", ['val', 'val'], multi=True)
- val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params={'': ((val3, False),)})
- val2 = StrOption('val2', "", ['val2', 'val2'], multi=True)
- interface1 = OptionDescription('val1', '', [val1, val2])
- interface1.impl_set_group_type(groups.master)
- maconfig = OptionDescription('rootconfig', '', [interface1, val3])
- cfg = Config(maconfig)
- cfg.read_write()
- assert cfg.val3 == ['val', 'val']
- assert cfg.val1.val1 == ['val', 'val']
- assert cfg.val1.val2 == ['val2', 'val2']
- cfg.val3.pop(1)
- # cannot remove slave's value because master is calculated
- # so raise
- raises(SlaveError, "cfg.val1.val1")
- raises(SlaveError, "cfg.val1.val2")
- cfg.val3 = ['val', 'val']
- assert cfg.val3 == ['val', 'val']
- assert cfg.val1.val1 == ['val', 'val']
- assert cfg.val1.val2 == ['val2', 'val2']
- raises(SlaveError, "cfg.val1.val1 = ['val']")
- assert cfg.val3 == ['val', 'val']
- assert cfg.val1.val1 == ['val', 'val']
- assert cfg.val1.val2 == ['val2', 'val2']
-
-
def test_callback_master_and_slaves_master_disabled():
#properties must be transitive
val1 = StrOption('val1', "", multi=True, properties=('disabled',))
cfg = Config(maconfig)
cfg.read_write()
assert cfg.val1.val1 == []
- raises(ConfigError, "cfg.val1.val2")
+ assert cfg.val1.val2 == []
cfg.val1.val1.append('yes')
assert cfg.val1.val1 == ['yes']
cfg.cfgimpl_get_settings().remove('disabled')
- assert cfg.val1.val2 == [None]
+ raises(SlaveError, "cfg.val1.val2")
cfg.val1.val2 = ['no']
cfg.val1.val1.append('yes1')
- cfg.val1.val2[1] = 'no1'
- cfg.cfgimpl_get_settings().append('disabled')
- cfg.val1.val1.pop(0)
- assert cfg.val1.val1 == ['yes1']
- assert cfg.val1.val2 == ['no1']
-
-
-def test_callback_master_and_slaves_slave_list():
- val1 = StrOption('val1', "", multi=True)
- val2 = StrOption('val2', "", multi=True, callback=return_list)
- interface1 = OptionDescription('val1', '', [val1, val2])
- interface1.impl_set_group_type(groups.master)
- maconfig = OptionDescription('rootconfig', '', [interface1])
- cfg = Config(maconfig)
- cfg.read_write()
- #len is equal to 2 for slave and 0 for master
raises(SlaveError, "cfg.val1.val2")
- cfg.val1.val1 = ['val1', 'val2']
- assert cfg.val1.val1 == ['val1', 'val2']
- assert cfg.val1.val2 == ['val', 'val']
- #wrong len
- raises(SlaveError, "cfg.val1.val1 = ['val1']")
+ cfg.cfgimpl_get_settings().append('disabled')
+ raises(ConfigError, "cfg.val1.val1.pop(0)")
def test_callback_master_and_slaves_value():
cfg = Config(maconfig)
cfg.read_write()
cfg.val4 == ['val10', 'val11']
- raises(SlaveError, "cfg.val1.val1")
- raises(SlaveError, "cfg.val1.val2")
- raises(SlaveError, "cfg.val1.val3")
- raises(SlaveError, "cfg.val1.val5")
- raises(SlaveError, "cfg.val1.val6")
+ assert cfg.val1.val1 == []
+ assert cfg.val1.val2 == []
+ assert cfg.val1.val3 == []
+ assert cfg.val1.val5 == []
+ assert cfg.val1.val6 == []
+ #raises(SlaveError, "cfg.val1.val1")
+ #raises(SlaveError, "cfg.val1.val2")
+ #raises(SlaveError, "cfg.val1.val3")
+ #raises(SlaveError, "cfg.val1.val5")
+ #raises(SlaveError, "cfg.val1.val6")
#
#default calculation has greater length
- raises(SlaveError, "cfg.val1.val1 = ['val1']")
+ #raises(SlaveError, "cfg.val1.val1 = ['val1']")
#
cfg.val1.val1 = ['val1', 'val2']
assert cfg.val1.val1 == ['val1', 'val2']
assert cfg.val1.val2 == ['val1', 'val2']
assert cfg.val1.val3 == ['yes', 'yes']
- assert cfg.val1.val5 == ['val10', 'val11']
- assert cfg.val1.val6 == ['val10', 'val11']
+ raises(SlaveError, "cfg.val1.val5")
+ raises(SlaveError, "cfg.val1.val6")
#
cfg.val1.val1.append('val3')
assert cfg.val1.val1 == ['val1', 'val2', 'val3']
assert cfg.val1.val2 == ['val1', 'val2', 'val3']
assert cfg.val1.val3 == ['yes', 'yes', 'yes']
- assert cfg.val1.val5 == ['val10', 'val11', None]
- assert cfg.val1.val6 == ['val10', 'val11', None]
+ raises(SlaveError, "cfg.val1.val5")
+ raises(SlaveError, "cfg.val1.val6")
#
cfg.val1.val1.pop(2)
assert cfg.val1.val1 == ['val1', 'val2']
assert cfg.val1.val2 == ['val1', 'val2']
assert cfg.val1.val3 == ['yes', 'yes']
- assert cfg.val1.val5 == ['val10', 'val11']
- assert cfg.val1.val6 == ['val10', 'val11']
+ raises(SlaveError, "cfg.val1.val5")
+ raises(SlaveError, "cfg.val1.val6")
#
cfg.val1.val2 = ['val2', 'val2']
cfg.val1.val3 = ['val2', 'val2']
cfg.val1.val1.append('val3')
assert cfg.val1.val2 == ['val2', 'val2', 'val3']
assert cfg.val1.val3 == ['val2', 'val2', 'yes']
- assert cfg.val1.val5 == ['val2', 'val2', None]
- assert cfg.val1.val6 == ['val2', 'val2', None]
+ raises(SlaveError, "cfg.val1.val5")
+ raises(SlaveError, "cfg.val1.val6")
cfg.cfgimpl_get_settings().remove('cache')
cfg.val4 = ['val10', 'val11', 'val12']
#if value is already set, not updated !
cfg.val1.val1.pop(2)
cfg.val1.val1.append('val3')
cfg.val1.val1 = ['val1', 'val2', 'val3']
- assert cfg.val1.val5 == ['val2', 'val2', 'val12']
- assert cfg.val1.val6 == ['val2', 'val2', 'val12']
-
-
-def test_callback_master_and_slaves_disabled():
- val = BoolOption('val', '', multi=True)
- val1 = StrOption('val1', "", multi=True)
- val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val, False),)})
- interface1 = OptionDescription('val1', '', [val1, val2])
- interface1.impl_set_group_type(groups.master)
- maconfig = OptionDescription('rootconfig', '', [val, interface1])
- cfg = Config(maconfig)
- cfg.read_write()
- #
- assert cfg.val == []
- assert cfg.val1.val1 == []
- assert cfg.val1.val2 == []
- cfg.val1.val1.append('val1')
- assert cfg.val == []
- assert cfg.val1.val1 == ['val1']
- assert cfg.val1.val2 == [None]
- #
- cfg.val.append(True)
- cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].append('disabled')
- assert cfg.val == [True]
- assert cfg.val1.val1 == ['val1']
- raises(PropertiesOptionError, 'cfg.val1.val2')
- #
- cfg.val1.val1.append('val1_1')
- assert cfg.val == [True]
- assert cfg.val1.val1 == ['val1', 'val1_1']
- raises(PropertiesOptionError, 'cfg.val1.val2')
- #
- cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].remove('disabled')
- assert cfg.val == [True]
- assert cfg.val1.val1 == ['val1', 'val1_1']
- raises(ValueError, 'cfg.val1.val2')
- #
- cfg.val = []
- assert cfg.val1.val1 == ['val1', 'val1_1']
- assert cfg.val1.val2 == [None, None]
- #
- cfg.val1.val2 = [None, None]
- cfg.val = [True, True]
- cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].append('disabled')
- cfg.val1.val1.pop(1)
- assert cfg.val == [True, True]
- assert cfg.val1.val1 == ['val1']
- raises(PropertiesOptionError, 'cfg.val1.val2')
- #
- cfg.val1.val1.append('val1_2')
- assert cfg.val == [True, True]
- assert cfg.val1.val1 == ['val1', 'val1_2']
- raises(PropertiesOptionError, 'cfg.val1.val2')
- #
- cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val2].remove('disabled')
- assert cfg.val == [True, True]
- assert cfg.val1.val1 == ['val1', 'val1_2']
- #[None, None] + pop() + append() => [None, True]
- raises(ValueError, 'assert cfg.val1.val2')
-
-
-def test_callback_master_and_slaves_requires():
- val = StrOption('val', '', 'val')
- valreq = StrOption('valreq', '', 'val')
- val1 = StrOption('val1', "", multi=True)
- val2 = StrOption('val2', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)})
- val3 = StrOption('val3', "", multi=True, callback=return_value, callback_params={'': ('yes',)})
- val4 = StrOption('val4', '', multi=True, default=[])
- val5 = StrOption('val5', "", multi=True, callback=return_value, callback_params={'': ((val4, False),)})
- val6 = StrOption('val6', "", multi=True, callback=return_value, callback_params={'': ((val, False),)},
- requires=({'option': valreq, 'expected': 'val_disabled', 'action': 'disabled'},))
- interface1 = OptionDescription('val1', '', [val1, val2, val3, val5, val6])
- interface1.impl_set_group_type(groups.master)
- maconfig = OptionDescription('rootconfig', '', [val, valreq, interface1, val4])
- cfg = Config(maconfig)
- cfg.read_write()
- assert cfg.val1.val1 == []
- assert cfg.val1.val2 == []
- assert cfg.val1.val3 == []
- assert cfg.val1.val5 == []
- assert cfg.val1.val6 == []
- #
- cfg.val1.val1 = ['val1']
- assert cfg.val1.val1 == ['val1']
- assert cfg.val1.val2 == ['val1']
- assert cfg.val1.val3 == ['yes']
- assert cfg.val1.val5 == [None]
- assert cfg.val1.val6 == ['val']
- cfg.val4 = ['val10']
- assert cfg.val1.val5 == ['val10']
- #
- cfg.valreq = 'val_disabled'
- assert cfg.val1.val1 == ['val1']
- assert cfg.val1.val2 == ['val1']
- assert cfg.val1.val3 == ['yes']
- assert cfg.val1.val5 == ['val10']
- raises(PropertiesOptionError, 'cfg.val1.val6')
- assert cfg.make_dict() == {'val1.val2': ['val1'], 'val1.val3': ['yes'], 'val1.val1': ['val1'], 'val1.val5': ['val10'], 'val': 'val', 'valreq': 'val_disabled', 'val4': ['val10']}
- #
- cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val].append('disabled')
- cfg.cfgimpl_get_settings()[cfg.cfgimpl_get_description().val1.val3].append('disabled')
- raises(PropertiesOptionError, 'cfg.val1.val6')
- assert cfg.make_dict() == {'val1.val2': ['val1'], 'val1.val1': ['val1'], 'val1.val5': ['val10'], 'val4': ['val10'], 'valreq': 'val_disabled'}
- #
- cfg.valreq = 'val'
- raises(ConfigError, 'cfg.val1.val6')
+ raises(SlaveError, "cfg.val1.val5")
+ raises(SlaveError, "cfg.val1.val6")
def test_callback_master():
raises(ValueError, "interface1.impl_set_group_type(groups.master)")
-def test_callback_master_and_other_master_slave():
- val1 = StrOption('val1', "", multi=True)
- val2 = StrOption('val2', "", multi=True)
- val3 = StrOption('val3', "", multi=True)
- val4 = StrOption('val4', '', multi=True, default=['val10', 'val11'])
- val5 = StrOption('val5', "", multi=True, callback=return_value, callback_params={'': ((val1, False),)})
- val6 = StrOption('val6', "", multi=True, callback=return_value, callback_params={'': ((val2, False),)})
- interface1 = OptionDescription('val1', '', [val1, val2, val3])
- interface1.impl_set_group_type(groups.master)
- interface2 = OptionDescription('val4', '', [val4, val5, val6])
- interface2.impl_set_group_type(groups.master)
- maconfig = OptionDescription('rootconfig', '', [interface1, interface2])
- cfg = Config(maconfig)
- cfg.read_write()
- assert cfg.val4.val4 == ['val10', 'val11']
- assert cfg.val4.val5 == [None, None]
- assert cfg.val4.val6 == [None, None]
- cfg.val1.val1 = ['yes']
- assert cfg.val4.val4 == ['val10', 'val11']
- assert cfg.val4.val5 == ['yes', None]
- assert cfg.val4.val6 == [None, None]
- cfg.val1.val2 = ['no']
- assert cfg.val4.val4 == ['val10', 'val11']
- assert cfg.val4.val5 == ['yes', None]
- assert cfg.val4.val6 == ['no', None]
- cfg.val1.val1 = ['yes', 'yes', 'yes']
- cfg.val1.val2 = ['no', 'no', 'no']
- raises(SlaveError, "cfg.val4.val4")
- raises(SlaveError, "cfg.val4.val5")
- raises(SlaveError, "cfg.val4.val6")
- cfg.val4.getattr('val4', validate=False).append('val12')
- assert cfg.val4.val4 == ['val10', 'val11', 'val12']
- assert cfg.val4.val5 == ['yes', 'yes', 'yes']
- assert cfg.val4.val6 == ['no', 'no', 'no']
-
-
#FIXME: slave est un symlink
cfg.ip_admin_eth0.ip_admin_eth0[0] = "192.168.230.146"
cfg.ip_admin_eth0.netmask_admin_eth0[0] = "255.255.255.0"
assert cfg.getowner(ip_admin_eth0) == owner
- assert cfg.getowner(netmask_admin_eth0) == owner
+ assert cfg.getowner(netmask_admin_eth0, 0) == owner
del(cfg.ip_admin_eth0.ip_admin_eth0)
assert cfg.getowner(ip_admin_eth0) == owners.default
- assert cfg.getowner(netmask_admin_eth0) == owners.default
+ assert cfg.getowner(netmask_admin_eth0, 0) == owners.default
assert cfg.ip_admin_eth0.ip_admin_eth0 == ['192.168.230.145']
assert cfg.ip_admin_eth0.netmask_admin_eth0 == [None]
cfg.ip_admin_eth0.netmask_admin_eth0[0] = "255.255.255.0"
assert cfg.getowner(ip_admin_eth0) == owners.default
- assert cfg.getowner(netmask_admin_eth0) == owner
+ assert cfg.getowner(netmask_admin_eth0, 0) == owner
del(cfg.ip_admin_eth0.ip_admin_eth0)
assert cfg.getowner(ip_admin_eth0) == owners.default
assert cfg.getowner(netmask_admin_eth0) == owners.default
cfg.ip_admin_eth0.ip_admin_eth0.append("192.168.230.145")
cfg.ip_admin_eth0.netmask_admin_eth0[0].append('255.255.255.0')
assert cfg.getowner(ip_admin_eth0) == owner
- assert cfg.getowner(netmask_admin_eth0) == owner
+ assert cfg.getowner(netmask_admin_eth0, 0) == owner
del(cfg.ip_admin_eth0.ip_admin_eth0)
assert cfg.getowner(ip_admin_eth0) == owners.default
- assert cfg.getowner(netmask_admin_eth0) == owners.default
+# assert cfg.getowner(netmask_admin_eth0) == owners.default
assert cfg.ip_admin_eth0.ip_admin_eth0 == []
assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
# the whole pypy projet is under MIT licence
# ____________________________________________________________
"enables us to carry out a calculation and return an option's value"
-from tiramisu.error import PropertiesOptionError, ConfigError, ContextError
+from tiramisu.error import PropertiesOptionError, ConfigError, ContextError, \
+ SlaveError
from tiramisu.i18n import _
from tiramisu.setting import undefined
# ____________________________________________________________
ret = calculate(callback, args, kwargs)
if callback_params != {}:
if isinstance(ret, list) and index is not undefined:
+ if option.impl_is_master_slaves('slave'):
+ raise SlaveError(_("callback cannot return a list for a "
+ "slave option ({0})").format(path))
if len(ret) < index + 1:
ret = None
else:
"read write is a global config's setting, see `settings.py`"
self.cfgimpl_get_settings().read_write()
- def getowner(self, opt, force_permissive=False):
+ def getowner(self, opt, index=None, force_permissive=False):
"""convenience method to retrieve an option's owner
from the config itself
"""
not isinstance(opt, DynSymLinkOption): # pragma: optional cover
raise TypeError(_('opt in getowner must be an option not {0}'
'').format(type(opt)))
- return self.cfgimpl_get_values().getowner(opt,
+ return self.cfgimpl_get_values().getowner(opt, index=index,
force_permissive=force_permissive)
def unwrap_from_path(self, path, force_permissive=False):
fake_config = Config(self._impl_descr, persistent=False,
force_values=get_storages_validation(),
force_settings=self.cfgimpl_get_settings())
- fake_config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_.get_modified_values()
+ fake_config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_._values
return fake_config
def duplicate(self):
config = Config(self._impl_descr)
- config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_.get_modified_values()
+ config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_._values
config.cfgimpl_get_settings()._p_._properties = self.cfgimpl_get_settings()._p_.get_modified_properties()
config.cfgimpl_get_settings()._p_._permissives = self.cfgimpl_get_settings()._p_.get_modified_permissives()
return config
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, multi=False, callback=None,
callback_params=None, validator=None, validator_params=None,
- properties=None, warnings_only=False, extra=None, allow_empty_list=undefined):
+ properties=None, warnings_only=False, extra=None,
+ allow_empty_list=undefined):
if not valid_name(name): # pragma: optional cover
raise ValueError(_("invalid name: {0} for option").format(name))
if requires is not None:
calc_properties = frozenset()
requires = undefined
if not multi and default_multi is not None: # pragma: optional cover
- raise ValueError(_("a default_multi is set whereas multi is False"
+ raise ValueError(_("default_multi is set whereas multi is False"
" in option: {0}").format(name))
if multi is True:
_multi = 0
'requirement {0}'.format(
list(set_forbidden_properties)))
StorageBase.__init__(self, name, _multi, warnings_only, doc, extra,
- calc_properties, requires, properties, allow_empty_list)
+ calc_properties, requires, properties,
+ allow_empty_list)
if multi is not False and default is None:
default = []
self.impl_validate(default)
if child.impl_getname() == name:
self.master = child
else:
+ if child.impl_getdefault() != []:
+ raise ValueError(_("not allowed default value for option {0} "
+ "in group {1}").format(child.impl_getname(),
+ name))
slaves.append(child)
if self.master is None: # pragma: optional cover
raise ValueError(_('master group with wrong'
def pop(self, opt, values, index):
for slave in self.getslaves(opt):
if not values.is_default_owner(slave, validate_properties=False,
- validate_meta=False):
+ validate_meta=False, index=index):
values._get_cached_item(slave, validate=False,
validate_properties=False
).pop(index, force=True)
for slave in self.getslaves(opt):
try:
slave_path = slave.impl_getpath(values._getcontext())
- if c_slave_path == slave_path:
- slave_value = c_slave_value
- else:
- slave_value = values._get_validated_value(slave,
- slave_path,
- False,
- False,
- None, False,
- None,
- self_properties=self_properties)
- slavelen = len(slave_value)
+ slavelen = values._p_.get_max_length(slave_path)
+ #if c_slave_path == slave_path:
+ # slave_value = c_slave_value
+ #else:
+ # slave_value = values._get_validated_value(slave,
+ # slave_path,
+ # False,
+ # False,
+ # None, False,
+ # None,
+ # self_properties=self_properties,
+ # masterlen=masterlen)
+ #slavelen = len(slave_value)
self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
except ConfigError: # pragma: optional cover
pass
undefined, force_permissive,
master=master)
master_is_meta = values._is_meta(opt, masterp)
- value = values._get_validated_value(opt, path, validate,
- force_permissive,
- force_properties,
- validate_properties,
- None, # not undefined
- with_meta=master_is_meta,
- self_properties=self_properties)
+ #value = values._get_validated_value(opt, path, validate,
+ # force_permissive,
+ # force_properties,
+ # validate_properties,
+ # None, # not undefined
+ # with_meta=master_is_meta,
+ # self_properties=self_properties)
#if slave, had values until master's one
- path = opt.impl_getpath(context)
- valuelen = len(value)
- if validate:
- self.validate_slave_length(masterlen, valuelen,
- opt.impl_getname(), opt)
- if valuelen < masterlen:
- for num in range(0, masterlen - valuelen):
- index = valuelen + num
- value.append(values._get_validated_value(opt, path, True,
- False, None,
- validate_properties=False,
- with_meta=master_is_meta,
- index=index,
- self_properties=self_properties),
- setitem=False,
- force=True,
- validate=validate)
- if validate_properties:
- context.cfgimpl_get_settings().validate_properties(opt, False,
- False,
- value=value,
- path=path,
- force_permissive=force_permissive,
- force_properties=force_properties,
- setting_properties=setting_properties)
+ #path = opt.impl_getpath(context)
+ #valuelen = len(value)
+ #if validate:
+ # self.validate_slave_length(masterlen, valuelen,
+ # opt.impl_getname(), opt)
+ #if valuelen < masterlen:
+
+ #FIXME voir si pas de plus grande valeur !
+ value = values._get_multi(opt, path)
+ for index in range(0, masterlen):
+ #index = valuelen + num
+ value.append(values._get_validated_value(opt, path, validate,
+ force_permissive, force_properties,
+ validate_properties,
+ with_meta=master_is_meta,
+ index=index,
+ self_properties=self_properties,
+ masterlen=masterlen),
+ setitem=False,
+ force=True,
+ validate=validate)
+ #FIXME hu?
+ if validate_properties:
+ context.cfgimpl_get_settings().validate_properties(opt, False,
+ False,
+ value=value,
+ path=path,
+ force_permissive=force_permissive,
+ force_properties=force_properties,
+ setting_properties=setting_properties)
return value
def setitem(self, values, opt, value, path):
base_path = '.'.join(path.split('.')[:-1]) + '.'
for slave in self.getslaves(opt):
slave_path = base_path + slave.impl_getname()
- slave_value = values._get_validated_value(slave,
- slave_path,
- False,
- False,
- None, False,
- None) # not undefined
- slavelen = len(slave_value)
+ slavelen = values._p_.get_max_length(slave_path)
self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
+ #slave_value = values._get_validated_value(slave,
+ # slave_path,
+ # False,
+ # False,
+ # None, False,
+ # None,
+ # masterlen=masterlen) # not undefined
+ #slavelen = len(slave_value)
+ #self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
else:
self.validate_slave_length(self.get_length(values, opt,
slave_path=path), len(value),
value=None, force_permissive=False,
force_properties=None,
setting_properties=undefined,
- self_properties=undefined):
+ self_properties=undefined,
+ index=None):
"""
validation upon the properties related to `opt_or_descr`
else:
if 'mandatory' in properties and \
not self._getcontext().cfgimpl_get_values()._isempty(
- opt_or_descr, value):
+ opt_or_descr, value, index=index):
properties.remove('mandatory')
elif opt_or_descr.impl_is_multi() and \
not is_write and 'empty' in forced_properties and \
'_master_slaves',
'_choice_values',
'_choice_values_params',
- #autre
+ #other
'_state_master_slaves',
'_state_callback',
'_state_callback_params',
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
-from copy import copy
from ..util import Cache
+from tiramisu.setting import undefined
class Values(Cache):
def __init__(self, storage):
"""init plugin means create values storage
"""
- self._values = {}
+ self._values = (tuple(), tuple(), tuple(), tuple())
self._informations = {}
# should init cache too
super(Values, self).__init__(storage)
# value
- def setvalue(self, path, value, owner):
+ def setvalue(self, path, value, owner, index):
"""set value for a path
a specified value must be associated to an owner
"""
- self._values[path] = (owner, value)
+ values = []
+ vidx = None
- def getvalue(self, path):
+ def _setvalue_info(nb, idx, value, vidx):
+ lst = list(self._values[nb])
+ if idx is None:
+ if index is None or nb == 0:
+ lst.append(value)
+ else:
+ lst.append([value])
+ else:
+ if index is None or nb == 0:
+ lst[idx] = value
+ else:
+ if nb == 1:
+ try:
+ vidx = lst[idx].index(index)
+ except ValueError:
+ vidx = None
+ if vidx is None:
+ lst[idx].append(value)
+ elif nb != 1:
+ lst[idx][vidx] = value
+ values.append(tuple(lst))
+ return vidx
+ try:
+ idx = self._values[0].index(path)
+ except ValueError:
+ idx = None
+ vidx = _setvalue_info(0, idx, path, vidx)
+ vidx = _setvalue_info(1, idx, index, vidx)
+ vidx = _setvalue_info(2, idx, value, vidx)
+ _setvalue_info(3, idx, owner, vidx)
+ self._values = tuple(values)
+
+ def getvalue(self, path, index=None):
"""get value for a path
return: only value, not the owner
"""
- return self._values[path][1]
+ return self._getvalue(path, 2, index)
- def hasvalue(self, path):
+ def hasvalue(self, path, index=None):
"""if path has a value
return: boolean
"""
- return path in self._values
+ return path in self._values[0]
def resetvalue(self, path):
"""remove value means delete value in storage
"""
- del(self._values[path])
+ def _resetvalue(nb):
+ lst = list(self._values[nb])
+ lst.pop(idx)
+ values.append(tuple(lst))
+ values = []
+ idx = self._values[0].index(path)
+ _resetvalue(0)
+ _resetvalue(1)
+ _resetvalue(2)
+ _resetvalue(3)
+ self._values = tuple(values)
def get_modified_values(self):
"""return all values in a dictionary
example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
"""
- return copy(self._values)
+ values = {}
+ for idx, path in enumerate(self._values[0]):
+ values[path] = (self._values[3][idx], self._values[2][idx])
+ return values
# owner
- def setowner(self, path, owner):
+ def setowner(self, path, owner, index=None):
"""change owner for a path
"""
- self._values[path] = (owner, self._values[path][1])
+ idx = self._values[0].index(path)
+ if isinstance(self._values[3][idx], list):
+ if index is None:
+ raise ValueError('list but no index')
+ owner = list(self._values[3][idx])[index] = owner
+ elif index is not None:
+ raise ValueError('index set but not a list')
+ lst = list(self._values[3])
+ lst[idx] = owner
+ values = list(self._values)
+ values[3] = tuple(lst)
+ self._values = tuple(values)
+
+ def get_max_length(self, path):
+ try:
+ idx = self._values[0].index(path)
+ except ValueError:
+ return 0
+ return max(self._values[1][idx]) + 1
- def getowner(self, path, default):
+ def getowner(self, path, default, index=None, only_default=False):
"""get owner for a path
return: owner object
"""
- return self._values.get(path, (default, None))[0]
+ if index is None:
+ if only_default:
+ if path in self._values[0]:
+ return None
+ else:
+ return default
+ val = self._getvalue(path, 3, index)
+ if val is None:
+ return default
+ return val
+ else:
+ value = self._getvalue(path, 3, index)
+ if value is None:
+ return default
+ else:
+ return value
+
+ def _getvalue(self, path, nb, index):
+ """
+ _values == ((path1, path2), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2), ((idx1_1, idx1_2), None))
+ """
+ try:
+ idx = self._values[0].index(path)
+ except ValueError:
+ value = None
+ else:
+ if isinstance(self._values[1][idx], list):
+ if index is None:
+ raise ValueError('list but no index')
+ elif index is not None:
+ raise ValueError('index set but not a list')
+
+ if self._values[1][idx] is None:
+ if index is None:
+ value = self._values[nb][idx]
+ else:
+ value = self._values[nb][idx][index]
+ else:
+ if index is not None:
+ try:
+ subidx = self._values[1][idx].index(index)
+ value = self._values[nb][idx][subidx]
+ except ValueError:
+ value = None
+ else:
+ value = []
+ for i in xrange(0, max(self._values[1][idx])):
+ if i in self._values[1][idx]:
+ value.append(self._values[nb][idx][self._values[1][idx].index(i)])
+ else:
+ value.append(undefined)
+ return value
def set_information(self, key, value):
"""updates the information's attribute
value = getattr(self, slot)
#value has owners object, need 'str()' it
if slot == '_values':
- _value = {}
- for key, values in value.items():
- vals = list(values)
- vals[0] = str(vals[0])
- _value[key] = tuple(vals)
+ _value = []
+ _value.append(value[0])
+ _value.append(value[1])
+ str_owner = []
+ _value.append(value[2])
+ for owner in value[3]:
+ if isinstance(owner, list):
+ str_owners = []
+ for subowner in owner:
+ str_owners.append(str(subowner))
+ str_owner.append(str_owners)
+ else:
+ str_owner.append(str(owner))
+ _value.append(str_owner)
states[slot] = _value
else:
states[slot] = value
return states
def __setstate__(self, states):
+ def convert_owner(owner):
+ try:
+ owner = getattr(owners, owner)
+ except AttributeError:
+ owners.addowner(owner)
+ owner = getattr(owners, owner)
+ return owner
+
for key, value in states.items():
#value has owners object, need to reconstruct it
if key == '_values':
- _value = {}
- for key_, values_ in value.items():
- vals = list(values_)
- try:
- vals[0] = getattr(owners, vals[0])
- except AttributeError:
- owners.addowner(vals[0])
- vals[0] = getattr(owners, vals[0])
- _value[key_] = tuple(vals)
- value = _value
+ _value = []
+ _value.append(value[0])
+ _value.append(value[1])
+ _value.append(value[2])
+ obj_owner = []
+ for owner in value[3]:
+ if isinstance(owner, list):
+ obj_owners = []
+ for subowner in owner:
+ obj_owners.append(convert_owner(subowner))
+ obj_owner.append(tuple(obj_owners))
+ else:
+ obj_owner.append(convert_owner(owner))
+ _value.append(tuple(obj_owner))
+ value = tuple(_value)
setattr(self, key, value)
def setcache(self, path, val, time):
raise ConfigError(_('the context does not exist anymore'))
return context
- def _getvalue(self, opt, path, is_default, index=undefined,
- with_meta=True, self_properties=undefined):
- """actually retrieves the value
-
- :param opt: the `option.Option()` object
- :returns: the option's value (or the default value if not set)
- """
- if opt.impl_is_optiondescription(): # pragma: optional cover
- raise ValueError(_('optiondescription has no value'))
+ def _get_multi(self, opt, path):
+ return Multi([], self.context, opt, path)
- if self_properties is undefined:
- self_properties = self._getcontext().cfgimpl_get_settings()._getproperties(
- opt, path, read_write=False)
- force_default = 'frozen' in self_properties and \
- 'force_default_on_freeze' in self_properties
- if not is_default and not force_default:
- value = self._p_.getvalue(path)
- if index is not undefined:
- try:
- return value[index]
- except IndexError:
- #value is smaller than expected
- #so return default value
- pass
- else:
- return value
- #so default value
+ def _getdefaultvalue(self, opt, path, with_meta, index):
# if value has callback and is not set
if opt.impl_has_callback():
callback, callback_params = opt.impl_get_callback()
value = opt.impl_getdefault_multi()
return value
+ def _getvalue(self, opt, path, is_default, index=undefined,
+ with_meta=True, self_properties=undefined,
+ masterlen=undefined):
+ """actually retrieves the value
+
+ :param opt: the `option.Option()` object
+ :returns: the option's value (or the default value if not set)
+ """
+ if opt.impl_is_optiondescription(): # pragma: optional cover
+ raise ValueError(_('optiondescription has no value'))
+
+ if self_properties is undefined:
+ self_properties = self._getcontext().cfgimpl_get_settings()._getproperties(
+ opt, path, read_write=False)
+ force_default = 'frozen' in self_properties and \
+ 'force_default_on_freeze' in self_properties
+ if not is_default and not force_default:
+ if opt.impl_is_master_slaves('slave'):
+ #if masterlen is not undefined:
+ if index is undefined:
+ value = []
+ vals = self._p_.getvalue(path)
+ length = max(masterlen, len(vals))
+ for idx in xrange(0, length):
+ try:
+ if vals[idx] is undefined:
+ value.append(self._getdefaultvalue(opt, path, with_meta, idx))
+ else:
+ value.append(vals[idx])
+ except IndexError:
+ try:
+ value.append(self._getdefaultvalue(opt, path, with_meta, idx))
+ except IndexError:
+ value.append(None)
+ else:
+ value = self._p_.getvalue(path, index)
+ return value
+ else:
+ value = self._p_.getvalue(path)
+ if index is not undefined:
+ try:
+ return value[index]
+ except IndexError:
+ #value is smaller than expected
+ #so return default value
+ pass
+ else:
+ return value
+ return self._getdefaultvalue(opt, path, with_meta, index)
+
def get_modified_values(self):
context = self._getcontext()
if context._impl_descr is not None:
if hasvalue:
self._p_.resetvalue(path)
- def _isempty(self, opt, value, force_allow_empty_list=False):
+ def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
"convenience method to know if an option is empty"
if value is undefined:
return False
else:
empty = opt._empty
- if opt.impl_is_multi():
+ if index in [None, undefined] and opt.impl_is_multi():
if force_allow_empty_list:
allow_empty_list = True
else:
force_properties, validate_properties,
index=undefined, submulti_index=undefined,
with_meta=True, setting_properties=undefined,
- self_properties=undefined):
+ self_properties=undefined, masterlen=undefined):
"""same has getitem but don't touch the cache
index is None for slave value, if value returned is not a list, just return []
"""
is_default = self._is_default_owner(opt, path,
validate_properties=False,
validate_meta=False,
- self_properties=self_properties)
+ self_properties=self_properties,
+ index=index)
try:
if index is None:
gv_index = undefined
gv_index = index
value = self._getvalue(opt, path, is_default, index=gv_index,
with_meta=with_meta,
- self_properties=self_properties)
+ self_properties=self_properties,
+ masterlen=masterlen)
config_error = None
except ConfigError as err:
# For calculating properties, we need value (ie for mandatory
# value is not set, for 'undefined' (cannot set None because of
# mandatory property)
value = undefined
-
- if config_error is None:
+ else:
if index is undefined:
force_index = None
else:
force_permissive=force_permissive,
force_properties=force_properties,
setting_properties=setting_properties,
- self_properties=self_properties)
+ self_properties=self_properties,
+ index=index)
if config_error is not None:
raise config_error
return value
def _setvalue(self, opt, path, value, force_permissive=False,
is_write=True, validate_properties=True,
- setting_properties=undefined):
+ setting_properties=undefined, index=None):
context = self._getcontext()
context.cfgimpl_reset_cache()
if validate_properties:
if isinstance(val, SubMulti):
value[idx] = list(val)
owner = context.cfgimpl_get_settings().getowner()
- self._p_.setvalue(path, value, owner)
+ if opt.impl_is_master_slaves('slave') and index is None:
+ try:
+ self._p_.resetvalue(path)
+ except ValueError:
+ pass
+ for idx, val in enumerate(value):
+ self._p_.setvalue(path, val, owner, idx)
+ else:
+ self._p_.setvalue(path, value, owner, index)
def _is_meta(self, opt, path):
context = self._getcontext()
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) is not owners.default:
+ if self._p_.getowner(path, owners.default, only_default=True) is not owners.default:
return False
if context.cfgimpl_get_meta() is not None:
return True
return False
- def getowner(self, opt, force_permissive=False):
+ def getowner(self, opt, index=None, force_permissive=False):
"""
retrieves the option's owner
not isinstance(opt, DynSymLinkOption):
opt = opt._impl_getopt()
path = opt.impl_getpath(self._getcontext())
- return self._getowner(opt, path, force_permissive=force_permissive)
+ return self._getowner(opt, path, index=index, force_permissive=force_permissive)
def _getowner(self, opt, path, validate_properties=True,
force_permissive=False, validate_meta=undefined,
- self_properties=undefined):
+ self_properties=undefined, only_default=False,
+ index=None):
"""get owner of an option
"""
if not isinstance(opt, Option) and not isinstance(opt,
if validate_properties:
self._getitem(opt, path, True, force_permissive, None, True,
self_properties=self_properties)
- owner = self._p_.getowner(path, owners.default)
+ owner = self._p_.getowner(path, owners.default, only_default=only_default, index=index)
if validate_meta is undefined:
if opt.impl_is_master_slaves('slave'):
master = opt.impl_get_master_slaves().getmaster(opt)
if validate_meta:
meta = context.cfgimpl_get_meta()
if owner is owners.default and meta is not None:
- owner = meta.cfgimpl_get_values()._getowner(opt, path)
+ owner = meta.cfgimpl_get_values()._getowner(opt, path,
+ validate_properties=validate_properties,
+ force_permissive=force_permissive,
+ self_properties=self_properties,
+ only_default=only_default, index=index)
return owner
def setowner(self, opt, owner):
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
path = opt.impl_getpath(self._getcontext())
- self._setowner(opt, path, owner)
-
- def _setowner(self, opt, path, owner):
if not self._p_.hasvalue(path): # pragma: optional cover
raise ConfigError(_('no value for {0} cannot change owner to {1}'
'').format(path, owner))
self._p_.setowner(path, owner)
def is_default_owner(self, opt, validate_properties=True,
- validate_meta=True):
+ validate_meta=True, index=None):
"""
:param config: *must* be only the **parent** config
(not the toplevel config)
path = opt.impl_getpath(self._getcontext())
return self._is_default_owner(opt, path,
validate_properties=validate_properties,
- validate_meta=validate_meta)
+ validate_meta=validate_meta, index=index)
def _is_default_owner(self, opt, path, validate_properties=True,
- validate_meta=True, self_properties=undefined):
- return self._getowner(opt, path, validate_properties,
- validate_meta=validate_meta,
- self_properties=self_properties) == \
- owners.default
+ validate_meta=True, self_properties=undefined,
+ index=None):
+ if not opt.impl_is_master_slaves('slave'):
+ index = None
+ d = self._getowner(opt, path, validate_properties,
+ validate_meta=validate_meta,
+ self_properties=self_properties, only_default=True,
+ index=index)
+ return d == owners.default
def reset_cache(self, only_expired):
"""
# ____________________________________________________________
# multi types
-
class Multi(list):
"""multi options values container
that support item notation for the values of multi options"""
self._validate(value, fake_context, index, True)
#assume not checking mandatory property
super(Multi, self).__setitem__(index, value)
- context.cfgimpl_get_values()._setvalue(self.opt, self.path, self, setting_properties=setting_properties)
+ self._store()
#def __repr__(self, *args, **kwargs):
# return super(Multi, self).__repr__(*args, **kwargs)
value.submulti = weakref.ref(self)
super(Multi, self).append(value)
if setitem:
- self._store(force)
+ self._store(force=force)
def sort(self, cmp=None, key=None, reverse=False):
if self.opt.impl_is_master_slaves():
self._store()
def insert(self, index, value, validate=True):
- #FIXME value should be undefined
if self.opt.impl_is_master_slaves():
raise SlaveError(_("cannot insert multi option {0} if master or "
"slave").format(self.opt.impl_getname()))
context.cfgimpl_get_values(), index)
#set value without valid properties
ret = super(Multi, self).pop(index)
- self._store(force)
+ self._store(force=force)
return ret
def _store(self, force=False):