use python-coverage to delete dead part of code

This commit is contained in:
Emmanuel Garette 2015-11-24 10:58:19 +01:00
parent 54ca54e505
commit ab555966f7
16 changed files with 409 additions and 269 deletions

View File

@ -5,6 +5,7 @@ do_autopath()
from tiramisu.setting import owners from tiramisu.setting import owners
from tiramisu.option import ChoiceOption, StrOption, OptionDescription from tiramisu.option import ChoiceOption, StrOption, OptionDescription
from tiramisu.config import Config from tiramisu.config import Config
from tiramisu.error import ConfigError
from py.test import raises from py.test import raises
@ -86,3 +87,18 @@ def test_choiceoption_calc_opt_multi_function():
assert cfg.getowner(ch) == owners.default assert cfg.getowner(ch) == owners.default
# #
raises(ValueError, "cfg.ch2") raises(ValueError, "cfg.ch2")
def test_choiceoption_calc_invalid():
st = StrOption('st', '', ['val1'], multi=True)
st
raises(ValueError, "ch = ChoiceOption('ch', '', default_multi='val2', values=[1, 2, 3], values_params={'': ((st, False),)}, multi=True)")
def test_choiceoption_calc_not_list():
st = StrOption('st', '', 'val1')
ch = ChoiceOption('ch', "", default_multi='val2', values=return_val, values_params={'': ((st, False),)}, multi=True)
od = OptionDescription('od', '', [st, ch])
cfg = Config(od)
cfg.read_write()
raises(ConfigError, "cfg.ch = ['val1']")

View File

@ -49,6 +49,14 @@ def test_base_config():
assert dm.impl_getname() == 'dummy' assert dm.impl_getname() == 'dummy'
def test_base_config_name():
gcdummy = BoolOption('dummy', 'dummy', default=False)
descr = OptionDescription('tiramisu', '', [gcdummy])
cfg = Config(descr, name='cfg')
cfg.impl_getname() == 'cfg'
raises(ValueError, "Config(descr, name='unvalid name')")
def test_not_config(): def test_not_config():
assert raises(TypeError, "Config('str')") assert raises(TypeError, "Config('str')")
@ -324,6 +332,15 @@ def test_delete_config_with_subconfig():
raises(ConfigError, 'sub.make_dict()') raises(ConfigError, 'sub.make_dict()')
def test_subconfig():
i = IntOption('i', '')
o = OptionDescription('val', '', [i])
o2 = OptionDescription('val', '', [o])
c = Config(o2)
raises(TypeError, "SubConfig(i, weakref.ref(c))")
pass
def test_config_weakref(): def test_config_weakref():
o = OptionDescription('val', '', []) o = OptionDescription('val', '', [])
o2 = OptionDescription('val', '', [o]) o2 = OptionDescription('val', '', [o])

View File

@ -85,7 +85,7 @@ def test_domainname_warning():
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean'") raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamean'")
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd' c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nd'
c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie' c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie'
raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainnamea.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnameto.olongthathavemorethanmaximumsizeforatruedomainnameanditsnoteas.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowien'") raises(ValueError, "c.f = 'domainnametoolongthathavemorethanmaximumsizeforatruedomainname.nditsnoteasytogeneratesolongdomainnamewithoutrepeatdomainnamet.olongthathavemorethanmaximumsizeforatruedomainnameanditsnotea.ytogeneratesolongdomainnamewithoutrepeatbutimnotabletodoitnowie.xxxx'")
c.f = 'd' c.f = 'd'
c.f = 'd.t' c.f = 'd.t'
# #

View File

@ -1,16 +1,20 @@
from autopath import do_autopath from autopath import do_autopath
do_autopath() do_autopath()
import warnings
from py.test import raises from py.test import raises
from tiramisu.config import Config from tiramisu.config import Config
from tiramisu.option import IPOption, NetworkOption, NetmaskOption, \ from tiramisu.option import IPOption, NetworkOption, NetmaskOption, \
PortOption, OptionDescription PortOption, OptionDescription
from tiramisu.error import ValueWarning
def test_ip(): def test_ip():
a = IPOption('a', '') a = IPOption('a', '')
b = IPOption('b', '', private_only=True) b = IPOption('b', '', private_only=True)
od = OptionDescription('od', '', [a, b]) d = IPOption('d', '', warnings_only=True, private_only=True)
warnings.simplefilter("always", ValueWarning)
od = OptionDescription('od', '', [a, b, d])
c = Config(od) c = Config(od)
c.a = '192.168.1.1' c.a = '192.168.1.1'
c.a = '192.168.1.0' c.a = '192.168.1.0'
@ -24,10 +28,9 @@ def test_ip():
raises(ValueError, "c.b = '255.255.255.0'") raises(ValueError, "c.b = '255.255.255.0'")
raises(ValueError, "IPOption('a', 'ip', default='192.000.023.01')") raises(ValueError, "IPOption('a', 'ip', default='192.000.023.01')")
d = IPOption('a', 'ip', default='192.0.23.1') with warnings.catch_warnings(record=True) as w:
od = OptionDescription('od', '', [d]) c.d = '88.88.88.88'
c = Config(od) assert len(w) == 1
raises(ValueError, "c.a = '192.000.023.01'")
def test_ip_default(): def test_ip_default():
@ -40,21 +43,31 @@ def test_ip_default():
def test_ip_reserved(): def test_ip_reserved():
a = IPOption('a', '') a = IPOption('a', '')
b = IPOption('b', '', allow_reserved=True) b = IPOption('b', '', allow_reserved=True)
od = OptionDescription('od', '', [a, b]) c = IPOption('c', '', warnings_only=True)
c = Config(od) od = OptionDescription('od', '', [a, b, c])
raises(ValueError, "c.a = '226.94.1.1'") warnings.simplefilter("always", ValueWarning)
c.b = '226.94.1.1' cfg = Config(od)
raises(ValueError, "cfg.a = '226.94.1.1'")
cfg.b = '226.94.1.1'
with warnings.catch_warnings(record=True) as w:
cfg.c = '226.94.1.1'
assert len(w) == 1
def test_network(): def test_network():
a = NetworkOption('a', '') a = NetworkOption('a', '')
od = OptionDescription('od', '', [a]) b = NetworkOption('b', '', warnings_only=True)
od = OptionDescription('od', '', [a, b])
warnings.simplefilter("always", ValueWarning)
c = Config(od) c = Config(od)
c.a = '192.168.1.1' c.a = '192.168.1.1'
c.a = '192.168.1.0' c.a = '192.168.1.0'
c.a = '88.88.88.88' c.a = '88.88.88.88'
c.a = '0.0.0.0' c.a = '0.0.0.0'
raises(ValueError, "c.a = '255.255.255.0'") raises(ValueError, "c.a = '255.255.255.0'")
with warnings.catch_warnings(record=True) as w:
c.b = '255.255.255.0'
assert len(w) == 1
def test_netmask(): def test_netmask():

