Merge branch 'master' into orm

Conflicts:
	test/test_dereference.py
	test/test_state.py
	tiramisu/config.py
	tiramisu/value.py
This commit is contained in:
Emmanuel Garette 2014-02-02 18:52:13 +01:00
commit 5897231421
9 changed files with 594 additions and 345 deletions

View File

@ -2,8 +2,8 @@
import autopath import autopath
#from py.test import raises #from py.test import raises
from tiramisu.config import Config from tiramisu.config import Config, GroupConfig, MetaConfig
from tiramisu.option import BoolOption, OptionDescription from tiramisu.option import BoolOption, IntOption, OptionDescription
import weakref import weakref
@ -119,3 +119,31 @@ def test_deref_optiondescription_config():
del(c) del(c)
#FIXME #FIXME
#assert w() is None #assert w() is None
def test_deref_groupconfig():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
conf1 = Config(od2)
conf2 = Config(od2)
meta = GroupConfig([conf1, conf2])
w = weakref.ref(conf1)
del(conf1)
assert w() is not None
del(meta)
assert w() is None
def test_deref_metaconfig():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
conf1 = Config(od2)
conf2 = Config(od2)
meta = MetaConfig([conf1, conf2])
w = weakref.ref(conf1)
del(conf1)
assert w() is not None
del(meta)
assert w() is None

View File

