key is now always path and change opt by path dictionary storage
This commit is contained in:
parent
707a215a2c
commit
b6bb685ca5
12 changed files with 297 additions and 242 deletions
|
@ -20,13 +20,13 @@ def test_cache():
|
|||
values = c.cfgimpl_get_values()
|
||||
settings = c.cfgimpl_get_settings()
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.u2
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert od1.u2 in values._p_.get_cached('value', c)
|
||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
assert 'u2' in values._p_.get_cached('value', c)
|
||||
assert 'u2' in settings._p_.get_cached('property', c)
|
||||
|
||||
|
||||
def test_cache_reset():
|
||||
|
@ -36,44 +36,44 @@ def test_cache_reset():
|
|||
settings = c.cfgimpl_get_settings()
|
||||
#when change a value
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.u2 = 1
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
#when remove a value
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
del(c.u2)
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
#when add/del property
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_get_settings()[od1.u2].append('test')
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_get_settings()[od1.u2].remove('test')
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
#when enable/disabled property
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_get_settings().append('test')
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_get_settings().remove('test')
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
|
||||
|
||||
def test_cache_reset_multi():
|
||||
|
@ -83,32 +83,32 @@ def test_cache_reset_multi():
|
|||
settings = c.cfgimpl_get_settings()
|
||||
#when change a value
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.u3 = [1]
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
#when append value
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.u3.append(1)
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
#when pop value
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.u3.pop(1)
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
#when remove a value
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
del(c.u3)
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
|
||||
|
||||
def test_reset_cache():
|
||||
|
@ -117,23 +117,23 @@ def test_reset_cache():
|
|||
values = c.cfgimpl_get_values()
|
||||
settings = c.cfgimpl_get_settings()
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_reset_cache()
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
c.u1
|
||||
sleep(1)
|
||||
c.u2
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert od1.u2 in values._p_.get_cached('value', c)
|
||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
assert 'u2' in values._p_.get_cached('value', c)
|
||||
assert 'u2' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_reset_cache()
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert od1.u2 not in values._p_.get_cached('value', c)
|
||||
assert od1.u2 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
assert 'u2' not in values._p_.get_cached('value', c)
|
||||
assert 'u2' not in settings._p_.get_cached('property', c)
|
||||
|
||||
|
||||
def test_reset_cache_only_expired():
|
||||
|
@ -142,22 +142,22 @@ def test_reset_cache_only_expired():
|
|||
values = c.cfgimpl_get_values()
|
||||
settings = c.cfgimpl_get_settings()
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_reset_cache(True)
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
sleep(1)
|
||||
c.u2
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert od1.u2 in values._p_.get_cached('value', c)
|
||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
assert 'u2' in values._p_.get_cached('value', c)
|
||||
assert 'u2' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_reset_cache(True)
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert od1.u2 in values._p_.get_cached('value', c)
|
||||
assert od1.u2 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
assert 'u2' in values._p_.get_cached('value', c)
|
||||
assert 'u2' in settings._p_.get_cached('property', c)
|
||||
|
||||
|
||||
def test_reset_cache_only():
|
||||
|
@ -166,14 +166,14 @@ def test_reset_cache_only():
|
|||
values = c.cfgimpl_get_values()
|
||||
settings = c.cfgimpl_get_settings()
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_reset_cache(only=('values',))
|
||||
assert od1.u1 not in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' not in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.u1
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' in settings._p_.get_cached('property', c)
|
||||
c.cfgimpl_reset_cache(only=('settings',))
|
||||
assert od1.u1 in values._p_.get_cached('value', c)
|
||||
assert od1.u1 not in settings._p_.get_cached('property', c)
|
||||
assert 'u1' in values._p_.get_cached('value', c)
|
||||
assert 'u1' not in settings._p_.get_cached('property', c)
|
||||
|
|
|
@ -39,6 +39,22 @@ def test_base_config():
|
|||
assert dm._name == 'dummy'
|
||||
|
||||
|
||||
def test_base_path():
|
||||
gcdummy = BoolOption('dummy', 'dummy', default=False)
|
||||
descr = OptionDescription('tiramisu', '', [gcdummy])
|
||||
cfg = Config(descr)
|
||||
assert cfg._impl_path is None
|
||||
base = OptionDescription('config', '', [descr])
|
||||
cfg = Config(base)
|
||||
assert cfg._impl_path is None
|
||||
assert cfg.tiramisu._impl_path == 'tiramisu'
|
||||
nbase = OptionDescription('baseconfig', '', [base])
|
||||
cfg = Config(nbase)
|
||||
assert cfg._impl_path is None
|
||||
assert cfg.config._impl_path == 'config'
|
||||
assert cfg.config.tiramisu._impl_path == 'config.tiramisu'
|
||||
|
||||
|
||||
def test_reset_value():
|
||||
descr = make_description()
|
||||
cfg = Config(descr)
|
||||
|
|
|
@ -164,3 +164,9 @@ def test_not_meta():
|
|||
meta.set_contexts('od1.i1', 7)
|
||||
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||
assert conf1.getowner('od1.i1') is conf2.getowner('od1.i1') is owners.user
|
||||
|
||||
|
||||
def test_meta_path():
|
||||
meta = make_description()
|
||||
assert meta._impl_path is None
|
||||
assert meta.od1._impl_path == 'od1'
|
||||
|
|
|
@ -494,7 +494,7 @@ def test_callback_hidden():
|
|||
od2 = OptionDescription('od2', '', [opt2])
|
||||
maconfig = OptionDescription('rootconfig', '', [od1, od2])
|
||||
cfg = Config(maconfig)
|
||||
cfg.cfgimpl_get_settings().set_permissive(('hidden',))
|
||||
cfg.cfgimpl_get_settings().setpermissive(('hidden',))
|
||||
cfg.read_write()
|
||||
raises(PropertiesOptionError, 'cfg.od1.opt1')
|
||||
cfg.od2.opt2
|
||||
|
|
|
@ -333,15 +333,15 @@ def test_reset_properties():
|
|||
setting.reset()
|
||||
assert setting._p_.get_properties(cfg) == {}
|
||||
setting[option].append('test')
|
||||
assert setting._p_.get_properties(cfg) == {option: set(('test',))}
|
||||
assert setting._p_.get_properties(cfg) == {'gc.dummy': set(('test',))}
|
||||
setting.reset()
|
||||
assert setting._p_.get_properties(cfg) == {option: set(('test',))}
|
||||
assert setting._p_.get_properties(cfg) == {'gc.dummy': set(('test',))}
|
||||
setting.append('frozen')
|
||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), option: set(('test',))}
|
||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), 'gc.dummy': set(('test',))}
|
||||
setting.reset(option)
|
||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator'))}
|
||||
setting[option].append('test')
|
||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), option: set(('test',))}
|
||||
assert setting._p_.get_properties(cfg) == {None: set(('frozen', 'expire', 'validator')), 'gc.dummy': set(('test',))}
|
||||
setting.reset(all_properties=True)
|
||||
assert setting._p_.get_properties(cfg) == {}
|
||||
raises(ValueError, 'setting.reset(all_properties=True, opt=option)')
|
||||
|
|
|
@ -21,7 +21,7 @@ def test_permissive():
|
|||
except PropertiesOptionError, err:
|
||||
props = err.proptype
|
||||
assert props == ['disabled']
|
||||
setting.set_permissive(('disabled',))
|
||||
setting.setpermissive(('disabled',))
|
||||
props = []
|
||||
try:
|
||||
config.u1
|
||||
|
@ -50,7 +50,7 @@ def test_permissive_mandatory():
|
|||
except PropertiesOptionError, err:
|
||||
props = err.proptype
|
||||
assert props == ['disabled', 'mandatory']
|
||||
setting.set_permissive(('mandatory', 'disabled',))
|
||||
setting.setpermissive(('mandatory', 'disabled',))
|
||||
setting.append('permissive')
|
||||
config.u1
|
||||
setting.remove('permissive')
|
||||
|
@ -66,7 +66,7 @@ def test_permissive_frozen():
|
|||
config = Config(descr)
|
||||
setting = config.cfgimpl_get_settings()
|
||||
config.read_write()
|
||||
setting.set_permissive(('frozen', 'disabled',))
|
||||
setting.setpermissive(('frozen', 'disabled',))
|
||||
try:
|
||||
config.u1 = 1
|
||||
except PropertiesOptionError, err:
|
||||
|
|
|
@ -35,15 +35,16 @@ def gen_id(config):
|
|||
|
||||
class SubConfig(BaseInformation):
|
||||
"sub configuration management entry"
|
||||
__slots__ = ('_impl_context', '_impl_descr')
|
||||
__slots__ = ('_impl_context', '_impl_descr', '_impl_path')
|
||||
|
||||
def __init__(self, descr, context):
|
||||
def __init__(self, descr, context, subpath=None):
|
||||
""" 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`
|
||||
:type subpath: `str` with the path name
|
||||
"""
|
||||
# main option description
|
||||
if not isinstance(descr, OptionDescription):
|
||||
|
@ -54,6 +55,7 @@ class SubConfig(BaseInformation):
|
|||
if not isinstance(context, SubConfig):
|
||||
raise ValueError('context must be a SubConfig')
|
||||
self._impl_context = context
|
||||
self._impl_path = subpath
|
||||
|
||||
def cfgimpl_reset_cache(self, only_expired=False, only=('values',
|
||||
'settings')):
|
||||
|
@ -183,7 +185,11 @@ class SubConfig(BaseInformation):
|
|||
return homeconfig.__setattr__(name, value)
|
||||
child = getattr(self.cfgimpl_get_description(), name)
|
||||
if not isinstance(child, SymLinkOption):
|
||||
self.cfgimpl_get_values().setitem(child, value,
|
||||
if self._impl_path is None:
|
||||
path = name
|
||||
else:
|
||||
path = self._impl_path + '.' + name
|
||||
self.cfgimpl_get_values().setitem(child, value, path,
|
||||
force_permissive=force_permissive)
|
||||
else:
|
||||
context = self.cfgimpl_get_context()
|
||||
|
@ -193,7 +199,7 @@ class SubConfig(BaseInformation):
|
|||
|
||||
def __delattr__(self, name):
|
||||
child = getattr(self.cfgimpl_get_description(), name)
|
||||
del(self.cfgimpl_get_values()[child])
|
||||
self.cfgimpl_get_values().__delitem__(child)
|
||||
|
||||
def __getattr__(self, name):
|
||||
return self._getattr(name)
|
||||
|
@ -222,6 +228,10 @@ class SubConfig(BaseInformation):
|
|||
return object.__getattribute__(self, name)
|
||||
opt_or_descr = getattr(self.cfgimpl_get_description(), name)
|
||||
# symlink options
|
||||
if self._impl_path is None:
|
||||
subpath = name
|
||||
else:
|
||||
subpath = self._impl_path + '.' + name
|
||||
if isinstance(opt_or_descr, SymLinkOption):
|
||||
context = self.cfgimpl_get_context()
|
||||
path = context.cfgimpl_get_description().impl_get_path_by_opt(
|
||||
|
@ -231,12 +241,13 @@ class SubConfig(BaseInformation):
|
|||
force_permissive=force_permissive)
|
||||
elif isinstance(opt_or_descr, OptionDescription):
|
||||
self.cfgimpl_get_settings().validate_properties(
|
||||
opt_or_descr, True, False, force_permissive=force_permissive,
|
||||
opt_or_descr, True, False, path=subpath,
|
||||
force_permissive=force_permissive,
|
||||
force_properties=force_properties)
|
||||
return SubConfig(opt_or_descr, self.cfgimpl_get_context())
|
||||
return SubConfig(opt_or_descr, self.cfgimpl_get_context(), subpath)
|
||||
else:
|
||||
return self.cfgimpl_get_values().getitem(
|
||||
opt_or_descr,
|
||||
opt_or_descr, path=subpath,
|
||||
validate=validate,
|
||||
force_properties=force_properties,
|
||||
force_permissive=force_permissive)
|
||||
|
@ -555,6 +566,7 @@ class MetaConfig(CommonConfig):
|
|||
if not isinstance(children, list):
|
||||
raise ValueError(_("metaconfig's children must be a list"))
|
||||
self._impl_descr = None
|
||||
self._impl_path = None
|
||||
if meta:
|
||||
for child in children:
|
||||
if not isinstance(child, CommonConfig):
|
||||
|
|
|
@ -152,24 +152,25 @@ populate_multitypes()
|
|||
|
||||
class Property(object):
|
||||
"a property is responsible of the option's value access rules"
|
||||
__slots__ = ('_setting', '_properties', '_opt')
|
||||
__slots__ = ('_setting', '_properties', '_opt', '_path')
|
||||
|
||||
def __init__(self, setting, prop, opt=None):
|
||||
def __init__(self, setting, prop, opt=None, path=None):
|
||||
self._opt = opt
|
||||
self._path = path
|
||||
self._setting = setting
|
||||
self._properties = prop
|
||||
|
||||
def append(self, propname):
|
||||
self._properties.add(propname)
|
||||
self._setting._setproperties(self._properties, self._opt)
|
||||
self._setting._setproperties(self._properties, self._opt, self._path)
|
||||
|
||||
def remove(self, propname):
|
||||
if propname in self._properties:
|
||||
self._properties.remove(propname)
|
||||
self._setting._setproperties(self._properties, self._opt)
|
||||
self._setting._setproperties(self._properties, self._opt, self._path)
|
||||
|
||||
def reset(self):
|
||||
self._setting.reset(opt=self._opt)
|
||||
self._setting.reset(path=self._path)
|
||||
|
||||
def __contains__(self, propname):
|
||||
return propname in self._properties
|
||||
|
@ -200,15 +201,6 @@ class Settings(object):
|
|||
self._p_ = __import__(import_lib, globals(), locals(), ['Settings'],
|
||||
-1).Settings(storage)
|
||||
|
||||
def _getkey(self, opt):
|
||||
if self._p_.key_is_path:
|
||||
if opt is None:
|
||||
return '_none'
|
||||
else:
|
||||
return self._get_opt_path(opt)
|
||||
else:
|
||||
return opt
|
||||
|
||||
#____________________________________________________________
|
||||
# properties methods
|
||||
def __contains__(self, propname):
|
||||
|
@ -219,7 +211,14 @@ class Settings(object):
|
|||
return str(list(self._getproperties()))
|
||||
|
||||
def __getitem__(self, opt):
|
||||
return Property(self, self._getproperties(opt), opt)
|
||||
if opt is None:
|
||||
path = None
|
||||
else:
|
||||
path = self._get_opt_path(opt)
|
||||
return self._getitem(opt, path)
|
||||
|
||||
def _getitem(self, opt, path):
|
||||
return Property(self, self._getproperties(opt, path), opt, path)
|
||||
|
||||
def __setitem__(self, opt, value):
|
||||
raise ValueError('you must only append/remove properties')
|
||||
|
@ -231,26 +230,32 @@ class Settings(object):
|
|||
if all_properties:
|
||||
self._p_.reset_all_propertives()
|
||||
else:
|
||||
self._p_.reset_properties(self._getkey(opt))
|
||||
if opt is None:
|
||||
path = None
|
||||
else:
|
||||
path = self._get_opt_path(opt)
|
||||
self._p_.reset_properties(path)
|
||||
self.context.cfgimpl_reset_cache()
|
||||
|
||||
def _getproperties(self, opt=None, is_apply_req=True):
|
||||
def _getproperties(self, opt=None, path=None, is_apply_req=True):
|
||||
if opt is None:
|
||||
props = self._p_.getproperties(self._getkey(opt), default_properties)
|
||||
props = self._p_.getproperties(path, default_properties)
|
||||
else:
|
||||
if path is None:
|
||||
raise ValueError(_('if opt is not None, path should not be None in _getproperties'))
|
||||
ntime = None
|
||||
if self._p_.hascache('property', self._getkey(opt)):
|
||||
if self._p_.hascache('property', path):
|
||||
ntime = time()
|
||||
is_cached, props = self._p_.getcache('property', self._getkey(opt), ntime)
|
||||
is_cached, props = self._p_.getcache('property', path, ntime)
|
||||
if is_cached:
|
||||
return props
|
||||
if is_apply_req:
|
||||
self.apply_requires(opt)
|
||||
props = self._p_.getproperties(self._getkey(opt), opt._properties)
|
||||
self.apply_requires(opt, path)
|
||||
props = self._p_.getproperties(path, opt._properties)
|
||||
if 'expire' in self:
|
||||
if ntime is None:
|
||||
ntime = time()
|
||||
self._p_.setcache('property', self._getkey(opt), props, ntime + expires_time)
|
||||
self._p_.setcache('property', path, props, ntime + expires_time)
|
||||
return props
|
||||
|
||||
def append(self, propname):
|
||||
|
@ -261,21 +266,21 @@ class Settings(object):
|
|||
"deletes property propname in the Config's properties attribute"
|
||||
Property(self, self._getproperties()).remove(propname)
|
||||
|
||||
def _setproperties(self, properties, opt=None):
|
||||
def _setproperties(self, properties, opt, path):
|
||||
"""save properties for specified opt
|
||||
(never save properties if same has option properties)
|
||||
"""
|
||||
if opt is None:
|
||||
self._p_.setproperties(self._getkey(opt), properties)
|
||||
self._p_.setproperties(path, properties)
|
||||
else:
|
||||
if set(opt._properties) == properties:
|
||||
self._p_.reset_properties(self._getkey(opt))
|
||||
self._p_.reset_properties(path)
|
||||
else:
|
||||
self._p_.setproperties(self._getkey(opt), properties)
|
||||
self._p_.setproperties(path, properties)
|
||||
self.context.cfgimpl_reset_cache()
|
||||
|
||||
#____________________________________________________________
|
||||
def validate_properties(self, opt_or_descr, is_descr, is_write,
|
||||
def validate_properties(self, opt_or_descr, is_descr, is_write, path,
|
||||
value=None, force_permissive=False,
|
||||
force_properties=None):
|
||||
"""
|
||||
|
@ -291,9 +296,9 @@ class Settings(object):
|
|||
property)
|
||||
"""
|
||||
# opt properties
|
||||
properties = copy(self._getproperties(opt_or_descr))
|
||||
properties = copy(self._getproperties(opt_or_descr, path))
|
||||
# remove opt permissive
|
||||
properties -= self._p_.getpermissive(self._getkey(opt_or_descr))
|
||||
properties -= self._p_.getpermissive(path)
|
||||
# remove global permissive if need
|
||||
self_properties = copy(self._getproperties())
|
||||
if force_permissive is True or 'permissive' in self_properties:
|
||||
|
@ -332,11 +337,10 @@ class Settings(object):
|
|||
"").format(opt_or_descr._name,
|
||||
str(props)), props)
|
||||
|
||||
# XXX should rename it to setpermissive, but kept for retro compatibility
|
||||
def set_permissive(self, permissive, opt=None):
|
||||
def setpermissive(self, permissive, path=None):
|
||||
if not isinstance(permissive, tuple):
|
||||
raise TypeError(_('permissive must be a tuple'))
|
||||
self._p_.setpermissive(self._getkey(opt), permissive)
|
||||
self._p_.setpermissive(path, permissive)
|
||||
|
||||
#____________________________________________________________
|
||||
def setowner(self, owner):
|
||||
|
@ -369,28 +373,27 @@ class Settings(object):
|
|||
else:
|
||||
self._p_.reset_all_cache('property')
|
||||
|
||||
def apply_requires(self, opt):
|
||||
def apply_requires(self, opt, path):
|
||||
"carries out the jit (just in time requirements between options"
|
||||
if opt._requires is None:
|
||||
return
|
||||
|
||||
# filters the callbacks
|
||||
setting = Property(self, self._getproperties(opt, False), opt)
|
||||
setting = Property(self, self._getproperties(opt, path, False), opt, path=path)
|
||||
descr = self.context.cfgimpl_get_description()
|
||||
optpath = descr.impl_get_path_by_opt(opt)
|
||||
for requires in opt._requires:
|
||||
matches = False
|
||||
for require in requires:
|
||||
option, expected, action, inverse, \
|
||||
transitive, same_action = require
|
||||
path = descr.impl_get_path_by_opt(option)
|
||||
if path == optpath or path.startswith(optpath + '.'):
|
||||
reqpath = self._get_opt_path(option)
|
||||
if reqpath == path or reqpath.startswith(path + '.'):
|
||||
raise RequirementError(_("malformed requirements "
|
||||
"imbrication detected for option:"
|
||||
" '{0}' with requirement on: "
|
||||
"'{1}'").format(optpath, path))
|
||||
"'{1}'").format(path, reqpath))
|
||||
try:
|
||||
value = self.context._getattr(path, force_permissive=True)
|
||||
value = self.context._getattr(reqpath, force_permissive=True)
|
||||
except PropertiesOptionError, err:
|
||||
if not transitive:
|
||||
continue
|
||||
|
@ -400,14 +403,14 @@ class Settings(object):
|
|||
"requirement's property "
|
||||
"error: "
|
||||
"{1} {2}").format(opt._name,
|
||||
path,
|
||||
reqpath,
|
||||
properties))
|
||||
# transitive action, force expected
|
||||
value = expected[0]
|
||||
inverse = False
|
||||
except AttributeError:
|
||||
raise AttributeError(_("required option not found: "
|
||||
"{0}").format(path))
|
||||
"{0}").format(reqpath))
|
||||
if (not inverse and
|
||||
value in expected or
|
||||
inverse and value not in expected):
|
||||
|
|
|
@ -32,21 +32,21 @@ class Settings(Cache):
|
|||
super(Settings, self).__init__()
|
||||
|
||||
# propertives
|
||||
def setproperties(self, opt, properties):
|
||||
self._properties[opt] = properties
|
||||
def setproperties(self, path, properties):
|
||||
self._properties[path] = properties
|
||||
|
||||
def getproperties(self, opt, default_properties):
|
||||
return self._properties.get(opt, set(default_properties))
|
||||
def getproperties(self, path, default_properties):
|
||||
return self._properties.get(path, set(default_properties))
|
||||
|
||||
def hasproperties(self, opt):
|
||||
return opt in self._properties
|
||||
def hasproperties(self, path):
|
||||
return path in self._properties
|
||||
|
||||
def reset_all_propertives(self):
|
||||
self._properties.clear()
|
||||
|
||||
def reset_properties(self, opt):
|
||||
def reset_properties(self, path):
|
||||
try:
|
||||
del(self._properties[opt])
|
||||
del(self._properties[path])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
@ -54,8 +54,8 @@ class Settings(Cache):
|
|||
return self._properties
|
||||
|
||||
# permissive
|
||||
def setpermissive(self, opt, permissive):
|
||||
self._permissives[opt] = frozenset(permissive)
|
||||
def setpermissive(self, path, permissive):
|
||||
self._permissives[path] = frozenset(permissive)
|
||||
|
||||
def getpermissive(self, opt=None):
|
||||
return self._permissives.get(opt, frozenset())
|
||||
def getpermissive(self, path=None):
|
||||
return self._permissives.get(path, frozenset())
|
||||
|
|
|
@ -36,22 +36,22 @@ class Cache(object):
|
|||
def __init__(self):
|
||||
self._cache = {}
|
||||
|
||||
def setcache(self, cache_type, opt, val, time):
|
||||
self._cache[opt] = (val, time)
|
||||
def setcache(self, cache_type, path, val, time):
|
||||
self._cache[path] = (val, time)
|
||||
|
||||
def getcache(self, cache_type, opt, exp):
|
||||
value, created = self._cache[opt]
|
||||
def getcache(self, cache_type, path, exp):
|
||||
value, created = self._cache[path]
|
||||
if exp < created:
|
||||
return True, value
|
||||
return False, None
|
||||
|
||||
def hascache(self, cache_type, opt):
|
||||
""" option is in the cache
|
||||
def hascache(self, cache_type, path):
|
||||
""" path is in the cache
|
||||
|
||||
:param cache_type: value | property
|
||||
:param opt: the key (typically, the option object)
|
||||
:param path: the path's option
|
||||
"""
|
||||
return opt in self._cache
|
||||
return path in self._cache
|
||||
|
||||
def reset_expired_cache(self, cache_type, exp):
|
||||
keys = self._cache.keys()
|
||||
|
@ -66,6 +66,6 @@ class Cache(object):
|
|||
|
||||
def get_cached(self, cache_type, context):
|
||||
"""return all values in a dictionary
|
||||
example: {option1: ('value1', 'time1'), option2: ('value2', 'time2')}
|
||||
example: {'path1': ('value1', 'time1'), 'path2': ('value2', 'time2')}
|
||||
"""
|
||||
return self._cache
|
||||
|
|
|
@ -32,43 +32,43 @@ class Values(Cache):
|
|||
super(Values, self).__init__()
|
||||
|
||||
# value
|
||||
def setvalue(self, opt, value, owner):
|
||||
"""set value for an option
|
||||
def setvalue(self, path, value, owner):
|
||||
"""set value for a path
|
||||
a specified value must be associated to an owner
|
||||
"""
|
||||
self._values[opt] = (owner, value)
|
||||
self._values[path] = (owner, value)
|
||||
|
||||
def getvalue(self, opt):
|
||||
"""get value for an option
|
||||
def getvalue(self, path):
|
||||
"""get value for a path
|
||||
return: only value, not the owner
|
||||
"""
|
||||
return self._values[opt][1]
|
||||
return self._values[path][1]
|
||||
|
||||
def hasvalue(self, opt):
|
||||
"""if opt has a value
|
||||
def hasvalue(self, path):
|
||||
"""if path has a value
|
||||
return: boolean
|
||||
"""
|
||||
return opt in self._values
|
||||
return path in self._values
|
||||
|
||||
def resetvalue(self, opt):
|
||||
def resetvalue(self, path):
|
||||
"""remove value means delete value in storage
|
||||
"""
|
||||
del(self._values[opt])
|
||||
del(self._values[path])
|
||||
|
||||
def get_modified_values(self):
|
||||
"""return all values in a dictionary
|
||||
example: {option1: (owner, 'value1'), option2: (owner, 'value2')}
|
||||
example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
|
||||
"""
|
||||
return self._values
|
||||
|
||||
# owner
|
||||
def setowner(self, opt, owner):
|
||||
"""change owner for an option
|
||||
def setowner(self, path, owner):
|
||||
"""change owner for a path
|
||||
"""
|
||||
self._values[opt] = (owner, self._values[opt][1])
|
||||
self._values[path] = (owner, self._values[path][1])
|
||||
|
||||
def getowner(self, opt, default):
|
||||
"""get owner for an option
|
||||
def getowner(self, path, default):
|
||||
"""get owner for a path
|
||||
return: owner object
|
||||
"""
|
||||
return self._values.get(opt, (default, None))[0]
|
||||
return self._values.get(path, (default, None))[0]
|
||||
|
|
|
@ -46,15 +46,6 @@ class Values(object):
|
|||
self._p_ = __import__(import_lib, globals(), locals(), ['Values'],
|
||||
-1).Values(storage)
|
||||
|
||||
def _getkey(self, opt):
|
||||
"""depends on the storage utility.
|
||||
typically, the option's path in the parent `Config` or `SubConfig`
|
||||
"""
|
||||
if self._p_.key_is_path:
|
||||
return self._get_opt_path(opt)
|
||||
else:
|
||||
return opt
|
||||
|
||||
def _getdefault(self, opt):
|
||||
"""
|
||||
actually retrieves the default value
|
||||
|
@ -71,24 +62,23 @@ class Values(object):
|
|||
else:
|
||||
return value
|
||||
|
||||
def _getvalue(self, opt, validate=True):
|
||||
def _getvalue(self, opt, path, validate=True):
|
||||
"""actually retrieves the value
|
||||
|
||||
:param opt: the `option.Option()` object
|
||||
:returns: the option's value (or the default value if not set)
|
||||
"""
|
||||
key = self._getkey(opt)
|
||||
if not self._p_.hasvalue(key):
|
||||
if not self._p_.hasvalue(path):
|
||||
# if there is no value
|
||||
value = self._getdefault(opt)
|
||||
if opt.impl_is_multi():
|
||||
value = Multi(value, self.context, opt, validate)
|
||||
value = Multi(value, self.context, opt, path, validate)
|
||||
else:
|
||||
# if there is a value
|
||||
value = self._p_.getvalue(key)
|
||||
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, validate=False)
|
||||
value = Multi(value, self.context, opt, path, validate=False)
|
||||
return value
|
||||
|
||||
def get_modified_values(self):
|
||||
|
@ -101,15 +91,20 @@ class Values(object):
|
|||
|
||||
:param opt: the `option.Option()` object
|
||||
"""
|
||||
return self._p_.hasvalue('value', self._getkey(opt))
|
||||
path = self._get_opt_path(opt)
|
||||
self._contains(path)
|
||||
|
||||
def _contains(self, path):
|
||||
return self._p_.hasvalue('value', path)
|
||||
|
||||
def __delitem__(self, opt):
|
||||
"""overrides the builtins `del()` instructions"""
|
||||
self.reset(opt)
|
||||
|
||||
def reset(self, opt):
|
||||
key = self._getkey(opt)
|
||||
if self._p_.hasvalue(key):
|
||||
def reset(self, opt, path=None):
|
||||
if path is None:
|
||||
path = self._get_opt_path(opt)
|
||||
if self._p_.hasvalue(path):
|
||||
setting = self.context.cfgimpl_get_settings()
|
||||
opt.impl_validate(opt.impl_getdefault(), self.context,
|
||||
'validator' in setting)
|
||||
|
@ -118,7 +113,7 @@ class Values(object):
|
|||
opt.impl_get_multitype() == multitypes.master):
|
||||
for slave in opt.impl_get_master_slaves():
|
||||
self.reset(slave)
|
||||
self._p_.resetvalue(key)
|
||||
self._p_.resetvalue(path)
|
||||
|
||||
def _isempty(self, opt, value):
|
||||
"convenience method to know if an option is empty"
|
||||
|
@ -150,30 +145,31 @@ class Values(object):
|
|||
"enables us to use the pythonic dictionnary-like access to values"
|
||||
return self.getitem(opt)
|
||||
|
||||
def getitem(self, opt, validate=True, force_permissive=False,
|
||||
def getitem(self, opt, path=None, validate=True, force_permissive=False,
|
||||
force_properties=None, validate_properties=True):
|
||||
ntime = None
|
||||
key = self._getkey(opt)
|
||||
if self._p_.hascache('value', self._getkey(opt)):
|
||||
if path is None:
|
||||
path = self._get_opt_path(opt)
|
||||
if self._p_.hascache('value', path):
|
||||
ntime = time()
|
||||
is_cached, value = self._p_.getcache('value', key, ntime)
|
||||
is_cached, value = self._p_.getcache('value', path, ntime)
|
||||
if is_cached:
|
||||
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, validate=False)
|
||||
value = Multi(value, self.context, opt, path, validate=False)
|
||||
return value
|
||||
val = self._getitem(opt, validate, force_permissive, force_properties,
|
||||
val = self._getitem(opt, path, validate, force_permissive, force_properties,
|
||||
validate_properties)
|
||||
if 'expire' in self.context.cfgimpl_get_settings() and validate and \
|
||||
validate_properties and force_permissive is False and \
|
||||
force_properties is None:
|
||||
if ntime is None:
|
||||
ntime = time()
|
||||
self._p_.setcache('value', key, val, ntime + expires_time)
|
||||
self._p_.setcache('value', path, val, ntime + expires_time)
|
||||
|
||||
return val
|
||||
|
||||
def _getitem(self, opt, validate, force_permissive, force_properties,
|
||||
def _getitem(self, opt, path, validate, force_permissive, force_properties,
|
||||
validate_properties):
|
||||
# options with callbacks
|
||||
setting = self.context.cfgimpl_get_settings()
|
||||
|
@ -181,7 +177,7 @@ class Values(object):
|
|||
# if value is callback and is not set
|
||||
# or frozen with force_default_on_freeze
|
||||
if opt.impl_has_callback() and (
|
||||
self.is_default_owner(opt) or
|
||||
self._is_default_owner(path) or
|
||||
(is_frozen and 'force_default_on_freeze' in setting[opt])):
|
||||
no_value_slave = False
|
||||
if (opt.impl_is_multi() and
|
||||
|
@ -200,53 +196,55 @@ class Values(object):
|
|||
if not isinstance(value, list):
|
||||
value = [value for i in range(lenmaster)]
|
||||
if opt.impl_is_multi():
|
||||
value = Multi(value, self.context, opt, validate)
|
||||
value = Multi(value, self.context, opt, path, validate)
|
||||
# suppress value if already set
|
||||
self.reset(opt)
|
||||
self.reset(opt, path)
|
||||
# frozen and force default
|
||||
elif is_frozen and 'force_default_on_freeze' in setting[opt]:
|
||||
value = self._getdefault(opt)
|
||||
if opt.impl_is_multi():
|
||||
value = Multi(value, self.context, opt, validate)
|
||||
value = Multi(value, self.context, opt, path, validate)
|
||||
else:
|
||||
value = self._getvalue(opt, validate)
|
||||
value = self._getvalue(opt, path, validate)
|
||||
if validate:
|
||||
opt.impl_validate(value, self.context, 'validator' in setting)
|
||||
if self.is_default_owner(opt) and \
|
||||
if self._is_default_owner(path) and \
|
||||
'force_store_value' in setting[opt]:
|
||||
self.setitem(opt, value, is_write=False)
|
||||
self.setitem(opt, value, path, is_write=False)
|
||||
if validate_properties:
|
||||
setting.validate_properties(opt, False, False, value=value,
|
||||
setting.validate_properties(opt, False, False, value=value, path=path,
|
||||
force_permissive=force_permissive,
|
||||
force_properties=force_properties)
|
||||
return value
|
||||
|
||||
def __setitem__(self, opt, value):
|
||||
self.setitem(opt, value)
|
||||
path = self._get_opt_path(opt)
|
||||
self.setitem(opt, value, path)
|
||||
|
||||
def setitem(self, opt, value, force_permissive=False, is_write=True):
|
||||
def setitem(self, opt, value, path, force_permissive=False,
|
||||
is_write=True):
|
||||
# is_write is, for example, used with "force_store_value"
|
||||
# user didn't change value, so not write
|
||||
# valid opt
|
||||
opt.impl_validate(value, self.context,
|
||||
'validator' in self.context.cfgimpl_get_settings())
|
||||
if opt.impl_is_multi() and not isinstance(value, Multi):
|
||||
value = Multi(value, self.context, opt)
|
||||
self._setvalue(opt, value, force_permissive=force_permissive,
|
||||
value = Multi(value, self.context, opt, path)
|
||||
self._setvalue(opt, path, value, force_permissive=force_permissive,
|
||||
is_write=is_write)
|
||||
|
||||
def _setvalue(self, opt, value, force_permissive=False,
|
||||
def _setvalue(self, opt, path, value, force_permissive=False,
|
||||
force_properties=None,
|
||||
is_write=True, validate_properties=True):
|
||||
self.context.cfgimpl_reset_cache()
|
||||
if validate_properties:
|
||||
setting = self.context.cfgimpl_get_settings()
|
||||
setting.validate_properties(opt, False, is_write,
|
||||
value=value,
|
||||
value=value, path=path,
|
||||
force_permissive=force_permissive,
|
||||
force_properties=force_properties)
|
||||
owner = self.context.cfgimpl_get_settings().getowner()
|
||||
self._p_.setvalue(self._getkey(opt), value, owner)
|
||||
self._p_.setvalue(path, value, owner)
|
||||
|
||||
def getowner(self, opt):
|
||||
"""
|
||||
|
@ -257,10 +255,14 @@ class Values(object):
|
|||
"""
|
||||
if isinstance(opt, SymLinkOption):
|
||||
opt = opt._opt
|
||||
owner = self._p_.getowner(self._getkey(opt), owners.default)
|
||||
path = self._get_opt_path(opt)
|
||||
return self._getowner(path)
|
||||
|
||||
def _getowner(self, path):
|
||||
owner = self._p_.getowner(path, owners.default)
|
||||
meta = self.context.cfgimpl_get_meta()
|
||||
if owner is owners.default and meta is not None:
|
||||
owner = meta.cfgimpl_get_values().getowner(opt)
|
||||
owner = meta.cfgimpl_get_values()._getowner(path)
|
||||
return owner
|
||||
|
||||
def setowner(self, opt, owner):
|
||||
|
@ -272,10 +274,15 @@ class Values(object):
|
|||
"""
|
||||
if not isinstance(owner, owners.Owner):
|
||||
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
|
||||
if self.getowner(opt) == owners.default:
|
||||
|
||||
path = self._get_opt_path(opt)
|
||||
self._setowner(path, owner)
|
||||
|
||||
def _setowner(self, path, owner):
|
||||
if self._getowner(path) == owners.default:
|
||||
raise ConfigError(_('no value for {0} cannot change owner to {1}'
|
||||
'').format(opt._name, owner))
|
||||
self._p_.setowner(self._getkey(opt), owner)
|
||||
'').format(path, owner))
|
||||
self._p_.setowner(path, owner)
|
||||
|
||||
def is_default_owner(self, opt):
|
||||
"""
|
||||
|
@ -283,7 +290,11 @@ class Values(object):
|
|||
(not the toplevel config)
|
||||
:return: boolean
|
||||
"""
|
||||
return self.getowner(opt) == owners.default
|
||||
path = self._get_opt_path(opt)
|
||||
return self._is_default_owner(path)
|
||||
|
||||
def _is_default_owner(self, path):
|
||||
return self._getowner(path) == owners.default
|
||||
|
||||
def reset_cache(self, only_expired):
|
||||
"""
|
||||
|
@ -310,15 +321,16 @@ class Values(object):
|
|||
class Multi(list):
|
||||
"""multi options values container
|
||||
that support item notation for the values of multi options"""
|
||||
__slots__ = ('opt', 'context')
|
||||
__slots__ = ('opt', 'path', 'context')
|
||||
|
||||
def __init__(self, value, context, opt, validate=True):
|
||||
def __init__(self, value, context, opt, path, validate=True):
|
||||
"""
|
||||
:param value: the Multi wraps a list value
|
||||
:param context: the home config that has the values
|
||||
:param opt: the option object that have this Multi value
|
||||
"""
|
||||
self.opt = opt
|
||||
self.path = path
|
||||
self.context = context
|
||||
if not isinstance(value, list):
|
||||
value = [value]
|
||||
|
@ -337,7 +349,7 @@ class Multi(list):
|
|||
valuelen = len(value)
|
||||
if valuelen > masterlen or (valuelen < masterlen and
|
||||
not self.context.cfgimpl_get_values(
|
||||
).is_default_owner(self.opt)):
|
||||
)._is_default_owner(self.path)):
|
||||
raise SlaveError(_("invalid len for the slave: {0}"
|
||||
" which has {1} as master").format(
|
||||
self.opt._name, masterp))
|
||||
|
@ -351,8 +363,9 @@ class Multi(list):
|
|||
masterlen = len(value)
|
||||
values = self.context.cfgimpl_get_values()
|
||||
for slave in self.opt._master_slaves:
|
||||
if not values.is_default_owner(slave):
|
||||
value_slave = values._getvalue(slave)
|
||||
path = values._get_opt_path(slave)
|
||||
if not values._is_default_owner(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"
|
||||
|
@ -363,11 +376,11 @@ class Multi(list):
|
|||
value_slave.append(slave.impl_getdefault_multi(),
|
||||
force=True)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
def __setitem__(self, path, value):
|
||||
self._validate(value)
|
||||
#assume not checking mandatory property
|
||||
super(Multi, self).__setitem__(key, value)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
||||
super(Multi, self).__setitem__(path, value)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, path, self)
|
||||
|
||||
def append(self, value, force=False):
|
||||
"""the list value can be updated (appened)
|
||||
|
@ -386,21 +399,26 @@ class Multi(list):
|
|||
value = None
|
||||
self._validate(value)
|
||||
super(Multi, self).append(value)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self, validate_properties=not force)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self, validate_properties=not force)
|
||||
if not force and self.opt.impl_get_multitype() == multitypes.master:
|
||||
for slave in self.opt.impl_get_master_slaves():
|
||||
if not values.is_default_owner(slave):
|
||||
path = values._get_opt_path(slave)
|
||||
if not values._is_default_owner(path):
|
||||
if slave.impl_has_callback():
|
||||
index = self.__len__() - 1
|
||||
dvalue = values._getcallback_value(slave, index=index)
|
||||
else:
|
||||
dvalue = slave.impl_getdefault_multi()
|
||||
old_value = values.getitem(slave, validate_properties=False)
|
||||
old_value = values.getitem(slave, path,
|
||||
validate_properties=False)
|
||||
if len(old_value) < self.__len__():
|
||||
values.getitem(slave, validate_properties=False).append(
|
||||
dvalue, force=True)
|
||||
values.getitem(slave, path,
|
||||
validate_properties=False).append(
|
||||
dvalue, force=True)
|
||||
else:
|
||||
values.getitem(slave, validate_properties=False)[index] = dvalue
|
||||
values.getitem(slave, path,
|
||||
validate_properties=False)[
|
||||
index] = dvalue
|
||||
|
||||
def sort(self, cmp=None, key=None, reverse=False):
|
||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||
|
@ -408,7 +426,7 @@ class Multi(list):
|
|||
raise SlaveError(_("cannot sort multi option {0} if master or slave"
|
||||
"").format(self.opt._name))
|
||||
super(Multi, self).sort(cmp=cmp, key=key, reverse=reverse)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||
|
||||
def reverse(self):
|
||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||
|
@ -416,7 +434,7 @@ class Multi(list):
|
|||
raise SlaveError(_("cannot reverse multi option {0} if master or "
|
||||
"slave").format(self.opt._name))
|
||||
super(Multi, self).reverse()
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||
|
||||
def insert(self, index, obj):
|
||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||
|
@ -424,7 +442,7 @@ class Multi(list):
|
|||
raise SlaveError(_("cannot insert multi option {0} if master or "
|
||||
"slave").format(self.opt._name))
|
||||
super(Multi, self).insert(index, obj)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||
|
||||
def extend(self, iterable):
|
||||
if self.opt.impl_get_multitype() in [multitypes.slave,
|
||||
|
@ -432,7 +450,7 @@ class Multi(list):
|
|||
raise SlaveError(_("cannot extend multi option {0} if master or "
|
||||
"slave").format(self.opt._name))
|
||||
super(Multi, self).extend(iterable)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self)
|
||||
|
||||
def _validate(self, value):
|
||||
if value is not None:
|
||||
|
@ -465,5 +483,5 @@ class Multi(list):
|
|||
).pop(key, force=True)
|
||||
#set value without valid properties
|
||||
ret = super(Multi, self).pop(key)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self, validate_properties=not force)
|
||||
self.context.cfgimpl_get_values()._setvalue(self.opt, self.path, self, validate_properties=not force)
|
||||
return ret
|
||||
|
|
Loading…
Reference in a new issue