View File

@ -707,6 +707,88 @@ def test_consistency_dyndescription():
raises(ValueError, "cfg.od.dodval2.stval2 = 'yes'") raises(ValueError, "cfg.od.dodval2.stval2 = 'yes'")
def test_consistency_dyndescription_default():
st = StrOption('st', '', 'yes')
st2 = StrOption('st2', '')
dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
od = OptionDescription('od', '', [dod])
st.impl_add_consistency('not_equal', st2)
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg
raises(ValueError, "cfg.od.dodval1.st2val1 = 'yes'")
raises(ValueError, "cfg.od.dodval2.st2val2 = 'yes'")
def test_consistency_dyndescription_multi():
st = StrOption('st', '', multi=True)
st2 = StrOption('st2', '', multi=True)
dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
od = OptionDescription('od', '', [dod])
st.impl_add_consistency('not_equal', st2)
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg.od.dodval1.stval1.append('yes')
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
cfg.od.dodval2.stval2.append('yes')
raises(ValueError, "cfg.od.dodval2.st2val2.append('yes')")
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
del(cfg.od.dodval2.stval2)
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
cfg.od.dodval2.st2val2.append('yes')
raises(ValueError, "cfg.od.dodval2.stval2.append('yes')")
def test_consistency_dyndescription_default_multi():
st = StrOption('st', '', ['yes'], multi=True)
st2 = StrOption('st2', '', multi=True)
dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
od = OptionDescription('od', '', [dod])
st.impl_add_consistency('not_equal', st2)
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
raises(ValueError, "cfg.od.dodval1.st2val1.append('yes')")
cfg.od.dodval1.stval1.append('yes')
def test_consistency_dyndescription_default_multi2():
st = StrOption('st', '', ['yes'], multi=True)
st2 = StrOption('st2', '', ['yes'], multi=True)
dod = DynOptionDescription('dod', '', [st, st2], callback=return_list)
dod
raises(ValueError, "st.impl_add_consistency('not_equal', st2)")
def test_consistency_only_one_dyndescription():
st = StrOption('st', '')
st
st2 = StrOption('st2', '')
DynOptionDescription('dod', '', [st2], callback=return_list)
raises(ConfigError, "st.impl_add_consistency('not_equal', st2)")
raises(ConfigError, "st2.impl_add_consistency('not_equal', st)")
def test_consistency_became_dyndescription():
st = StrOption('st', '')
st2 = StrOption('st2', '')
st2.impl_add_consistency('not_equal', st)
od = DynOptionDescription('dod', '', [st2], callback=return_list)
od2 = OptionDescription('od', '', [od, st])
od2
raises(ConfigError, "c = Config(od2)")
def test_consistency_became_dyndescription2():
st = StrOption('st', '')
st2 = StrOption('st2', '')
st.impl_add_consistency('not_equal', st2)
od = DynOptionDescription('dod', '', [st2], callback=return_list)
od2 = OptionDescription('od', '', [od, st])
od2
raises(ConfigError, "c = Config(od2)")
def test_consistency_external_dyndescription(): def test_consistency_external_dyndescription():
st = StrOption('st', '') st = StrOption('st', '')
st1 = StrOption('st1', '') st1 = StrOption('st1', '')

View File

@ -24,7 +24,7 @@ def make_description():
conf2 = Config(od2, name='conf2') conf2 = Config(od2, name='conf2')
conf1.read_write() conf1.read_write()
conf2.read_write() conf2.read_write()
meta = MetaConfig([conf1, conf2]) meta = MetaConfig([conf1, conf2], name='meta')
meta.cfgimpl_get_settings().setowner(owners.meta) meta.cfgimpl_get_settings().setowner(owners.meta)
return meta return meta
@ -168,6 +168,9 @@ def test_meta_meta_set():
raises(AttributeError, "meta2.find_firsts(byname='i1', byvalue=10)") raises(AttributeError, "meta2.find_firsts(byname='i1', byvalue=10)")
raises(AttributeError, "meta2.find_firsts(byname='not', byvalue=10)") raises(AttributeError, "meta2.find_firsts(byname='not', byvalue=10)")
raises(AttributeError, "meta2.find_firsts(byname='i6')") raises(AttributeError, "meta2.find_firsts(byname='i6')")
raises(ValueError, "meta2.set_value('od1.i6', 7, only_config=True, force_default=True)")
raises(ValueError, "meta2.set_value('od1.i6', 7, only_config=True, force_default_if_same=True)")
raises(ValueError, "meta2.set_value('od1.i6', 7, only_config=True, force_dont_change_value=True)")
def test_not_meta(): def test_not_meta():
@ -200,6 +203,21 @@ def test_group_find_firsts():
assert [conf1, conf2] == grp.find_firsts(byname='i1').cfgimpl_get_children() assert [conf1, conf2] == grp.find_firsts(byname='i1').cfgimpl_get_children()
def test_group_group():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
conf1 = Config(od2, name='conf1')
conf2 = Config(od2, name='conf2')
grp = GroupConfig([conf1, conf2])
raises(ValueError, "GroupConfig([grp])")
grp = GroupConfig([conf1, conf2], 'grp')
grp2 = GroupConfig([grp])
grp2.set_value('od1.i1', 2)
assert grp2.grp.conf1.od1.i1 == 2
assert grp2.grp.conf1.getowner(i1) == owners.user
def test_meta_path(): def test_meta_path():
meta = make_description() meta = make_description()
assert meta._impl_path is None assert meta._impl_path is None

View File

@ -869,3 +869,10 @@ def test_masterslaves_callback_description():
assert cfg.od.st.st1.st1 == ['yes'] assert cfg.od.st.st1.st1 == ['yes']
assert cfg.od.st.st1.st2 == ['yes'] assert cfg.od.st.st1.st2 == ['yes']
assert cfg.getowner(st1) == owner assert cfg.getowner(st1) == owner
def test_re_set_callback():
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True)
st2.impl_set_callback(return_value, {'': ((st1, False),)})
raises(ConfigError, "st2.impl_set_callback(return_value, {'': ((st1, False),)})")

View File