@ -1,172 +1,173 @@
#import autopath import autopath
#from py.test import raises from py.test import raises
#from tiramisu.setting import owners from tiramisu.setting import owners
#from tiramisu.config import Config, MetaConfig from tiramisu.config import Config, GroupConfig, MetaConfig
#from tiramisu.option import IntOption, OptionDescription from tiramisu.option import IntOption, OptionDescription
#from tiramisu.error import ConfigError from tiramisu.error import ConfigError
#owners.addowner('meta') owners.addowner('meta')
#def make_description(): def make_description():
# i1 = IntOption('i1', '') i1 = IntOption('i1', '')
# i2 = IntOption('i2', '', default=1) i2 = IntOption('i2', '', default=1)
# i3 = IntOption('i3', '') i3 = IntOption('i3', '')
# i4 = IntOption('i4', '', default=2) i4 = IntOption('i4', '', default=2)
# od1 = OptionDescription('od1', '', [i1, i2, i3, i4]) od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
# od2 = OptionDescription('od2', '', [od1]) od2 = OptionDescription('od2', '', [od1])
# conf1 = Config(od2) conf1 = Config(od2)
# conf2 = Config(od2) conf2 = Config(od2)
# meta = MetaConfig([conf1, conf2]) meta = MetaConfig([conf1, conf2])
# meta.cfgimpl_get_settings().setowner(owners.meta) meta.cfgimpl_get_settings().setowner(owners.meta)
# return meta return meta
##FIXME ne pas mettre 2 meta dans une config #FIXME ne pas mettre 2 meta dans une config
##FIXME ne pas mettre 2 OD differents dans un meta #FIXME ne pas mettre 2 OD differents dans un meta
#def test_none(): #FIXME serialization
# meta = make_description() def test_none():
# conf1, conf2 = meta._impl_children meta = make_description()
# assert conf1.od1.i3 is conf2.od1.i3 is None conf1, conf2 = meta._impl_children
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default assert conf1.od1.i3 is conf2.od1.i3 is None
# meta.od1.i3 = 3 assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
# assert conf1.od1.i3 == conf2.od1.i3 == 3 meta.od1.i3 = 3
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta assert conf1.od1.i3 == conf2.od1.i3 == 3
# meta.od1.i3 = 3 assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
# conf1.od1.i3 = 2 meta.od1.i3 = 3
# assert conf1.od1.i3 == 2 conf1.od1.i3 = 2
# assert conf2.od1.i3 == 3 assert conf1.od1.i3 == 2
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user assert conf2.od1.i3 == 3
# assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
# meta.od1.i3 = 4 assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
# assert conf1.od1.i3 == 2 meta.od1.i3 = 4
# assert conf2.od1.i3 == 4 assert conf1.od1.i3 == 2
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user assert conf2.od1.i3 == 4
# assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
# del(meta.od1.i3) assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.meta
# assert conf1.od1.i3 == 2 del(meta.od1.i3)
# assert conf2.od1.i3 is None assert conf1.od1.i3 == 2
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user assert conf2.od1.i3 is None
# assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is owners.user
# del(conf1.od1.i3) assert conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
# assert conf1.od1.i3 is conf2.od1.i3 is None del(conf1.od1.i3)
# assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default assert conf1.od1.i3 is conf2.od1.i3 is None
assert conf1.getowner(conf1.unwrap_from_path('od1.i3')) is conf2.getowner(conf2.unwrap_from_path('od1.i3')) is owners.default
#def test_default(): def test_default():
# meta = make_description() meta = make_description()
# conf1, conf2 = meta._impl_children conf1, conf2 = meta._impl_children
# assert conf1.od1.i2 == conf2.od1.i2 == 1 assert conf1.od1.i2 == conf2.od1.i2 == 1
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
# meta.od1.i2 = 3 meta.od1.i2 = 3
# assert conf1.od1.i2 == conf2.od1.i2 == 3 assert conf1.od1.i2 == conf2.od1.i2 == 3
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
# meta.od1.i2 = 3 meta.od1.i2 = 3
# conf1.od1.i2 = 2 conf1.od1.i2 = 2
# assert conf1.od1.i2 == 2 assert conf1.od1.i2 == 2
# assert conf2.od1.i2 == 3 assert conf2.od1.i2 == 3
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
# meta.od1.i2 = 4 meta.od1.i2 = 4
# assert conf1.od1.i2 == 2 assert conf1.od1.i2 == 2
# assert conf2.od1.i2 == 4 assert conf2.od1.i2 == 4
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
# del(meta.od1.i2) del(meta.od1.i2)
# assert conf1.od1.i2 == 2 assert conf1.od1.i2 == 2
# assert conf2.od1.i2 == 1 assert conf2.od1.i2 == 1
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
# del(conf1.od1.i2) del(conf1.od1.i2)
# assert conf1.od1.i2 == conf2.od1.i2 == 1 assert conf1.od1.i2 == conf2.od1.i2 == 1
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
#def test_contexts(): def test_contexts():
# meta = make_description() meta = make_description()
# conf1, conf2 = meta._impl_children conf1, conf2 = meta._impl_children
# assert conf1.od1.i2 == conf2.od1.i2 == 1 assert conf1.od1.i2 == conf2.od1.i2 == 1
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
# meta.set_contexts('od1.i2', 6) meta.setattrs('od1.i2', 6)
# assert meta.od1.i2 == 1 assert meta.od1.i2 == 1
# assert conf1.od1.i2 == conf2.od1.i2 == 6 assert conf1.od1.i2 == conf2.od1.i2 == 6
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user
#def test_find(): def test_find():
# meta = make_description() meta = make_description()
# i2 = meta.unwrap_from_path('od1.i2') i2 = meta.unwrap_from_path('od1.i2')
# assert [i2] == meta.find(byname='i2') assert [i2] == meta.find(byname='i2')
# assert i2 == meta.find_first(byname='i2') assert i2 == meta.find_first(byname='i2')
# assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, 'od1.i2': 1} assert meta.make_dict() == {'od1.i4': 2, 'od1.i1': None, 'od1.i3': None, 'od1.i2': 1}
#def test_meta_meta(): def test_meta_meta():
# meta1 = make_description() meta1 = make_description()
# meta2 = MetaConfig([meta1]) meta2 = MetaConfig([meta1])
# meta2.cfgimpl_get_settings().setowner(owners.meta) meta2.cfgimpl_get_settings().setowner(owners.meta)
# conf1, conf2 = meta1._impl_children conf1, conf2 = meta1._impl_children
# assert conf1.od1.i2 == conf2.od1.i2 == 1 assert conf1.od1.i2 == conf2.od1.i2 == 1
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
# meta2.od1.i2 = 3 meta2.od1.i2 = 3
# assert conf1.od1.i2 == conf2.od1.i2 == 3 assert conf1.od1.i2 == conf2.od1.i2 == 3
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
# meta2.od1.i2 = 3 meta2.od1.i2 = 3
# conf1.od1.i2 = 2 conf1.od1.i2 = 2
# assert conf1.od1.i2 == 2 assert conf1.od1.i2 == 2
# assert conf2.od1.i2 == 3 assert conf2.od1.i2 == 3
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
# meta2.od1.i2 = 4 meta2.od1.i2 = 4
# assert conf1.od1.i2 == 2 assert conf1.od1.i2 == 2
# assert conf2.od1.i2 == 4 assert conf2.od1.i2 == 4
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
# del(meta2.od1.i2) del(meta2.od1.i2)
# assert conf1.od1.i2 == 2 assert conf1.od1.i2 == 2
# assert conf2.od1.i2 == 1 assert conf2.od1.i2 == 1
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is owners.user
# assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default assert conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
# del(conf1.od1.i2) del(conf1.od1.i2)
# assert conf1.od1.i2 == conf2.od1.i2 == 1 assert conf1.od1.i2 == conf2.od1.i2 == 1
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
# meta1.od1.i2 = 6 meta1.od1.i2 = 6
# assert conf1.od1.i2 == conf2.od1.i2 == 6 assert conf1.od1.i2 == conf2.od1.i2 == 6
# assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.meta
#def test_meta_meta_set(): def test_meta_meta_set():
# meta1 = make_description() meta1 = make_description()
# meta2 = MetaConfig([meta1]) meta2 = MetaConfig([meta1])
# meta2.cfgimpl_get_settings().setowner(owners.meta) meta2.cfgimpl_get_settings().setowner(owners.meta)
# conf1, conf2 = meta1._impl_children conf1, conf2 = meta1._impl_children
# meta2.set_contexts('od1.i1', 7) meta2.setattrs('od1.i1', 7)
# assert conf1.od1.i1 == conf2.od1.i1 == 7 assert conf1.od1.i1 == conf2.od1.i1 == 7
# assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
# assert [conf1, conf2] == meta2.find_first_contexts(byname='i1', byvalue=7) assert [conf1, conf2] == meta2.find_firsts(byname='i1', byvalue=7)
# conf1.od1.i1 = 8 conf1.od1.i1 = 8
# assert [conf2] == meta2.find_first_contexts(byname='i1', byvalue=7) assert [conf2] == meta2.find_firsts(byname='i1', byvalue=7)
# assert [conf1] == meta2.find_first_contexts(byname='i1', byvalue=8) assert [conf1] == meta2.find_firsts(byname='i1', byvalue=8)
# raises(AttributeError, "meta2.find_first_contexts(byname='i1', byvalue=10)") raises(AttributeError, "meta2.find_firsts(byname='i1', byvalue=10)")
#def test_not_meta(): def test_not_meta():
# i1 = IntOption('i1', '') i1 = IntOption('i1', '')
# od1 = OptionDescription('od1', '', [i1]) od1 = OptionDescription('od1', '', [i1])
# od2 = OptionDescription('od2', '', [od1]) od2 = OptionDescription('od2', '', [od1])
# conf1 = Config(od2) conf1 = Config(od2)
# conf2 = Config(od2) conf2 = Config(od2)
# meta = MetaConfig([conf1, conf2], False) meta = GroupConfig([conf1, conf2])
# raises(ConfigError, 'meta.od1.i1') raises(ConfigError, 'meta.od1.i1')
# conf1, conf2 = meta._impl_children conf1, conf2 = meta._impl_children
# meta.set_contexts('od1.i1', 7) meta.setattrs('od1.i1', 7)
# assert conf1.od1.i1 == conf2.od1.i1 == 7 assert conf1.od1.i1 == conf2.od1.i1 == 7
# assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is 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
# assert meta.od1._impl_path == 'od1' assert meta.od1._impl_path == 'od1'

21
test/test_multi.py Normal file
View File

@ -0,0 +1,21 @@
# coding: utf-8
import autopath
from tiramisu.value import Multi
from tiramisu.option import IntOption, OptionDescription
from tiramisu.config import Config
from tiramisu.error import ConfigError
import weakref
from py.test import raises
def test_multi():
i = IntOption('int', '', multi=True)
o = OptionDescription('od', '', [i])
c = Config(o)
multi = Multi([1,2,3], weakref.ref(c), i, 'int')
raises(ValueError, "Multi([1,2,3], c, i, 'int')")
raises(ValueError, "Multi(multi, weakref.ref(c), i, 'int')")
assert c is multi._getcontext()
del(c)
raises(ConfigError, "multi._getcontext()")

View File

@ -374,6 +374,9 @@ def test_callback_multi_value():
assert cfg.val2 == ['val'] assert cfg.val2 == ['val']
assert cfg.val3 == ['yes'] assert cfg.val3 == ['yes']
assert cfg.val4 == ['val', 'yes'] assert cfg.val4 == ['val', 'yes']
cfg.val2.append('new')
assert cfg.val1 == ['val']
assert cfg.val2 == ['val', 'new']
def test_callback_multi_list(): def test_callback_multi_list():
@ -467,6 +470,66 @@ def test_callback_master_and_slaves_slave():
assert cfg.val1.val2 == ['val2', 'val2', 'val'] assert cfg.val1.val2 == ['val2', 'val2', 'val']
def test_callback_master_and_slaves_slave_cal():
val3 = StrOption('val3', "", multi=True)
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params={'': ((val3, False),)})
val2 = StrOption('val2', "", multi=True, callback=return_val)
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 == []
assert cfg.val1.val1 == []
assert cfg.val1.val2 == []
cfg.val1.val1 = ['val1']
cfg.val3 = ['val1']
assert cfg.val1.val1 == ['val1']
assert cfg.val1.val2 == ['val']
assert cfg.val1.val1 == ['val1']
assert cfg.val1.val2 == ['val']
del(cfg.val1.val1)
cfg.val1.val2 = ['val']
cfg.val3 = ['val1', 'val2']
assert cfg.val1.val2 == ['val', 'val']
assert cfg.val1.val1 == ['val1', 'val2']
cfg.val1.val2 = ['val1', '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 = ['val1', 'val2', 'val3']
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_slave_list(): def test_callback_master_and_slaves_slave_list():
val1 = StrOption('val1', "", multi=True) val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True, callback=return_list) val2 = StrOption('val2', "", multi=True, callback=return_list)

View File