@ -6,7 +6,7 @@ from py.test import raises
from tiramisu.setting import owners, groups from tiramisu.setting import owners, groups
from tiramisu.config import Config from tiramisu.config import Config
from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\ from tiramisu.option import IPOption, NetworkOption, NetmaskOption, IntOption,\
BroadcastOption, SymLinkOption, OptionDescription BroadcastOption, SymLinkOption, OptionDescription, submulti
from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError
import warnings import warnings
@ -14,7 +14,6 @@ import warnings
def test_consistency(): def test_consistency():
a = IntOption('a', '') a = IntOption('a', '')
b = IntOption('b', '') b = IntOption('b', '')
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b) a.impl_add_consistency('not_equal', b)
#consistency to itself #consistency to itself
raises(ConfigError, "a.impl_add_consistency('not_equal', a)") raises(ConfigError, "a.impl_add_consistency('not_equal', a)")
@ -25,17 +24,26 @@ def test_consistency():
def test_consistency_not_exists(): def test_consistency_not_exists():
a = IntOption('a', '') a = IntOption('a', '')
b = IntOption('b', '') b = IntOption('b', '')
od = OptionDescription('od', '', [a, b]) a, b
raises(ConfigError, "a.impl_add_consistency('not_exists', b)") raises(ConfigError, "a.impl_add_consistency('not_exists', b)")
def test_consistency_unknown_params(): def test_consistency_unknown_params():
a = IntOption('a', '') a = IntOption('a', '')
b = IntOption('b', '') b = IntOption('b', '')
od = OptionDescription('od', '', [a, b]) a, b
raises(ValueError, "a.impl_add_consistency('not_equal', b, unknown=False)") raises(ValueError, "a.impl_add_consistency('not_equal', b, unknown=False)")
def test_consistency_warnings_only_default():
a = IntOption('a', '', 1)
b = IntOption('b', '', 1)
warnings.simplefilter("always", ValueWarning)
with warnings.catch_warnings(record=True) as w:
a.impl_add_consistency('not_equal', b, warnings_only=True)
assert w != []
def test_consistency_warnings_only(): def test_consistency_warnings_only():
a = IntOption('a', '') a = IntOption('a', '')
b = IntOption('b', '') b = IntOption('b', '')
@ -99,8 +107,8 @@ def test_consistency_not_in_config_1():
b = IntOption('b', '') b = IntOption('b', '')
a.impl_add_consistency('not_equal', b) a.impl_add_consistency('not_equal', b)
od1 = OptionDescription('od1', '', [a]) od1 = OptionDescription('od1', '', [a])
od2 = OptionDescription('od2', '', [b])
od = OptionDescription('root', '', [od1]) od = OptionDescription('root', '', [od1])
od
raises(ConfigError, "Config(od)") raises(ConfigError, "Config(od)")
@ -121,6 +129,7 @@ def test_consistency_not_in_config_3():
od1 = OptionDescription('od1', '', [a]) od1 = OptionDescription('od1', '', [a])
od2 = OptionDescription('od2', '', [b]) od2 = OptionDescription('od2', '', [b])
od = OptionDescription('root', '', [od1, od2]) od = OptionDescription('root', '', [od1, od2])
od
#with subconfig #with subconfig
raises(ConfigError, "Config(od.od1)") raises(ConfigError, "Config(od.od1)")
@ -145,6 +154,34 @@ def test_consistency_not_equal_symlink():
assert set(od._cache_consistencies.keys()) == set([a, b]) assert set(od._cache_consistencies.keys()) == set([a, b])
def test_consistency_not_equal_submulti():
a = IntOption('a', '', multi=submulti)
b = IntOption('b', '', multi=submulti)
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
c = Config(od)
assert c.a == []
assert c.b == []
c.a = [[1]]
del(c.a)
c.a = [[1]]
raises(ValueError, "c.b = [[1]]")
c.a = [[1, 2]]
c.b = [[3]]
c.b = [[3, 1]]
c.b = [[3]]
c.b[0].append(1)
c.b = [[3], [1]]
def test_consistency_not_equal_default_submulti():
a = IntOption('a', '', [[1, 2]], multi=submulti)
b = IntOption('b', '', [[1]], multi=submulti)
od = OptionDescription('od', '', [a, b])
od
raises(ValueError, "a.impl_add_consistency('not_equal', b)")
def test_consistency_not_equal_multi(): def test_consistency_not_equal_multi():
a = IntOption('a', '', multi=True) a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True) b = IntOption('b', '', multi=True)
@ -160,9 +197,25 @@ def test_consistency_not_equal_multi():
c.b = [2] c.b = [2]
def test_consistency_not_equal_multi_default():
a = IntOption('a', '', multi=True)
b = IntOption('b', '', multi=True, default_multi=1)
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
c = Config(od)
assert c.a == []
assert c.b == []
c.a = [1]
del(c.a)
c.a = [1]
raises(ValueError, "c.b = [1]")
c.b = [2]
def test_consistency_default(): def test_consistency_default():
a = IntOption('a', '', 1) a = IntOption('a', '', 1)
b = IntOption('b', '', 1) b = IntOption('b', '', 1)
a, b
raises(ValueError, "a.impl_add_consistency('not_equal', b)") raises(ValueError, "a.impl_add_consistency('not_equal', b)")
@ -170,6 +223,7 @@ def test_consistency_default_multi():
a = IntOption('a', '', [2, 1], multi=True) a = IntOption('a', '', [2, 1], multi=True)
b = IntOption('b', '', [1, 1], multi=True) b = IntOption('b', '', [1, 1], multi=True)
c = IntOption('c', '', [1, 2], multi=True) c = IntOption('c', '', [1, 2], multi=True)
b
raises(ValueError, "a.impl_add_consistency('not_equal', b)") raises(ValueError, "a.impl_add_consistency('not_equal', b)")
a.impl_add_consistency('not_equal', c) a.impl_add_consistency('not_equal', c)
@ -221,8 +275,11 @@ def test_consistency_ip_in_network():
a = NetworkOption('a', '') a = NetworkOption('a', '')
b = NetmaskOption('b', '') b = NetmaskOption('b', '')
c = IPOption('c', '') c = IPOption('c', '')
od = OptionDescription('od', '', [a, b, c]) d = IPOption('d', '')
od = OptionDescription('od', '', [a, b, c, d])
c.impl_add_consistency('in_network', a, b) c.impl_add_consistency('in_network', a, b)
d.impl_add_consistency('in_network', a, b, warnings_only=True)
warnings.simplefilter("always", ValueWarning)
cfg = Config(od) cfg = Config(od)
cfg.a = '192.168.1.0' cfg.a = '192.168.1.0'
cfg.b = '255.255.255.0' cfg.b = '255.255.255.0'
@ -230,6 +287,9 @@ def test_consistency_ip_in_network():
raises(ValueError, "cfg.c = '192.168.2.1'") raises(ValueError, "cfg.c = '192.168.2.1'")
raises(ValueError, "cfg.c = '192.168.1.0'") raises(ValueError, "cfg.c = '192.168.1.0'")
raises(ValueError, "cfg.c = '192.168.1.255'") raises(ValueError, "cfg.c = '192.168.1.255'")
with warnings.catch_warnings(record=True) as w:
cfg.d = '192.168.2.1'
assert len(w) == 1
def test_consistency_ip_in_network_len_error(): def test_consistency_ip_in_network_len_error():
@ -239,6 +299,7 @@ def test_consistency_ip_in_network_len_error():
od = OptionDescription('od', '', [a, b, c]) od = OptionDescription('od', '', [a, b, c])
c.impl_add_consistency('in_network', a) c.impl_add_consistency('in_network', a)
cfg = Config(od) cfg = Config(od)
cfg
raises(ConfigError, "cfg.a = '192.168.2.0'") raises(ConfigError, "cfg.a = '192.168.2.0'")
@ -257,7 +318,7 @@ def test_consistency_ip_netmask_network_error():
def test_consistency_ip_netmask_error_multi(): def test_consistency_ip_netmask_error_multi():
a = IPOption('a', '', multi=True) a = IPOption('a', '', multi=True)
b = NetmaskOption('b', '') b = NetmaskOption('b', '')
od = OptionDescription('od', '', [a, b]) OptionDescription('od', '', [a, b])
raises(ConfigError, "b.impl_add_consistency('ip_netmask', a)") raises(ConfigError, "b.impl_add_consistency('ip_netmask', a)")
@ -449,17 +510,17 @@ def test_consistency_broadcast_default_1():
a = NetworkOption('a', '', '192.168.1.0') a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128') b = NetmaskOption('b', '', '255.255.255.128')
c = BroadcastOption('c', '', '192.168.2.127') c = BroadcastOption('c', '', '192.168.2.127')
d = BroadcastOption('d', '', '192.168.1.127')
od = OptionDescription('a', '', [a, b, c]) od = OptionDescription('a', '', [a, b, c])
od
raises(ValueError, "c.impl_add_consistency('broadcast', a, b)") raises(ValueError, "c.impl_add_consistency('broadcast', a, b)")
def test_consistency_broadcast_default_2(): def test_consistency_broadcast_default_2():
a = NetworkOption('a', '', '192.168.1.0') a = NetworkOption('a', '', '192.168.1.0')
b = NetmaskOption('b', '', '255.255.255.128') b = NetmaskOption('b', '', '255.255.255.128')
c = BroadcastOption('c', '', '192.168.2.127')
d = BroadcastOption('d', '', '192.168.1.127') d = BroadcastOption('d', '', '192.168.1.127')
od2 = OptionDescription('a', '', [a, b, d]) od2 = OptionDescription('a', '', [a, b, d])
od2
d.impl_add_consistency('broadcast', a, b) d.impl_add_consistency('broadcast', a, b)