@ -1,10 +1,11 @@
#from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \ #from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
# OptionDescription # IntOption, OptionDescription
#from tiramisu.config import Config #from tiramisu.config import Config, GroupConfig, MetaConfig
#from tiramisu.setting import owners #from tiramisu.setting import owners
#from tiramisu.storage import delete_session #from tiramisu.storage import delete_session
#from tiramisu.error import ConfigError #from tiramisu.error import ConfigError
#from pickle import dumps, loads #from pickle import dumps, loads
#from py.test import raises
# #
# #
#def return_value(value=None): #def return_value(value=None):
@ -90,6 +91,45 @@
# assert val1 == val2 # assert val1 == val2
# #
# #
#def _diff_conf(cfg1, cfg2):
# attr1 = set(_get_slots(cfg1))
# attr2 = set(_get_slots(cfg2))
# diff1 = attr1 - attr2
# diff2 = attr2 - attr1
# if diff1 != set():
# raise Exception('more attribute in cfg1 {0}'.format(list(diff1)))
# if diff2 != set():
# raise Exception('more attribute in cfg2 {0}'.format(list(diff2)))
# for attr in attr1:
# if attr in ('_impl_context', '__weakref__'):
# continue
# err1 = False
# err2 = False
# val1 = None
# val2 = None
# try:
# val1 = getattr(cfg1, attr)
# except:
# err1 = True
#
# try:
# val2 = getattr(cfg2, attr)
# except:
# err2 = True
# assert err1 == err2
# if val1 is None:
# assert val1 == val2
# elif attr == '_impl_values':
# assert cfg1.cfgimpl_get_values().get_modified_values() == cfg2.cfgimpl_get_values().get_modified_values()
# elif attr == '_impl_settings':
# assert cfg1.cfgimpl_get_settings().get_modified_properties() == cfg2.cfgimpl_get_settings().get_modified_properties()
# assert cfg1.cfgimpl_get_settings().get_modified_permissives() == cfg2.cfgimpl_get_settings().get_modified_permissives()
# elif attr == '_impl_descr':
# _diff_opt(cfg1.cfgimpl_get_description(), cfg2.cfgimpl_get_description())
# else:
# assert val1 == val2
#
#
#def test_diff_opt(): #def test_diff_opt():
# b = BoolOption('b', '') # b = BoolOption('b', '')
# u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}]) # u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
@ -169,10 +209,7 @@
# cfg._impl_test = True # cfg._impl_test = True
# a = dumps(cfg) # a = dumps(cfg)
# q = loads(a) # q = loads(a)
# _diff_opt(maconfig, q.cfgimpl_get_description()) # _diff_conf(cfg, q)
# assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
# assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
# assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
# try: # try:
# delete_session('29090931') # delete_session('29090931')
# except ConfigError: # except ConfigError:
@ -191,12 +228,9 @@
# cfg.cfgimpl_get_settings()[val1].append('test') # cfg.cfgimpl_get_settings()[val1].append('test')
# a = dumps(cfg) # a = dumps(cfg)
# q = loads(a) # q = loads(a)
# _diff_opt(maconfig, q.cfgimpl_get_description()) # _diff_conf(cfg, q)
# assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
# assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
# assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
# try: # try:
# delete_session('29090931') # delete_session('29090932')
# except ConfigError: # except ConfigError:
# pass # pass
# #
@ -212,15 +246,12 @@
# cfg.val1 = True # cfg.val1 = True
# a = dumps(cfg) # a = dumps(cfg)
# q = loads(a) # q = loads(a)
# _diff_opt(maconfig, q.cfgimpl_get_description()) # _diff_conf(cfg, q)
# assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
# assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
# assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
# q.val1 = False # q.val1 = False
# #assert cfg.val1 is True # #assert cfg.val1 is True
# assert q.val1 is False # assert q.val1 is False
# try: # try:
# delete_session('29090931') # delete_session('29090933')
# except ConfigError: # except ConfigError:
# pass # pass
# #
@ -238,14 +269,94 @@
# cfg.val1 = True # cfg.val1 = True
# a = dumps(cfg) # a = dumps(cfg)
# q = loads(a) # q = loads(a)
# _diff_opt(maconfig, q.cfgimpl_get_description()) # _diff_conf(cfg, q)
# assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
# assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
# assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
# q.val1 = False # q.val1 = False
# nval1 = q.cfgimpl_get_description().val1 # nval1 = q.cfgimpl_get_description().val1
# assert q.getowner(nval1) == owners.newowner # assert q.getowner(nval1) == owners.newowner
# try: # try:
# delete_session('29090931') # delete_session('29090934')
# except ConfigError: # except ConfigError:
# pass # pass
#
#
#def test_state_metaconfig():
# i1 = IntOption('i1', '')
# od1 = OptionDescription('od1', '', [i1])
# od2 = OptionDescription('od2', '', [od1])
# conf1 = Config(od2, session_id='29090935')
# conf1._impl_test = True
# conf2 = Config(od2, session_id='29090936')
# conf2._impl_test = True
# meta = MetaConfig([conf1, conf2], session_id='29090937')
# meta._impl_test = True
# raises(ConfigError, "dumps(meta)")
# try:
# delete_session('29090935')
# delete_session('29090936')
# delete_session('29090937')
# except ConfigError:
# pass
#
#
#def test_state_groupconfig():
# i1 = IntOption('i1', '')
# od1 = OptionDescription('od1', '', [i1])
# od2 = OptionDescription('od2', '', [od1])
# conf1 = Config(od2, session_id='29090935')
# conf1._impl_test = True
# conf2 = Config(od2, session_id='29090936')
# conf2._impl_test = True
# meta = GroupConfig([conf1, conf2], session_id='29090937')
# meta._impl_test = True
# a = dumps(meta)
# q = loads(a)
# _diff_conf(meta, q)
# try:
# delete_session('29090935')
# delete_session('29090936')
# delete_session('29090937')
# except ConfigError:
# pass
#
#
#def test_state_unkown_setting_owner():
# """load an unknow _owner, should create it"""
# assert not 'supernewuser' in owners.__dict__
# loads("""ccopy_reg
#_reconstructor
#p0
#(ctiramisu.setting
#Settings
#p1
#c__builtin__
#object
#p2
#Ntp3
#Rp4
#(dp5
#S'_owner'
#p6
#S'supernewuser'
#p7
#sS'_p_'
#p8
#g0
#(ctiramisu.storage.dictionary.setting
#Settings
#p9
#g2
#Ntp10
#Rp11
#(dp12
#S'_cache'
#p13
#(dp14
#sS'_permissives'
#p15
#(dp16
#sS'_properties'
#p17
#(dp18
#sbsb.
#.""")
# assert 'supernewuser' in owners.__dict__

View File