View File

@ -11,8 +11,11 @@ from tiramisu.error import SlaveError
from py.test import raises from py.test import raises
def return_val(): def return_val(val=None):
if val is None:
return 'val' return 'val'
else:
return val
def return_list(value=None): def return_list(value=None):
@ -319,6 +322,8 @@ def test_callback_submulti_list():
cfg.multi.append() cfg.multi.append()
assert cfg.getowner(multi) == owner assert cfg.getowner(multi) == owner
assert cfg.multi == [['val', 'val'], ['val', 'val']] assert cfg.multi == [['val', 'val'], ['val', 'val']]
cfg.multi.append()
assert cfg.multi == [['val', 'val'], ['val', 'val'], ['val', 'val']]
del(cfg.multi) del(cfg.multi)
assert cfg.getowner(multi) == owners.default assert cfg.getowner(multi) == owners.default
cfg.multi[0].append() cfg.multi[0].append()
@ -342,6 +347,8 @@ def test_callback_submulti_list_list():
cfg.multi[0].append() cfg.multi[0].append()
assert cfg.getowner(multi) == owner assert cfg.getowner(multi) == owner
assert cfg.multi == [['val', 'val', None]] assert cfg.multi == [['val', 'val', None]]
del(cfg.multi)
cfg.multi.append()
#FIXME multi sur une master #FIXME multi sur une master
@ -639,3 +646,20 @@ def test__master_is_submulti():
cfg.ip_admin_eth0.ip_admin_eth0[0].pop(0) cfg.ip_admin_eth0.ip_admin_eth0[0].pop(0)
assert cfg.ip_admin_eth0.ip_admin_eth0 == [["192.168.1.1"], ["192.168.230.147"]] assert cfg.ip_admin_eth0.ip_admin_eth0 == [["192.168.1.1"], ["192.168.230.147"]]
raises(ValueError, 'cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.1.1", "192.168.1.1"]') raises(ValueError, 'cfg.ip_admin_eth0.ip_admin_eth0 = ["192.168.1.1", "192.168.1.1"]')
def test_callback_submulti():
multi = StrOption('multi', '', multi=submulti)
multi2 = StrOption('multi2', '', multi=submulti, callback=return_val, callback_params={'': ((multi, False),)})
od = OptionDescription('multi', '', [multi, multi2])
cfg = Config(od)
cfg.read_write()
owner = cfg.cfgimpl_get_settings().getowner()
assert cfg.getowner(multi) == owners.default
assert cfg.multi == []
assert cfg.multi2 == []
cfg.multi.append(['val'])
assert cfg.getowner(multi) == owner
assert cfg.getowner(multi2) == owners.default
assert cfg.multi == [['val']]
assert cfg.multi2 == [['val']]

View File

@ -139,7 +139,6 @@ def carry_out_calculation(option, context, callback, callback_params,
# if callback_params has a callback, launch several time calculate() # if callback_params has a callback, launch several time calculate()
master_slave = False master_slave = False
# multi's option should have same value for all option # multi's option should have same value for all option
len_multi = None
try: try:
if option._is_subdyn(): if option._is_subdyn():
tcparams[''] = [(option.impl_getsuffix(), False)] tcparams[''] = [(option.impl_getsuffix(), False)]
@ -182,7 +181,6 @@ def carry_out_calculation(option, context, callback, callback_params,
if opt.impl_is_master_slaves() and \ if opt.impl_is_master_slaves() and \
opt.impl_get_master_slaves().in_same_group(option): opt.impl_get_master_slaves().in_same_group(option):
len_multi = len(value)
master_slave = True master_slave = True
is_multi = True is_multi = True
else: else:
@ -197,32 +195,20 @@ def carry_out_calculation(option, context, callback, callback_params,
# if no index, return a list # if no index, return a list
if master_slave: if master_slave:
ret = [] ret = []
if index is not undefined:
# for example if append master and get a no default slave without
# getting master
range_ = [index]
else:
range_ = range(len_multi)
for incr in range_:
args = [] args = []
kwargs = {} kwargs = {}
for key, couples in tcparams.items(): for key, couples in tcparams.items():
for couple in couples: for couple in couples:
value, ismulti = couple value, ismulti = couple
if ismulti: if ismulti:
val = value[incr] val = value[index]
else: else:
val = value val = value
if key == '': if key == '':
args.append(val) args.append(val)
else: else:
kwargs[key] = val kwargs[key] = val
calc = calculate(callback, args, kwargs) return calculate(callback, args, kwargs)
if index is not undefined:
ret = calc
else:
ret.append(calc)
return ret
else: else:
# no value is multi # no value is multi
# return a single value # return a single value
@ -236,15 +222,9 @@ def carry_out_calculation(option, context, callback, callback_params,
else: else:
kwargs[key] = couple[0] kwargs[key] = couple[0]
ret = calculate(callback, args, kwargs) ret = calculate(callback, args, kwargs)
if callback_params != {}: if callback_params != {} and isinstance(ret, list) and index is not undefined:
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 " raise SlaveError(_("callback cannot return a list for a "
"slave option ({0})").format(path)) "slave option ({0})").format(path))
if len(ret) < index + 1:
ret = None
else:
ret = ret[index]
return ret return ret

View File