@ -152,7 +152,10 @@ def carry_out_calculation(option, config, callback, callback_params,
opt) opt)
# get value # get value
try: try:
value = config._getattr(path, force_permissive=True) value = config._getattr(path, force_permissive=True, validate=False)
# convert to list, not modifie this multi
if value.__class__.__name__ == 'Multi':
value = list(value)
except PropertiesOptionError as err: except PropertiesOptionError as err:
if force_permissive: if force_permissive:
continue continue

View File

@ -48,7 +48,7 @@ class SubConfig(object):
:type subpath: `str` with the path name :type subpath: `str` with the path name
""" """
# main option description # main option description
if not isinstance(descr, OptionDescription): if descr is not None and not isinstance(descr, OptionDescription):
raise TypeError(_('descr must be an optiondescription, not {0}' raise TypeError(_('descr must be an optiondescription, not {0}'
).format(type(descr))) ).format(type(descr)))
self._impl_descr = descr self._impl_descr = descr
@ -172,7 +172,7 @@ class SubConfig(object):
def cfgimpl_get_description(self): def cfgimpl_get_description(self):
if self._impl_descr is None: if self._impl_descr is None:
raise ConfigError(_('no option description found for this config' raise ConfigError(_('no option description found for this config'
' (may be metaconfig without meta)')) ' (may be GroupConfig)'))
else: else:
return self._impl_descr return self._impl_descr
@ -459,9 +459,9 @@ class SubConfig(object):
return context_descr.impl_get_path_by_opt(descr) return context_descr.impl_get_path_by_opt(descr)
class CommonConfig(SubConfig): class _CommonConfig(SubConfig):
"abstract base class for the Config and the MetaConfig" "abstract base class for the Config, GroupConfig and the MetaConfig"
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta') __slots__ = ('_impl_values', '_impl_settings', '_impl_meta', '_impl_test')
def _impl_build_all_caches(self): def _impl_build_all_caches(self):
if not self.cfgimpl_get_description().impl_already_build_caches(): if not self.cfgimpl_get_description().impl_already_build_caches():
@ -503,7 +503,8 @@ class CommonConfig(SubConfig):
return None return None
def cfgimpl_get_meta(self): def cfgimpl_get_meta(self):
return self._impl_meta if self._impl_meta is not None:
return self._impl_meta()
# information # information
def impl_set_information(self, key, value): def impl_set_information(self, key, value):
@ -521,42 +522,15 @@ class CommonConfig(SubConfig):
""" """
return self._impl_values.get_information(key, default) return self._impl_values.get_information(key, default)
# ----- state
# ____________________________________________________________
class Config(CommonConfig):
"main configuration management entry"
__slots__ = ('__weakref__', '_impl_test')
def __init__(self, descr, session_id=None, persistent=False):
""" Configuration option management master class
:param descr: describes the configuration schema
:type descr: an instance of ``option.OptionDescription``
:param context: the current root config
:type context: `Config`
:param session_id: session ID is import with persistent Config to
retrieve good session
:type session_id: `str`
:param persistent: if persistent, don't delete storage when leaving
:type persistent: `boolean`
"""
settings, values = get_storages(self, session_id, persistent)
self._impl_settings = Settings(self, settings)
self._impl_values = Values(self, values)
super(Config, self).__init__(descr, weakref.ref(self))
self._impl_build_all_caches()
self._impl_meta = None
#undocumented option used only in test script
self._impl_test = False
def __getstate__(self): def __getstate__(self):
if self._impl_meta is not None: if self._impl_meta is not None:
raise ConfigError('cannot serialize Config with meta') raise ConfigError('cannot serialize Config with MetaConfig')
slots = set() slots = set()
for subclass in self.__class__.__mro__: for subclass in self.__class__.__mro__:
if subclass is not object: if subclass is not object:
slots.update(subclass.__slots__) slots.update(subclass.__slots__)
slots -= frozenset(['_impl_context', '__weakref__']) slots -= frozenset(['_impl_context', '_impl_meta', '__weakref__'])
state = {} state = {}
for slot in slots: for slot in slots:
try: try:
@ -583,6 +557,35 @@ class Config(CommonConfig):
storage = get_storage(test=self._impl_test, **state['_storage']) storage = get_storage(test=self._impl_test, **state['_storage'])
self._impl_values._impl_setstate(storage) self._impl_values._impl_setstate(storage)
self._impl_settings._impl_setstate(storage) self._impl_settings._impl_setstate(storage)
self._impl_meta = None
# ____________________________________________________________
class Config(_CommonConfig):
"main configuration management entry"
__slots__ = ('__weakref__', '_impl_test')
def __init__(self, descr, session_id=None, persistent=False):
""" Configuration option management master class
:param descr: describes the configuration schema
:type descr: an instance of ``option.OptionDescription``
:param context: the current root config
:type context: `Config`
:param session_id: session ID is import with persistent Config to
retrieve good session
:type session_id: `str`
:param persistent: if persistent, don't delete storage when leaving
:type persistent: `boolean`
"""
settings, values = get_storages(self, session_id, persistent)
self._impl_settings = Settings(self, settings)
self._impl_values = Values(self, values)
super(Config, self).__init__(descr, weakref.ref(self))
self._impl_build_all_caches()
self._impl_meta = None
#undocumented option used only in test script
self._impl_test = False
def cfgimpl_reset_cache(self, def cfgimpl_reset_cache(self,
only_expired=False, only_expired=False,
@ -593,99 +596,119 @@ class Config(CommonConfig):
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired) self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
#class MetaConfig(CommonConfig): class GroupConfig(_CommonConfig):
# __slots__ = ('_impl_children',) __slots__ = ('_impl_children', '__weakref__')
# def __init__(self, children, meta=True, session_id=None, persistent=False): def __init__(self, children, session_id=None, persistent=False,
# if not isinstance(children, list): _descr=None):
# raise ValueError(_("metaconfig's children must be a list")) if not isinstance(children, list):
# self._impl_descr = None raise ValueError(_("metaconfig's children must be a list"))
# self._impl_path = None self._impl_children = children
# if meta: settings, values = get_storages(self, session_id, persistent)
# for child in children: self._impl_settings = Settings(self, settings)
# if not isinstance(child, CommonConfig): self._impl_values = Values(self, values)
# raise TypeError(_("metaconfig's children " super(GroupConfig, self).__init__(_descr, weakref.ref(self))
# "must be config, not {0}" self._impl_meta = None
# ).format(type(child))) #undocumented option used only in test script
# if self._impl_descr is None: self._impl_test = False
# self._impl_descr = child.cfgimpl_get_description()
# elif not self._impl_descr is child.cfgimpl_get_description():
# raise ValueError(_('all config in metaconfig must '
# 'have the same optiondescription'))
# if child.cfgimpl_get_meta() is not None:
# raise ValueError(_("child has already a metaconfig's"))
# child._impl_meta = self
# self._impl_children = children def cfgimpl_get_children(self):
# settings, values = get_storages(self, session_id, persistent) return self._impl_children
# self._impl_settings = Settings(self, settings)
# self._impl_values = Values(self, values)
# self._impl_meta = None
# def cfgimpl_get_children(self): #def cfgimpl_get_context(self):
# return self._impl_children # "a meta config is a config which has a setting, that is itself"
# return self
#
def cfgimpl_reset_cache(self,
only_expired=False,
only=('values', 'settings')):
if 'values' in only:
self.cfgimpl_get_values().reset_cache(only_expired=only_expired)
if 'settings' in only:
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
for child in self._impl_children:
child.cfgimpl_reset_cache(only_expired=only_expired, only=only)
# def cfgimpl_get_context(self): def setattrs(self, path, value):
# "a meta config is a config wich has a setting, that is itself" """Setattr not in current GroupConfig, but in each children
# return self """
for child in self._impl_children:
try:
if not isinstance(child, GroupConfig):
setattr(child, path, value)
else:
child.setattrs(path, value)
except PropertiesOptionError:
pass
# def cfgimpl_reset_cache(self, def find_firsts(self, byname=None, bypath=None, byvalue=None,
# only_expired=False, type_='path', display_error=True):
# only=('values', 'settings')): """Find first not in current GroupConfig, but in each children
# if 'values' in only: """
# self.cfgimpl_get_values().reset_cache(only_expired=only_expired) ret = []
# if 'settings' in only: #if MetaConfig, all children have same OptionDescription as context
# self.cfgimpl_get_settings().reset_cache(only_expired=only_expired) #so search only one time for all children
# for child in self._impl_children: try:
# child.cfgimpl_reset_cache(only_expired=only_expired, only=only) if bypath is None and byname is not None and \
isinstance(self, MetaConfig):
bypath = self._find(bytype=None, byvalue=None, byname=byname,
first=True, type_='path',
check_properties=False,
display_error=display_error)
byname = None
except AttributeError:
pass
for child in self._impl_children:
try:
if not isinstance(child, MetaConfig):
if bypath is not None:
#if byvalue is None, try if not raise
value = getattr(child, bypath)
if byvalue is not None:
if isinstance(value, Multi):
if byvalue in value:
ret.append(child)
else:
if value == byvalue:
ret.append(child)
else:
ret.append(child)
else:
ret.append(child.find_first(byname=byname,
byvalue=byvalue,
type_=type_,
display_error=False))
else:
ret.extend(child.find_firsts(byname=byname,
bypath=bypath,
byvalue=byvalue,
type_=type_,
display_error=False))
except AttributeError:
pass
return self._find_return_results(ret, display_error)
# def set_contexts(self, path, value):
# for child in self._impl_children:
# try:
# if not isinstance(child, MetaConfig):
# setattr(child, path, value)
# else:
# child.set_contexts(path, value)
# except PropertiesOptionError:
# pass
# def find_first_contexts(self, byname=None, bypath=None, byvalue=None, class MetaConfig(GroupConfig):
# type_='path', display_error=True): __slots__ = tuple()
# ret = []
# try: def __init__(self, children, session_id=None, persistent=False):
# if bypath is None and byname is not None and \ descr = None
# self.cfgimpl_get_description() is not None: for child in children:
# bypath = self._find(bytype=None, byvalue=None, byname=byname, if not isinstance(child, _CommonConfig):
# first=True, type_='path', raise TypeError(_("metaconfig's children "
# check_properties=False, "should be config, not {0}"
# display_error=display_error) ).format(type(child)))
# except ConfigError: if child.cfgimpl_get_meta() is not None:
# pass raise ValueError(_("child has already a metaconfig's"))
# for child in self._impl_children: if descr is None:
# try: descr = child.cfgimpl_get_description()
# if not isinstance(child, MetaConfig): elif not descr is child.cfgimpl_get_description():
# if bypath is not None: raise ValueError(_('all config in metaconfig must '
# if byvalue is not None: 'have the same optiondescription'))
# if getattr(child, bypath) == byvalue: child._impl_meta = weakref.ref(self)
# ret.append(child)
# else: super(MetaConfig, self).__init__(children, session_id, persistent, descr)
# #not raise
# getattr(child, bypath)
# ret.append(child)
# else:
# ret.append(child.find_first(byname=byname,
# byvalue=byvalue,
# type_=type_,
# display_error=False))
# else:
# ret.extend(child.find_first_contexts(byname=byname,
# bypath=bypath,
# byvalue=byvalue,
# type_=type_,
# display_error=False))
# except AttributeError:
# pass
# return self._find_return_results(ret, display_error)
def mandatory_warnings(config): def mandatory_warnings(config):

View File

@ -73,7 +73,7 @@ class Values(object):
else: else:
return value return value
def _getvalue(self, opt, path, validate=True): def _getvalue(self, opt, path):
"""actually retrieves the value """actually retrieves the value
:param opt: the `option.Option()` object :param opt: the `option.Option()` object
@ -82,14 +82,9 @@ class Values(object):
if not self._p_.hasvalue(path): if not self._p_.hasvalue(path):
# if there is no value # if there is no value
value = self._getdefault(opt) value = self._getdefault(opt)
if opt.impl_is_multi():
value = Multi(value, self.context, opt, path, validate)
else: else:
# if there is a value # if there is a value
value = self._p_.getvalue(path) value = self._p_.getvalue(path)
if opt.impl_is_multi() and not isinstance(value, Multi):
# load value so don't need to validate if is not a Multi
value = Multi(value, self.context, opt, path, validate=False)
return value return value
def get_modified_values(self): def get_modified_values(self):
@ -198,7 +193,7 @@ class Values(object):
# ConfigError if properties did not raise. # ConfigError if properties did not raise.
config_error = None config_error = None
force_permissives = None force_permissives = None
# if value is callback and is not set # if value has callback and is not set
# or frozen with force_default_on_freeze # or frozen with force_default_on_freeze
if opt.impl_has_callback() and ( if opt.impl_has_callback() and (
self._is_default_owner(path) or self._is_default_owner(path) or
@ -208,7 +203,7 @@ class Values(object):
if (opt.impl_is_multi() and if (opt.impl_is_multi() and
opt.impl_get_multitype() == multitypes.slave): opt.impl_get_multitype() == multitypes.slave):
masterp = self._get_opt_path(opt.impl_get_master_slaves()) masterp = self._get_opt_path(opt.impl_get_master_slaves())
mastervalue = getattr(context, masterp) mastervalue = context._getattr(masterp, validate=validate)
lenmaster = len(mastervalue) lenmaster = len(mastervalue)
if lenmaster == 0: if lenmaster == 0:
value = [] value = []
@ -240,7 +235,10 @@ class Values(object):
if opt.impl_is_multi(): if opt.impl_is_multi():
value = Multi(value, self.context, opt, path, validate) value = Multi(value, self.context, opt, path, validate)
else: else:
value = self._getvalue(opt, path, validate) value = self._getvalue(opt, path)
if opt.impl_is_multi():
# load value so don't need to validate if is not a Multi
value = Multi(value, self.context, opt, path, validate=validate)
if config_error is None and validate: if config_error is None and validate:
opt.impl_validate(value, context, 'validator' in setting) opt.impl_validate(value, context, 'validator' in setting)
if config_error is None and self._is_default_owner(path) and \ if config_error is None and self._is_default_owner(path) and \
@ -266,10 +264,27 @@ class Values(object):
context = self._getcontext() context = self._getcontext()
opt.impl_validate(value, context, opt.impl_validate(value, context,
'validator' in context.cfgimpl_get_settings()) 'validator' in context.cfgimpl_get_settings())
if opt.impl_is_multi() and not isinstance(value, Multi): if opt.impl_is_multi():
value = Multi(value, self.context, opt, path, setitem=True) value = Multi(value, self.context, opt, path, setitem=True)
# Save old value
if opt.impl_get_multitype() == multitypes.master and \
self._p_.hasvalue(path):
old_value = self._p_.getvalue(path)
old_owner = self._p_.getowner(path, None)
else:
old_value = undefined
old_owner = undefined
self._setvalue(opt, path, value, force_permissive=force_permissive, self._setvalue(opt, path, value, force_permissive=force_permissive,
is_write=is_write) is_write=is_write)
if opt.impl_is_multi() and opt.impl_get_multitype() == multitypes.master:
try:
value._valid_master()
except Exception, err:
if old_value is not undefined:
self._p_.setvalue(path, old_value, old_owner)
else:
self._p_.resetvalue(path)
raise err
def _setvalue(self, opt, path, value, force_permissive=False, def _setvalue(self, opt, path, value, force_permissive=False,
force_properties=None, force_properties=None,
@ -283,6 +298,8 @@ class Values(object):
force_permissive=force_permissive, force_permissive=force_permissive,
force_properties=force_properties) force_properties=force_properties)
owner = context.cfgimpl_get_settings().getowner() owner = context.cfgimpl_get_settings().getowner()
if isinstance(value, Multi):
value = list(value)
self._p_.setvalue(path, value, owner) self._p_.setvalue(path, value, owner)
def getowner(self, opt): def getowner(self, opt):
@ -403,6 +420,8 @@ class Multi(list):
:param opt: the option object that have this Multi value :param opt: the option object that have this Multi value
:param setitem: only if set a value :param setitem: only if set a value
""" """
if isinstance(value, Multi):
raise ValueError(_('{0} is already a Multi ').format(opt._name))
self.opt = opt self.opt = opt
self.path = path self.path = path
if not isinstance(context, weakref.ReferenceType): if not isinstance(context, weakref.ReferenceType):
@ -412,8 +431,9 @@ class Multi(list):
value = [value] value = [value]
if validate and self.opt.impl_get_multitype() == multitypes.slave: if validate and self.opt.impl_get_multitype() == multitypes.slave:
value = self._valid_slave(value, setitem) value = self._valid_slave(value, setitem)
elif validate and self.opt.impl_get_multitype() == multitypes.master: elif not setitem and validate and \
self._valid_master(value) self.opt.impl_get_multitype() == multitypes.master:
self._valid_master()
super(Multi, self).__init__(value) super(Multi, self).__init__(value)
def _getcontext(self): def _getcontext(self):
@ -433,12 +453,10 @@ class Multi(list):
values = context.cfgimpl_get_values() values = context.cfgimpl_get_values()
masterp = context.cfgimpl_get_description().impl_get_path_by_opt( masterp = context.cfgimpl_get_description().impl_get_path_by_opt(
self.opt.impl_get_master_slaves()) self.opt.impl_get_master_slaves())
mastervalue = getattr(context, masterp) mastervalue = context._getattr(masterp, validate=False)
masterlen = len(mastervalue) masterlen = len(mastervalue)
valuelen = len(value) valuelen = len(value)
is_default_owner = not values._is_default_owner(self.path) or setitem if valuelen > masterlen or (valuelen < masterlen and setitem):
if valuelen > masterlen or (valuelen < masterlen and
is_default_owner):
raise SlaveError(_("invalid len for the slave: {0}" raise SlaveError(_("invalid len for the slave: {0}"
" which has {1} as master").format( " which has {1} as master").format(
self.opt.impl_getname(), masterp)) self.opt.impl_getname(), masterp))
@ -455,30 +473,12 @@ class Multi(list):
#else: same len so do nothing #else: same len so do nothing
return value return value
def _valid_master(self, value): def _valid_master(self):
masterlen = len(value) #masterlen = len(value)
values = self._getcontext().cfgimpl_get_values() values = self._getcontext().cfgimpl_get_values()
for slave in self.opt._master_slaves: for slave in self.opt._master_slaves:
path = values._get_opt_path(slave) path = values._get_opt_path(slave)
if not values._is_default_owner(path): Multi(values._getvalue(slave, path), self.context, slave, path)
value_slave = values._getvalue(slave, path)
if len(value_slave) > masterlen:
raise SlaveError(_("invalid len for the master: {0}"
" which has {1} as slave with"
" greater len").format(
self.opt.impl_getname(), slave.impl_getname()))
elif len(value_slave) < masterlen:
for num in range(0, masterlen - len(value_slave)):
if slave.impl_has_callback():
# if callback add a value, but this value will not
# change anymore automaticly (because this value
# has owner)
index = value_slave.__len__()
value_slave.append(
values._getcallback_value(slave, index=index),
force=True)
else:
value_slave.append(undefined, force=True)
def __setitem__(self, index, value): def __setitem__(self, index, value):
self._validate(value, index) self._validate(value, index)
@ -518,16 +518,15 @@ class Multi(list):
dvalue = values._getcallback_value(slave, index=index) dvalue = values._getcallback_value(slave, index=index)
else: else:
dvalue = slave.impl_getdefault_multi() dvalue = slave.impl_getdefault_multi()
old_value = values.getitem(slave, path, old_value = values.getitem(slave, path, validate=False,
validate_properties=False) validate_properties=False)
if len(old_value) < self.__len__(): if len(old_value) + 1 != self.__len__():
values.getitem(slave, path, raise SlaveError(_("invalid len for the slave: {0}"
" which has {1} as master").format(
self.opt._name, self.__len__()))
values.getitem(slave, path, validate=False,
validate_properties=False).append( validate_properties=False).append(
dvalue, force=True) dvalue, force=True)
else:
values.getitem(slave, path,
validate_properties=False)[
index] = dvalue
def sort(self, cmp=None, key=None, reverse=False): def sort(self, cmp=None, key=None, reverse=False):
if self.opt.impl_get_multitype() in [multitypes.slave, if self.opt.impl_get_multitype() in [multitypes.slave,
@ -597,7 +596,7 @@ class Multi(list):
values = context.cfgimpl_get_values() values = context.cfgimpl_get_values()
if not values.is_default_owner(slave): if not values.is_default_owner(slave):
#get multi without valid properties #get multi without valid properties
values.getitem(slave, values.getitem(slave, validate=False,
validate_properties=False validate_properties=False
).pop(index, force=True) ).pop(index, force=True)
#set value without valid properties #set value without valid properties

View File

@ -79,7 +79,7 @@ msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule"
#: tiramisu/option.py:141 tiramisu/value.py:376 #: tiramisu/option.py:141 tiramisu/value.py:376
msgid "information's item not found: {0}" msgid "information's item not found: {0}"
msgstr "aucune config spécifié alors que c'est nécessaire" msgstr "aucune config spécifiée alors que c'est nécessaire"
#: tiramisu/option.py:203 #: tiramisu/option.py:203
msgid "cannot serialize Option, only in OptionDescription" msgid "cannot serialize Option, only in OptionDescription"