@ -669,9 +669,6 @@ class Config(_CommonConfig):
def impl_getname(self): def impl_getname(self):
return self._impl_name return self._impl_name
def impl_setname(self, name):
self._impl_name = name
class GroupConfig(_CommonConfig): class GroupConfig(_CommonConfig):
__slots__ = ('__weakref__', '_impl_children', '_impl_name') __slots__ = ('__weakref__', '_impl_children', '_impl_name')
@ -684,12 +681,10 @@ class GroupConfig(_CommonConfig):
for child in children: for child in children:
if not isinstance(child, _CommonConfig): if not isinstance(child, _CommonConfig):
raise ValueError(_("groupconfig's children must be Config, MetaConfig or GroupConfig")) raise ValueError(_("groupconfig's children must be Config, MetaConfig or GroupConfig"))
name = child._impl_name name_ = child._impl_name
if name is None: if name_ is None:
raise ValueError(_('name must be set to config before creating groupconfig')) raise ValueError(_('name must be set to config before creating groupconfig'))
#if name in names: names.append(name_)
# raise ValueError(_('config name must be uniq in groupconfig'))
names.append(name)
if len(names) != len(set(names)): if len(names) != len(set(names)):
for idx in xrange(1, len(names) + 1): for idx in xrange(1, len(names) + 1):
name = names.pop(0) name = names.pop(0)
@ -827,6 +822,9 @@ class MetaConfig(GroupConfig):
def set_value(self, path, value, force_default=False, def set_value(self, path, value, force_default=False,
force_dont_change_value=False, force_default_if_same=False, force_dont_change_value=False, force_default_if_same=False,
only_config=False): only_config=False):
"""only_config: could be set if you want modify value in all Config included in
this MetaConfig
"""
if only_config: if only_config:
if force_default or force_default_if_same or force_dont_change_value: if force_default or force_default_if_same or force_dont_change_value:
raise ValueError(_('force_default, force_default_if_same or ' raise ValueError(_('force_default, force_default_if_same or '

View File

@ -140,6 +140,7 @@ class Base(StorageBase):
default = [] default = []
self.impl_validate(default) self.impl_validate(default)
self._set_default_values(default, default_multi) self._set_default_values(default, default_multi)
#callback is False in optiondescription
if callback is not False: if callback is not False:
self.impl_set_callback(callback, callback_params) self.impl_set_callback(callback, callback_params)
self.commit() self.commit()
@ -184,7 +185,7 @@ class BaseOption(Base):
:param load: `True` if we are at the init of the option description :param load: `True` if we are at the init of the option description
:type load: bool :type load: bool
""" """
if not load and self.impl_getrequires() is None: if not load and self.impl_getrequires() == []:
self._state_requires = None self._state_requires = None
elif load and self._state_requires is None: elif load and self._state_requires is None:
del(self._state_requires) del(self._state_requires)
@ -215,7 +216,7 @@ class BaseOption(Base):
if self.__class__.__name__ == 'OptionDescription' or \ if self.__class__.__name__ == 'OptionDescription' or \
isinstance(self, SymLinkOption): isinstance(self, SymLinkOption):
return return
if not load and self.impl_get_callback() is None: if not load and self.impl_get_callback() == (None, {}):
self._state_callback = None self._state_callback = None
self._state_callback_params = {} self._state_callback_params = {}
elif load and self._state_callback is None: elif load and self._state_callback is None:
@ -228,7 +229,6 @@ class BaseOption(Base):
else: else:
callback, callback_params = self.impl_get_callback() callback, callback_params = self.impl_get_callback()
self._state_callback_params = {} self._state_callback_params = {}
if callback_params is not None:
cllbck_prms = {} cllbck_prms = {}
for key, values in callback_params.items(): for key, values in callback_params.items():
vls = [] vls = []
@ -242,8 +242,6 @@ class BaseOption(Base):
value[1]) value[1])
vls.append(value) vls.append(value)
cllbck_prms[key] = tuple(vls) cllbck_prms[key] = tuple(vls)
else:
cllbck_prms = None
if load: if load:
del(self._state_callback) del(self._state_callback)
@ -354,11 +352,6 @@ class BaseOption(Base):
except (KeyError, AttributeError): except (KeyError, AttributeError):
pass pass
elif name == '_opt': elif name == '_opt':
try:
if self._impl_getopt() is not None:
#so _opt is already set
is_readonly = True
except (KeyError, AttributeError):
pass pass
elif name != '_readonly': elif name != '_readonly':
is_readonly = self.impl_is_readonly() is_readonly = self.impl_is_readonly()
@ -470,20 +463,9 @@ class Option(OnlyOption):
try: try:
all_cons_vals.append(opt_value[index]) all_cons_vals.append(opt_value[index])
except IndexError, err: except IndexError, err:
log.debug('indexerror in _launch_consistency: {0}'.format(err))
#value is not already set, could be higher index #value is not already set, could be higher index
#so return if no value and not default_value #so return if no value and not default_value
if context is not undefined: log.debug('indexerror in _launch_consistency: {0}'.format(err))
if isinstance(opt, DynSymLinkOption):
path = opt.impl_getpath(context)
else:
path = descr.impl_get_path_by_opt(opt)
default_value = context.cfgimpl_get_values()._getvalue(opt, path, True, index=index)
else:
default_value = opt.impl_getdefault_multi()
if default_value is not None:
all_cons_vals.append(default_value)
else:
return return
except PropertiesOptionError as err: except PropertiesOptionError as err:
log.debug('propertyerror in _launch_consistency: {0}'.format(err)) log.debug('propertyerror in _launch_consistency: {0}'.format(err))
@ -563,15 +545,11 @@ class Option(OnlyOption):
if self._is_warnings_only(): if self._is_warnings_only():
warning = error warning = error
error = None error = None
except ValueWarning as warning:
log.debug(_('do_validation for {0}: warning in value').format(
self.impl_getname()), exc_info=True)
pass
if error is None and warning is None: if error is None and warning is None:
try: try:
# if context launch consistency validation # if context launch consistency validation
if context is not undefined: #if context is not undefined:
descr._valid_consistency(current_opt, _value, context, self._valid_consistency(current_opt, _value, context,
_index, submulti_index) _index, submulti_index)
except ValueError as error: except ValueError as error:
log.debug(_('do_validation for {0}: error in consistency').format( log.debug(_('do_validation for {0}: error in consistency').format(
@ -584,7 +562,7 @@ class Option(OnlyOption):
if warning: if warning:
msg = _("warning on the value of the option {0}: {1}").format( msg = _("warning on the value of the option {0}: {1}").format(
self.impl_getname(), warning) self.impl_getname(), warning)
if context is None or 'warnings' in \ if context is undefined or 'warnings' in \
context.cfgimpl_get_settings(): context.cfgimpl_get_settings():
warnings.warn_explicit(ValueWarning(msg, self), warnings.warn_explicit(ValueWarning(msg, self),
ValueWarning, ValueWarning,
@ -594,8 +572,8 @@ class Option(OnlyOption):
self.impl_getname(), error)) self.impl_getname(), error))
# generic calculation # generic calculation
if context is not undefined: #if context is not undefined:
descr = context.cfgimpl_get_description() # descr = context.cfgimpl_get_description()
if not self.impl_is_multi(): if not self.impl_is_multi():
do_validation(value, None, None) do_validation(value, None, None)
@ -656,33 +634,7 @@ class Option(OnlyOption):
"accesses the Option's doc" "accesses the Option's doc"
return self.impl_get_information('doc') return self.impl_get_information('doc')
#def impl_getkey(self, value): def _valid_consistencies(self, other_opts):
# return value
def impl_add_consistency(self, func, *other_opts, **params):
"""Add consistency means that value will be validate with other_opts
option's values.
:param func: function's name
:type func: `str`
:param other_opts: options used to validate value
:type other_opts: `list` of `tiramisu.option.Option`
:param params: extra params (warnings_only and transitive are allowed)
"""
if self.impl_is_readonly(): # pragma: optional cover
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
" read-only").format(
self.__class__.__name__,
self.impl_getname()))
warnings_only = False
transitive = True
for key, value in params.items():
if key == 'warnings_only':
warnings_only = value
elif key == 'transitive':
transitive = value
else:
raise ValueError(_('unknow parameter {0} in consistency').format(key))
if self._is_subdyn(): if self._is_subdyn():
dynod = self._impl_getsubdyn() dynod = self._impl_getsubdyn()
else: else:
@ -706,31 +658,75 @@ class Option(OnlyOption):
if self.impl_is_multi() != opt.impl_is_multi(): # pragma: optional cover if self.impl_is_multi() != opt.impl_is_multi(): # pragma: optional cover
raise ConfigError(_('every options in consistency must be ' raise ConfigError(_('every options in consistency must be '
'multi or none')) 'multi or none'))
def impl_add_consistency(self, func, *other_opts, **params):
"""Add consistency means that value will be validate with other_opts
option's values.
:param func: function's name
:type func: `str`
:param other_opts: options used to validate value
:type other_opts: `list` of `tiramisu.option.Option`
:param params: extra params (warnings_only and transitive are allowed)
"""
if self.impl_is_readonly(): # pragma: optional cover
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
" read-only").format(
self.__class__.__name__,
self.impl_getname()))
self._valid_consistencies(other_opts)
func = '_cons_{0}'.format(func) func = '_cons_{0}'.format(func)
if func not in dir(self): if func not in dir(self):
raise ConfigError(_('consistency {0} not available for this option').format(func)) raise ConfigError(_('consistency {0} not available for this option').format(func))
all_cons_opts = tuple([self] + list(other_opts)) all_cons_opts = tuple([self] + list(other_opts))
value = self.impl_getdefault() unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
if value is not None: if unknown_params != set():
if self.impl_is_multi(): raise ValueError(_('unknow parameter {0} in consistency').format(unknown_params))
for idx, val in enumerate(value):
if not self.impl_is_submulti():
self._launch_consistency(func, self, val, undefined, idx,
None, all_cons_opts,
warnings_only, transitive)
else:
for slave_idx, val in enumerate(value):
self._launch_consistency(func, self, val, None,
idx, slave_idx,
all_cons_opts,
warnings_only, transitive)
else:
self._launch_consistency(func, self, value, undefined, None,
None, all_cons_opts, warnings_only,
transitive)
self._add_consistency(func, all_cons_opts, params) self._add_consistency(func, all_cons_opts, params)
#re validate default value when add consistency #validate default value when add consistency
try:
self.impl_validate(self.impl_getdefault()) self.impl_validate(self.impl_getdefault())
except ValueError, err:
self._del_consistency()
raise err
def _valid_consistency(self, option, value, context, index, submulti_idx):
if context is not undefined:
descr = context.cfgimpl_get_description()
if descr._cache_consistencies is None:
return True
#consistencies is something like [('_cons_not_equal', (opt1, opt2))]
if isinstance(option, DynSymLinkOption):
consistencies = descr._cache_consistencies.get(option._impl_getopt())
else:
consistencies = descr._cache_consistencies.get(option)
else:
consistencies = option._get_consistencies()
if consistencies is not None:
for func, all_cons_opts, params in consistencies:
warnings_only = params.get('warnings_only', False)
transitive = params.get('transitive', True)
#all_cons_opts[0] is the option where func is set
if isinstance(option, DynSymLinkOption):
subpath = '.'.join(option._dyn.split('.')[:-1])
namelen = len(option._impl_getopt().impl_getname())
suffix = option.impl_getname()[namelen:]
opts = []
for opt in all_cons_opts:
name = opt.impl_getname() + suffix
path = subpath + '.' + name
opts.append(opt._impl_to_dyn(name, path))
else:
opts = all_cons_opts
try:
opts[0]._launch_consistency(func, option, value, context,
index, submulti_idx, opts,
warnings_only, transitive)
except ValueError as err:
if warnings_only:
raise ValueWarning(err.message, option)
else:
raise err
def _cons_not_equal(self, opts, vals, warnings_only): def _cons_not_equal(self, opts, vals, warnings_only):
for idx_inf, val_inf in enumerate(vals): for idx_inf, val_inf in enumerate(vals):
@ -740,6 +736,7 @@ class Option(OnlyOption):
msg = _("same value for {0} and {1}, should be different") msg = _("same value for {0} and {1}, should be different")
else: else:
msg = _("same value for {0} and {1}, must be different") msg = _("same value for {0} and {1}, must be different")
log.debug('_cons_not_equal: {0} and {1} are not different'.format(val_inf, val_sup))
raise ValueError(msg.format(opts[idx_inf].impl_getname(), raise ValueError(msg.format(opts[idx_inf].impl_getname(),
opts[idx_inf + idx_sup + 1].impl_getname())) opts[idx_inf + idx_sup + 1].impl_getname()))
@ -753,7 +750,7 @@ class Option(OnlyOption):
:param load: `True` if we are at the init of the option description :param load: `True` if we are at the init of the option description
:type load: bool :type load: bool
""" """
if not load and self._get_consistencies() is None: if not load and self._get_consistencies() == ():
self._state_consistencies = None self._state_consistencies = None
elif load and self._state_consistencies is None: elif load and self._state_consistencies is None:
del(self._state_consistencies) del(self._state_consistencies)
@ -787,10 +784,7 @@ class Option(OnlyOption):
def _validate_callback(self, callback, callback_params): def _validate_callback(self, callback, callback_params):
if callback is None: if callback is None:
return return
try:
default_multi = self.impl_getdefault_multi() default_multi = self.impl_getdefault_multi()
except AttributeError:
default_multi = None
if (not self.impl_is_multi() and (self.impl_getdefault() is not None or if (not self.impl_is_multi() and (self.impl_getdefault() is not None or
default_multi is not None)) or \ default_multi is not None)) or \
(self.impl_is_multi() and (self.impl_getdefault() != [] or (self.impl_is_multi() and (self.impl_getdefault() != [] or
@ -808,8 +802,6 @@ def validate_requires_arg(requires, name):
know more about know more about
the description of the requires dictionary the description of the requires dictionary
""" """
if requires is None:
return None, None
ret_requires = {} ret_requires = {}
config_action = {} config_action = {}

View File

@ -173,13 +173,9 @@ class IPOption(Option):
# sometimes an ip term starts with a zero # sometimes an ip term starts with a zero
# but this does not fit in some case, for example bind does not like it # but this does not fit in some case, for example bind does not like it
self._impl_valid_unicode(value) self._impl_valid_unicode(value)
try:
for val in value.split('.'): for val in value.split('.'):
if val.startswith("0") and len(val) > 1: if val.startswith("0") and len(val) > 1:
raise ValueError(_('invalid IP')) # pragma: optional cover raise ValueError(_('invalid IP')) # pragma: optional cover
except AttributeError: # pragma: optional cover
#if integer for example
raise ValueError(_('invalid IP'))
# 'standard' validation # 'standard' validation
try: try:
IP('{0}/32'.format(value)) IP('{0}/32'.format(value))
@ -432,6 +428,7 @@ class DomainnameOption(Option):
def _validate(self, value, context=undefined): def _validate(self, value, context=undefined):
self._impl_valid_unicode(value) self._impl_valid_unicode(value)
def _valid_length(val): def _valid_length(val):
if len(val) < 1: if len(val) < 1:
raise ValueError(_("invalid domainname's length (min 1)")) raise ValueError(_("invalid domainname's length (min 1)"))

View File

@ -24,10 +24,9 @@ import re
from tiramisu.i18n import _ from tiramisu.i18n import _
from tiramisu.setting import groups, undefined # , log from tiramisu.setting import groups, undefined # , log
from .baseoption import BaseOption, DynSymLinkOption, SymLinkOption, \ from .baseoption import BaseOption, SymLinkOption, allowed_character
allowed_character
from . import MasterSlaves from . import MasterSlaves
from tiramisu.error import ConfigError, ConflictError, ValueWarning from tiramisu.error import ConfigError, ConflictError
from tiramisu.storage import get_storages_option from tiramisu.storage import get_storages_option
from tiramisu.autolib import carry_out_calculation from tiramisu.autolib import carry_out_calculation
@ -103,6 +102,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
cache_option.append(option._get_id()) cache_option.append(option._get_id())
if not isinstance(option, OptionDescription): if not isinstance(option, OptionDescription):
for func, all_cons_opts, params in option._get_consistencies(): for func, all_cons_opts, params in option._get_consistencies():
all_cons_opts[0]._valid_consistencies(all_cons_opts[1:])
for opt in all_cons_opts: for opt in all_cons_opts:
_consistencies.setdefault(opt, _consistencies.setdefault(opt,
[]).append((func, []).append((func,
@ -162,40 +162,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
raise ValueError(_('group_type: {0}' raise ValueError(_('group_type: {0}'
' not allowed').format(group_type)) ' not allowed').format(group_type))
def _valid_consistency(self, option, value, context, index, submulti_idx):
if self._cache_consistencies is None:
return True
#consistencies is something like [('_cons_not_equal', (opt1, opt2))]
if isinstance(option, DynSymLinkOption):
consistencies = self._cache_consistencies.get(option._impl_getopt())
else:
consistencies = self._cache_consistencies.get(option)
if consistencies is not None:
for func, all_cons_opts, params in consistencies:
warnings_only = params.get('warnings_only', False)
transitive = params.get('transitive', True)
#all_cons_opts[0] is the option where func is set
if isinstance(option, DynSymLinkOption):
subpath = '.'.join(option._dyn.split('.')[:-1])
namelen = len(option._impl_getopt().impl_getname())
suffix = option.impl_getname()[namelen:]
opts = []
for opt in all_cons_opts:
name = opt.impl_getname() + suffix
path = subpath + '.' + name
opts.append(opt._impl_to_dyn(name, path))
else:
opts = all_cons_opts
try:
opts[0]._launch_consistency(func, option, value, context,
index, submulti_idx, opts,
warnings_only, transitive)
except ValueError as err:
if warnings_only:
raise ValueWarning(err.message, option)
else:
raise err
def _impl_getstate(self, descr=None): def _impl_getstate(self, descr=None):
"""enables us to export into a dict """enables us to export into a dict
:param descr: parent :class:`tiramisu.option.OptionDescription` :param descr: parent :class:`tiramisu.option.OptionDescription`
@ -317,12 +283,15 @@ class DynOptionDescription(OptionDescription):
for child in children: for child in children:
if isinstance(child, OptionDescription): if isinstance(child, OptionDescription):
if child.impl_get_group_type() != groups.master: if child.impl_get_group_type() != groups.master:
raise ConfigError(_('cannot set optiondescription in an ' raise ConfigError(_('cannot set optiondescription in a '
'dynoptiondescription')) 'dynoptiondescription'))
for chld in child._impl_getchildren(): for chld in child._impl_getchildren():
chld._impl_setsubdyn(self) chld._impl_setsubdyn(self)
if isinstance(child, SymLinkOption): if isinstance(child, SymLinkOption):
raise ConfigError(_('cannot set symlinkoption in an ' raise ConfigError(_('cannot set symlinkoption in a '
'dynoptiondescription'))
if isinstance(child, SymLinkOption):
raise ConfigError(_('cannot set symlinkoption in a '
'dynoptiondescription')) 'dynoptiondescription'))
child._impl_setsubdyn(self) child._impl_setsubdyn(self)
self.impl_set_callback(callback, callback_params) self.impl_set_callback(callback, callback_params)

View File

@ -145,6 +145,9 @@ class StorageBase(object):
except AttributeError: except AttributeError:
self._consistencies = [cons] self._consistencies = [cons]
def _del_consistency(self):
self._consistencies.pop(-1)
def _get_consistencies(self): def _get_consistencies(self):
try: try:
return self._consistencies return self._consistencies

View File

@ -57,7 +57,7 @@ class Values(object):
def _get_multi(self, opt, path): def _get_multi(self, opt, path):
return Multi([], self.context, opt, path) return Multi([], self.context, opt, path)
def _getdefaultvalue(self, opt, path, with_meta, index): def _getdefaultvalue(self, opt, path, with_meta, index, submulti_index):
# if value has callback and is not set # if value has callback and is not set
if opt.impl_has_callback(): if opt.impl_has_callback():
callback, callback_params = opt.impl_get_callback() callback, callback_params = opt.impl_get_callback()
@ -65,18 +65,14 @@ class Values(object):
callback=callback, callback=callback,
callback_params=callback_params, callback_params=callback_params,
index=index) index=index)
try:
if isinstance(value, list) and index is not undefined: if isinstance(value, list) and index is not undefined:
#if submulti and return a list of list, just return list #if return a list and index is set, return value only if
if opt.impl_is_submulti(): #it's a submulti without submulti_index and without list of list
val = value[index] if opt.impl_is_submulti() and submulti_index is undefined and \
if isinstance(val, list): (len(value) == 0 or not isinstance(value[0], list)):
value = val return value
else: else:
value = value[index]
return value return value
except IndexError:
pass
if with_meta: if with_meta:
meta = self._getcontext().cfgimpl_get_meta() meta = self._getcontext().cfgimpl_get_meta()
if meta is not None: if meta is not None:
@ -94,7 +90,7 @@ class Values(object):
# now try to get default value # now try to get default value
value = opt.impl_getdefault() value = opt.impl_getdefault()
if opt.impl_is_multi() and index is not undefined: if opt.impl_is_multi() and index is not undefined:
if value is None: if value == []:
value = opt.impl_getdefault_multi() value = opt.impl_getdefault_multi()
else: else:
try: try:
@ -103,43 +99,20 @@ class Values(object):
value = opt.impl_getdefault_multi() value = opt.impl_getdefault_multi()
return value return value
def _getvalue(self, opt, path, is_default, index=undefined, def _getvalue(self, opt, path, is_default, self_properties,
with_meta=True, self_properties=undefined, index=undefined, submulti_index=undefined, with_meta=True,
masterlen=undefined): masterlen=undefined):
"""actually retrieves the value """actually retrieves the value
:param opt: the `option.Option()` object :param opt: the `option.Option()` object
:returns: the option's value (or the default value if not set) :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 = 'frozen' in self_properties and \
'force_default_on_freeze' in self_properties 'force_default_on_freeze' in self_properties
# not default value
if not is_default and not force_default: if not is_default and not force_default:
if opt.impl_is_master_slaves('slave'): if opt.impl_is_master_slaves('slave'):
#if masterlen is not undefined: return self._p_.getvalue(path, index)
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: else:
value = self._p_.getvalue(path) value = self._p_.getvalue(path)
if index is not undefined: if index is not undefined:
@ -151,7 +124,7 @@ class Values(object):
pass pass
else: else:
return value return value
return self._getdefaultvalue(opt, path, with_meta, index) return self._getdefaultvalue(opt, path, with_meta, index, submulti_index)
def get_modified_values(self): def get_modified_values(self):
context = self._getcontext() context = self._getcontext()
@ -316,13 +289,9 @@ class Values(object):
self_properties=self_properties, self_properties=self_properties,
index=index) index=index)
try: try:
if index is None: value = self._getvalue(opt, path, is_default, self_properties,
gv_index = undefined index=index, submulti_index=submulti_index,
else:
gv_index = index
value = self._getvalue(opt, path, is_default, index=gv_index,
with_meta=with_meta, with_meta=with_meta,
self_properties=self_properties,
masterlen=masterlen) masterlen=masterlen)
config_error = None config_error = None
except ConfigError as err: except ConfigError as err:
@ -344,9 +313,6 @@ class Values(object):
else: else:
force_index = index force_index = index
if opt.impl_is_multi(): if opt.impl_is_multi():
#for slave is a multi
if index is None and not isinstance(value, list):
value = []
if force_index is None: if force_index is None:
value = Multi(value, self.context, opt, path) value = Multi(value, self.context, opt, path)
elif opt.impl_is_submulti() and submulti_index is undefined: elif opt.impl_is_submulti() and submulti_index is undefined:
@ -773,10 +739,7 @@ class Multi(list):
" which is a slave").format(self.opt.impl_getname())) " which is a slave").format(self.opt.impl_getname()))
index = self.__len__() index = self.__len__()
if value is undefined: if value is undefined:
try:
value = self._get_validated_value(index) value = self._get_validated_value(index)
except IndexError:
value = None
context = self._getcontext() context = self._getcontext()
setting = context.cfgimpl_get_settings() setting = context.cfgimpl_get_settings()
setting_properties = setting._getproperties(read_write=False) setting_properties = setting._getproperties(read_write=False)