ConfigBag optimisation
This commit is contained in:
parent
acdddcfe9c
commit
41c17004d2
@ -246,7 +246,7 @@ def test_reset_cache():
|
||||
api.option('u1').value.get()
|
||||
assert 'u1' in values._p_.get_cached()
|
||||
assert 'u1' in settings._p_.get_cached()
|
||||
c.cfgimpl_reset_cache(None, None, None)
|
||||
c.cfgimpl_reset_cache(None, None)
|
||||
assert 'u1' not in values._p_.get_cached()
|
||||
assert 'u1' not in settings._p_.get_cached()
|
||||
api.option('u1').value.get()
|
||||
@ -258,7 +258,7 @@ def test_reset_cache():
|
||||
assert 'u1' in settings._p_.get_cached()
|
||||
assert 'u2' in values._p_.get_cached()
|
||||
assert 'u2' in settings._p_.get_cached()
|
||||
c.cfgimpl_reset_cache(None, None, None)
|
||||
c.cfgimpl_reset_cache(None, None)
|
||||
assert 'u1' not in values._p_.get_cached()
|
||||
assert 'u1' not in settings._p_.get_cached()
|
||||
assert 'u2' not in values._p_.get_cached()
|
||||
@ -273,7 +273,7 @@ def test_reset_cache():
|
||||
# values = c.cfgimpl_get_values()
|
||||
# api.option('od1.u1').value.get()
|
||||
# assert 'od1.u1' in values._p_.get_cached()
|
||||
# c.od1.cfgimpl_reset_cache(None, None, None)
|
||||
# c.od1.cfgimpl_reset_cache(None, None)
|
||||
# assert 'od1.u1' not in values._p_.get_cached()
|
||||
|
||||
|
||||
|
@ -429,10 +429,10 @@ def test_invalid_option():
|
||||
raises(ValueError, "DomainnameOption('a', '', multi=True, default_multi=1)")
|
||||
|
||||
|
||||
def test_help():
|
||||
stro = StrOption('s', '', multi=True)
|
||||
od1 = OptionDescription('o', '', [stro])
|
||||
od2 = OptionDescription('o', '', [od1])
|
||||
cfg = Config(od2)
|
||||
api = getapi(cfg)
|
||||
api.help(_display=False, _valid=True)
|
||||
#def test_help():
|
||||
# stro = StrOption('s', '', multi=True)
|
||||
# od1 = OptionDescription('o', '', [stro])
|
||||
# od2 = OptionDescription('o', '', [od1])
|
||||
# cfg = Config(od2)
|
||||
# api = getapi(cfg)
|
||||
# api.help(_display=False, _valid=True)
|
||||
|
@ -110,8 +110,8 @@ def test_iter_on_groups():
|
||||
descr = make_description()
|
||||
api = getapi(Config(descr))
|
||||
api.property.read_write()
|
||||
result = list(api.option('creole').list('optiondescription', group_type=groups.family))
|
||||
group_names = [res[0] for res in result]
|
||||
result = api.option('creole').list('optiondescription', group_type=groups.family)
|
||||
group_names = [res.option.name() for res in result]
|
||||
assert group_names == ['general', 'interface1']
|
||||
for i in api.option('creole').list('optiondescription', group_type=groups.family):
|
||||
#test StopIteration
|
||||
@ -123,13 +123,15 @@ def test_iter_on_groups_force_permissive():
|
||||
api = getapi(Config(descr))
|
||||
api.property.read_write()
|
||||
api.permissive.set(frozenset(['hidden']))
|
||||
#result = list(config.creole.general.__iter__(force_permissive=True))
|
||||
group_names = list(api.forcepermissive.option('creole.general').list())
|
||||
result = api.forcepermissive.option('creole.general').list()
|
||||
group_names = [res.option.name() for res in result]
|
||||
ass = ['numero_etab', 'nom_machine', 'nombre_interfaces',
|
||||
'activer_proxy_client', 'mode_conteneur_actif',
|
||||
'mode_conteneur_actif2', 'serveur_ntp', 'time_zone']
|
||||
assert group_names == ass
|
||||
group_names = list(api.option('creole.general').list())
|
||||
# mode_conteneur_actif2 is not visible is not forcepermissive
|
||||
result = api.option('creole.general').list()
|
||||
group_names = [res.option.name() for res in result]
|
||||
ass.remove('mode_conteneur_actif2')
|
||||
assert group_names == ass
|
||||
|
||||
@ -139,8 +141,8 @@ def test_iter_group_on_groups_force_permissive():
|
||||
api = getapi(Config(descr))
|
||||
api.property.read_write()
|
||||
api.permissive.set(frozenset(['hidden']))
|
||||
result = list(api.forcepermissive.option('creole').list(type='optiondescription', group_type=groups.family))
|
||||
group_names = [res[0] for res in result]
|
||||
result = api.forcepermissive.option('creole').list(type='optiondescription', group_type=groups.family)
|
||||
group_names = [res.option.name() for res in result]
|
||||
assert group_names == ['general', 'interface1', 'new']
|
||||
|
||||
|
||||
@ -149,8 +151,8 @@ def test_iter_on_groups_props():
|
||||
api = getapi(Config(descr))
|
||||
api.property.read_write()
|
||||
api.option('creole.interface1').property.add('disabled')
|
||||
result = list(api.option('creole').list(type='optiondescription', group_type=groups.family))
|
||||
group_names = [res[0] for res in result]
|
||||
result = api.option('creole').list(type='optiondescription', group_type=groups.family)
|
||||
group_names = [res.option.name() for res in result]
|
||||
assert group_names == ['general']
|
||||
|
||||
|
||||
|
@ -796,33 +796,32 @@ def test_callback_master_and_slaves_slave_cal():
|
||||
val1 = StrOption('val1', "", multi=True, callback=return_value, callback_params=Params(ParamOption(val3)))
|
||||
val2 = StrOption('val2', "", multi=True, callback=return_val)
|
||||
interface1 = MasterSlaves('val1', '', [val1, val2])
|
||||
#interface1.impl_set_group_type(groups.master)
|
||||
maconfig = OptionDescription('rootconfig', '', [interface1, val3])
|
||||
api = getapi(Config(maconfig))
|
||||
api.property.read_write()
|
||||
#
|
||||
assert api.option('val3').value.get() == []
|
||||
assert api.option('val1.val1').value.get() == []
|
||||
#
|
||||
api.option('val1.val1').value.set(['val1'])
|
||||
api.option('val3').value.set(['val1'])
|
||||
assert api.option('val1.val1').value.get() == ['val1']
|
||||
assert api.option('val1.val2', 0).value.get() == 'val'
|
||||
#
|
||||
api.option('val1.val1').value.reset()
|
||||
api.option('val1.val2', 0).value.set('val')
|
||||
#
|
||||
api.option('val3').value.set(['val1', 'val2'])
|
||||
assert api.option('val1.val2', 0).value.get() == 'val'
|
||||
assert api.option('val1.val2', 1).value.get() == 'val'
|
||||
assert api.option('val1.val1').value.get() == ['val1', 'val2']
|
||||
# len of slave is higher than master's one
|
||||
api.option('val1.val2', 0).value.set('val1')
|
||||
api.option('val1.val2', 1).value.set('val2')
|
||||
api.option('val3').value.set(['val1'])
|
||||
# cannot remove slave's value because master is calculated
|
||||
# so raise
|
||||
if TIRAMISU_VERSION == 2:
|
||||
raises(SlaveError, "api.option('val1.val1').value.get()")
|
||||
raises(SlaveError, "api.option('val1.val2', 0).value.get()")
|
||||
else:
|
||||
assert api.option('val1.val1').value.get() == ['val1']
|
||||
raises(SlaveError, "api.option('val1.val2', 0).value.get()")
|
||||
assert api.option('val1.val1').value.get() == ['val1']
|
||||
raises(SlaveError, "api.option('val1.val2', 0).value.get()")
|
||||
#
|
||||
api.option('val3').value.set(['val1', 'val2', 'val3'])
|
||||
assert api.option('val1.val2', 0).value.get() == 'val1'
|
||||
assert api.option('val1.val2', 1).value.get() == 'val2'
|
||||
@ -1020,6 +1019,7 @@ def test_callback_hidden():
|
||||
api = getapi(Config(maconfig))
|
||||
api.property.read_write()
|
||||
raises(PropertiesOptionError, "api.option('od1.opt1').value.get()")
|
||||
# do not raise, forcepermissive
|
||||
api.option('od2.opt2').value.get()
|
||||
|
||||
|
||||
|
@ -5,7 +5,7 @@ do_autopath()
|
||||
from py.test import raises
|
||||
|
||||
try:
|
||||
from tiramisu.setting import ConfigBag
|
||||
from tiramisu.setting import OptionBag, ConfigBag
|
||||
tiramisu_version = 3
|
||||
except:
|
||||
tiramisu_version = 2
|
||||
@ -151,10 +151,12 @@ def test_slots_config():
|
||||
c = Config(od2)
|
||||
raises(AttributeError, "c.x = 1")
|
||||
raises(AttributeError, "c.cfgimpl_x = 1")
|
||||
if tiramisu_version == 2:
|
||||
sc = c.getattr('a')
|
||||
else:
|
||||
sc = c.getattr('a', None, ConfigBag(c))
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(od2,
|
||||
'a',
|
||||
None,
|
||||
ConfigBag(c))
|
||||
sc = c.getattr('a', option_bag)
|
||||
assert isinstance(sc, SubConfig)
|
||||
raises(AttributeError, "sc.x = 1")
|
||||
raises(AttributeError, "sc.cfgimpl_x = 1")
|
||||
|
512
tiramisu/api.py
512
tiramisu/api.py
@ -22,7 +22,7 @@ from typing import List, Any, Optional, Callable, Union, Dict
|
||||
|
||||
from .error import APIError, ConfigError, SlaveError, PropertiesOptionError
|
||||
from .i18n import _
|
||||
from .setting import ConfigBag, owners, Undefined, undefined, FORBIDDEN_SET_PROPERTIES
|
||||
from .setting import ConfigBag, OptionBag, owners, groups, Undefined, undefined, FORBIDDEN_SET_PROPERTIES
|
||||
from .config import Config, SubConfig, GroupConfig, MetaConfig
|
||||
from .option import ChoiceOption
|
||||
|
||||
@ -102,35 +102,36 @@ class TiramisuHelp:
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + 'unrestraint', _('access to option without property restriction')))
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + 'forcepermissive', _('access to option without verifying permissive property')))
|
||||
root = '[unrestraint.|forcepermissive.]'
|
||||
modules = list(self.registers.keys())
|
||||
modules.sort()
|
||||
for module_name in modules:
|
||||
module = self.registers[module_name]
|
||||
instance_module = module(None)
|
||||
if isinstance(instance_module, TiramisuDispatcher):
|
||||
if _valid and not getdoc(module.__call__): # pragma: no cover
|
||||
raise Exception('unknown doc for {}'.format('__call__'))
|
||||
module_doc = _(getdoc(module.__call__))
|
||||
module_signature = signature(module.__call__)
|
||||
module_args = [str(module_signature.parameters[key]) for key in list(module_signature.parameters.keys())[1:]]
|
||||
module_args = '(' + ', '.join(module_args) + ')'
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + module_name + module_args, module_doc))
|
||||
if hasattr(module, 'subhelp'):
|
||||
instance_submodule = module.subhelp(None, None, None, None, None)
|
||||
options.extend(instance_submodule.help(init=False, space=space + ' ', root=root + module_name + module_args + '.'))
|
||||
else:
|
||||
root = root + '[config(path).]'
|
||||
if isinstance(instance_module, CommonTiramisuOption):
|
||||
if _valid and not getdoc(module): # pragma: no cover
|
||||
raise Exception('unknown doc for {}'.format(module.__class__.__name__))
|
||||
module_doc = _(getdoc(module))
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + module_name, module_doc))
|
||||
if isinstance(instance_module, TiramisuContext):
|
||||
if _valid and not getdoc(module): # pragma: no cover
|
||||
raise Exception('unknown doc for {}'.format(module.__class__.__name__))
|
||||
module_doc = _(getdoc(module))
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + module_name, module_doc))
|
||||
options.extend(instance_module.help(init=False, space=space + ' ', root=root + '{}.'.format(module_name)))
|
||||
if 'registers' in dir(self):
|
||||
modules = list(self.registers.keys())
|
||||
modules.sort()
|
||||
for module_name in modules:
|
||||
module = self.registers[module_name]
|
||||
instance_module = module(None)
|
||||
if isinstance(instance_module, TiramisuDispatcher):
|
||||
if _valid and not getdoc(module.__call__): # pragma: no cover
|
||||
raise Exception('unknown doc for {}'.format('__call__'))
|
||||
module_doc = _(getdoc(module.__call__))
|
||||
module_signature = signature(module.__call__)
|
||||
module_args = [str(module_signature.parameters[key]) for key in list(module_signature.parameters.keys())[1:]]
|
||||
module_args = '(' + ', '.join(module_args) + ')'
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + module_name + module_args, module_doc))
|
||||
if hasattr(module, 'subhelp'):
|
||||
instance_submodule = module.subhelp(None, None, None, None, None)
|
||||
options.extend(instance_submodule.help(init=False, space=space + ' ', root=root + module_name + module_args + '.'))
|
||||
else:
|
||||
root = root + '[config(path).]'
|
||||
if isinstance(instance_module, CommonTiramisuOption):
|
||||
if _valid and not getdoc(module): # pragma: no cover
|
||||
raise Exception('unknown doc for {}'.format(module.__class__.__name__))
|
||||
module_doc = _(getdoc(module))
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + module_name, module_doc))
|
||||
if isinstance(instance_module, TiramisuContext):
|
||||
if _valid and not getdoc(module): # pragma: no cover
|
||||
raise Exception('unknown doc for {}'.format(module.__class__.__name__))
|
||||
module_doc = _(getdoc(module))
|
||||
options.append(self.tmpl_help.format(space, self.icon, root + module_name, module_doc))
|
||||
options.extend(instance_module.help(init=False, space=space + ' ', root=root + '{}.'.format(module_name)))
|
||||
|
||||
funcs = dir(self)
|
||||
funcs.sort()
|
||||
@ -159,20 +160,21 @@ class CommonTiramisu(TiramisuHelp):
|
||||
registers = {}
|
||||
|
||||
def _get_option(self) -> Any:
|
||||
option = self.config_bag.option
|
||||
option = self.option_bag.option
|
||||
if option is None:
|
||||
option = self.subconfig.cfgimpl_get_description().impl_getchild(self._name,
|
||||
self.config_bag,
|
||||
self.subconfig)
|
||||
self.config_bag.option = option
|
||||
self.option_bag.set_option(option,
|
||||
self._path,
|
||||
self.index,
|
||||
self.config_bag)
|
||||
if self.config_bag.setting_properties:
|
||||
self.config_bag.config.cfgimpl_get_settings().validate_properties(self._path,
|
||||
self.index,
|
||||
self.config_bag)
|
||||
self.config_bag.config.cfgimpl_get_settings().validate_properties(self.option_bag)
|
||||
if self.index is not None:
|
||||
if option.impl_is_optiondescription() or not option.impl_is_master_slaves('slave'):
|
||||
raise APIError('index must be set only with a slave option')
|
||||
self._length = self.subconfig.cfgimpl_get_length_slave(option, self.config_bag)
|
||||
self._length = self.subconfig.cfgimpl_get_length_slave(self.option_bag)
|
||||
if self.index >= self._length:
|
||||
raise SlaveError(_('index "{}" is higher than the master length "{}" '
|
||||
'for option "{}"').format(self.index,
|
||||
@ -188,14 +190,16 @@ class CommonTiramisuOption(CommonTiramisu):
|
||||
slave_need_index = True
|
||||
|
||||
def __init__(self,
|
||||
name: Optional[str],
|
||||
path: Optional[str]=None,
|
||||
index: Optional[int]=None,
|
||||
subconfig: Any=None,
|
||||
config_bag: Optional[ConfigBag]=None) -> None:
|
||||
name: str,
|
||||
path: str,
|
||||
index: int,
|
||||
subconfig: Union[Config, SubConfig],
|
||||
config_bag: ConfigBag,
|
||||
option_bag: OptionBag) -> None:
|
||||
self._path = path
|
||||
self.index = index
|
||||
self.config_bag = config_bag
|
||||
self.option_bag = option_bag
|
||||
self._name = name
|
||||
self.subconfig = subconfig
|
||||
if config_bag is not None and self.slave_need_index:
|
||||
@ -310,7 +314,8 @@ class TiramisuOptionOption(CommonTiramisuOption):
|
||||
return option.impl_getrequires()
|
||||
|
||||
def __getattr__(self, name: str) -> Callable:
|
||||
if not self._get_option().impl_is_optiondescription() and name != 'get_option':
|
||||
#if not self._get_option().impl_is_optiondescription() and name != 'get_option':
|
||||
if not self._get_option().impl_is_optiondescription():
|
||||
subkey = '_' + name
|
||||
if subkey in dir(self):
|
||||
func = getattr(self, subkey)
|
||||
@ -327,17 +332,19 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||
"""manager option's owner"""
|
||||
|
||||
def __init__(self,
|
||||
name: Optional[str],
|
||||
path: Optional[str]=None,
|
||||
index: Optional[int]=None,
|
||||
subconfig: Union[None, Config, SubConfig]=None,
|
||||
config_bag: Optional[ConfigBag]=None) -> None:
|
||||
name: str,
|
||||
path: str,
|
||||
index: int,
|
||||
subconfig: Union[Config, SubConfig],
|
||||
config_bag: ConfigBag,
|
||||
option_bag: OptionBag) -> None:
|
||||
|
||||
super().__init__(name,
|
||||
path,
|
||||
index,
|
||||
subconfig,
|
||||
config_bag)
|
||||
config_bag,
|
||||
option_bag)
|
||||
if config_bag:
|
||||
self.values = self.config_bag.config.cfgimpl_get_values()
|
||||
|
||||
@ -345,17 +352,13 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||
def get(self):
|
||||
"""get owner for a specified option"""
|
||||
option = self._get_option()
|
||||
return self.values.getowner(self._path,
|
||||
self.index,
|
||||
self.config_bag)
|
||||
return self.values.getowner(self.option_bag)
|
||||
|
||||
@count
|
||||
def isdefault(self):
|
||||
"""is option has defaut value"""
|
||||
self._get_option()
|
||||
return self.values.is_default_owner(self._path,
|
||||
self.index,
|
||||
self.config_bag)
|
||||
return self.values.is_default_owner(self.option_bag)
|
||||
|
||||
@count
|
||||
def set(self, owner):
|
||||
@ -369,10 +372,8 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||
except AttributeError:
|
||||
owners.addowner(owner)
|
||||
obj_owner = getattr(owners, owner)
|
||||
self.values.setowner(self._path,
|
||||
self.index,
|
||||
obj_owner,
|
||||
self.config_bag)
|
||||
self.values.setowner(obj_owner,
|
||||
self.option_bag)
|
||||
|
||||
|
||||
class TiramisuOptionProperty(CommonTiramisuOption):
|
||||
@ -381,16 +382,18 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||
slave_need_index = False
|
||||
|
||||
def __init__(self,
|
||||
name: Optional[str],
|
||||
path: Optional[str]=None,
|
||||
index: Optional[int]=None,
|
||||
subconfig: Union[None, Config, SubConfig]=None,
|
||||
config_bag: Optional[ConfigBag]=None) -> None:
|
||||
name: str,
|
||||
path: str,
|
||||
index: int,
|
||||
subconfig: Union[Config, SubConfig],
|
||||
config_bag: ConfigBag,
|
||||
option_bag: OptionBag) -> None:
|
||||
super().__init__(name,
|
||||
path,
|
||||
index,
|
||||
subconfig,
|
||||
config_bag)
|
||||
config_bag,
|
||||
option_bag)
|
||||
if config_bag:
|
||||
self.settings = config_bag.config.cfgimpl_get_settings()
|
||||
|
||||
@ -400,12 +403,9 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||
self._get_option()
|
||||
if apply_requires:
|
||||
self._test_slave_index()
|
||||
properties = self.settings.getproperties(self._path,
|
||||
self.index,
|
||||
self.config_bag,
|
||||
apply_requires)
|
||||
if TIRAMISU_VERSION == 2:
|
||||
properties = properties.get()
|
||||
else:
|
||||
self.option_bag.apply_requires = False
|
||||
properties = self.option_bag.properties
|
||||
return set(properties)
|
||||
|
||||
@count
|
||||
@ -415,33 +415,27 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||
if prop in FORBIDDEN_SET_PROPERTIES:
|
||||
raise ConfigError(_('cannot add this property: "{0}"').format(
|
||||
' '.join(prop)))
|
||||
props = self.settings.getproperties(self._path,
|
||||
None,
|
||||
self.config_bag,
|
||||
props = self.settings.getproperties(self.option_bag,
|
||||
apply_requires=False)
|
||||
self.settings.setproperties(self._path,
|
||||
props | {prop},
|
||||
self.config_bag)
|
||||
self.option_bag)
|
||||
|
||||
@count
|
||||
def pop(self, prop):
|
||||
"""remove new property for an option"""
|
||||
self._get_option()
|
||||
props = self.settings.getproperties(self._path,
|
||||
self.index,
|
||||
self.config_bag,
|
||||
props = self.settings.getproperties(self.option_bag,
|
||||
apply_requires=False)
|
||||
self.settings.setproperties(self._path,
|
||||
props - {prop},
|
||||
self.config_bag)
|
||||
self.option_bag)
|
||||
|
||||
@count
|
||||
def reset(self):
|
||||
"""reset all personalised properties"""
|
||||
self._get_option()
|
||||
self.settings.reset(self.config_bag.option,
|
||||
self._path,
|
||||
self.config_bag)
|
||||
self.settings.reset(self.option_bag)
|
||||
|
||||
|
||||
class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||
@ -450,16 +444,18 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||
slave_need_index = False
|
||||
|
||||
def __init__(self,
|
||||
name: Optional[str],
|
||||
path: Optional[str]=None,
|
||||
index: Optional[int]=None,
|
||||
subconfig: Union[None, Config, SubConfig]=None,
|
||||
config_bag: Optional[ConfigBag]=None) -> None:
|
||||
name: str,
|
||||
path: str,
|
||||
index: int,
|
||||
subconfig: Union[Config, SubConfig],
|
||||
config_bag: ConfigBag,
|
||||
option_bag: OptionBag) -> None:
|
||||
super().__init__(name,
|
||||
path,
|
||||
index,
|
||||
subconfig,
|
||||
config_bag)
|
||||
config_bag,
|
||||
option_bag)
|
||||
if config_bag:
|
||||
self.settings = config_bag.config.cfgimpl_get_settings()
|
||||
|
||||
@ -475,21 +471,9 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||
@count
|
||||
def set(self, permissives):
|
||||
"""set permissives value"""
|
||||
if TIRAMISU_VERSION == 2:
|
||||
permissives = tuple(permissives)
|
||||
path = self._path
|
||||
opt = self._opt
|
||||
self.settings.setpermissive(opt=opt,
|
||||
path=path,
|
||||
config_bag=self.config_bag,
|
||||
permissive=permissives)
|
||||
else:
|
||||
path = self._path
|
||||
opt = self._get_option()
|
||||
self.settings.setpermissive(opt=opt,
|
||||
path=path,
|
||||
config_bag=self.config_bag,
|
||||
permissives=permissives)
|
||||
self._get_option()
|
||||
self.settings.setpermissive(self.option_bag,
|
||||
permissives=permissives)
|
||||
|
||||
@count
|
||||
def reset(self):
|
||||
@ -526,12 +510,10 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||
@count
|
||||
def get(self):
|
||||
"""get option's value"""
|
||||
self._get_option()
|
||||
self._test_slave_index()
|
||||
settings = self.config_bag.config.cfgimpl_get_settings()
|
||||
value = self.subconfig.getattr(self._name,
|
||||
self.index,
|
||||
self.config_bag)
|
||||
self.option_bag)
|
||||
#if isinstance(value, Multi):
|
||||
# value = list(value)
|
||||
return value
|
||||
@ -545,35 +527,35 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||
if isinstance(value, list):
|
||||
while undefined in value:
|
||||
idx = value.index(undefined)
|
||||
value[idx] = values.getdefaultvalue(self._path,
|
||||
idx,
|
||||
self.config_bag)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(self.option_bag.option,
|
||||
self.option_bag.path,
|
||||
idx,
|
||||
self.config_bag)
|
||||
value[idx] = values.getdefaultvalue(option_bag)
|
||||
else:
|
||||
if value == undefined:
|
||||
value = values.getdefaultvalue(self._path,
|
||||
self.index,
|
||||
self.config_bag)
|
||||
self.subconfig.setattr(self._name,
|
||||
self.index,
|
||||
value,
|
||||
self.config_bag)
|
||||
value = values.getdefaultvalue(self.option_bag)
|
||||
self.subconfig.setattr(value,
|
||||
self.option_bag)
|
||||
|
||||
@count
|
||||
def _pop(self, index):
|
||||
"""pop value for a master option (only for master option)"""
|
||||
self._get_option()
|
||||
self.config_bag.config.delattr(self._path,
|
||||
index,
|
||||
self.config_bag)
|
||||
if self.option_bag.option.impl_is_symlinkoption():
|
||||
raise TypeError(_("can't delete a SymLinkOption"))
|
||||
self.config_bag.config.cfgimpl_get_values().reset_master(index,
|
||||
self.option_bag,
|
||||
self.subconfig)
|
||||
|
||||
@count
|
||||
def reset(self):
|
||||
"""reset value for a value"""
|
||||
self._get_option()
|
||||
self._test_slave_index()
|
||||
self.config_bag.config.delattr(self._path,
|
||||
self.index,
|
||||
self.config_bag)
|
||||
#self.config_bag.config.delattr(self.option_bag)
|
||||
self.subconfig.delattr(self.option_bag)
|
||||
|
||||
@count
|
||||
def _len_master(self):
|
||||
@ -590,7 +572,7 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||
option = self._get_option()
|
||||
# for example if index is None
|
||||
if '_length' not in vars(self):
|
||||
self._length = self.subconfig.cfgimpl_get_length_slave(option, self.config_bag)
|
||||
self._length = self.subconfig.cfgimpl_get_length_slave(self.option_bag)
|
||||
return self._length
|
||||
|
||||
def __getattr__(self, name: str) -> Callable:
|
||||
@ -608,7 +590,8 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||
@count
|
||||
def _list(self):
|
||||
"""all values available for an option (only for choiceoption)"""
|
||||
return self.config_bag.option.impl_get_values(self.config_bag)
|
||||
self._get_option()
|
||||
return self._get_option().impl_get_values(self.option_bag)
|
||||
|
||||
|
||||
def registers(registers: Dict[str, type], prefix: str) -> None:
|
||||
@ -620,19 +603,27 @@ def registers(registers: Dict[str, type], prefix: str) -> None:
|
||||
|
||||
|
||||
class TiramisuOption(CommonTiramisu):
|
||||
registers = {}
|
||||
def __init__(self,
|
||||
name: Optional[str],
|
||||
path: Optional[str]=None,
|
||||
index: Optional[int]=None,
|
||||
subconfig: Union[None, Config, SubConfig]=None,
|
||||
config_bag: Optional[ConfigBag]=None) -> None:
|
||||
config_bag: Optional[ConfigBag]=None,
|
||||
option_bag: Optional[OptionBag]=None) -> None:
|
||||
self._name = name
|
||||
self.subconfig = subconfig
|
||||
if subconfig == None:
|
||||
raise Exception()
|
||||
self._path = path
|
||||
self.index = index
|
||||
self.config_bag = config_bag
|
||||
self.registers = {}
|
||||
registers(self.registers, self.__class__.__name__)
|
||||
if option_bag:
|
||||
self.option_bag = option_bag
|
||||
else:
|
||||
self.option_bag = OptionBag()
|
||||
if not self.registers:
|
||||
registers(self.registers, self.__class__.__name__)
|
||||
|
||||
def __getattr__(self, subfunc: str) -> Any:
|
||||
if subfunc in self.registers:
|
||||
@ -640,11 +631,14 @@ class TiramisuOption(CommonTiramisu):
|
||||
self._path,
|
||||
self.index,
|
||||
self.subconfig,
|
||||
self.config_bag)
|
||||
self.config_bag,
|
||||
self.option_bag)
|
||||
elif subfunc == 'make_dict' and self._get_option().impl_is_optiondescription():
|
||||
return self._make_dict
|
||||
elif subfunc == 'find' and self._get_option().impl_is_optiondescription():
|
||||
return self._find
|
||||
elif subfunc == 'get' and self._get_option().impl_is_optiondescription():
|
||||
return self._get
|
||||
elif subfunc == 'list' and self._get_option().impl_is_optiondescription():
|
||||
return self._list
|
||||
elif subfunc == 'group_type' and self._get_option().impl_is_optiondescription():
|
||||
@ -659,9 +653,9 @@ class TiramisuOption(CommonTiramisu):
|
||||
withoption=None,
|
||||
fullpath=False):
|
||||
"""return dict with path as key and value for an optiondescription (only for optiondescription)"""
|
||||
self._get_option()
|
||||
return self.config_bag.config.getattr(self._path,
|
||||
None,
|
||||
self.config_bag).make_dict(config_bag=self.config_bag,
|
||||
self.option_bag).make_dict(config_bag=self.config_bag,
|
||||
flatten=flatten,
|
||||
fullpath=fullpath,
|
||||
withoption=withoption,
|
||||
@ -680,19 +674,42 @@ class TiramisuOption(CommonTiramisu):
|
||||
bytype=type,
|
||||
_subpath=self._path,
|
||||
config_bag=self.config_bag):
|
||||
config_bag = self.config_bag.copy('nooption')
|
||||
subconfig, name = config_bag.config.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
subconfig, name = self.config_bag.config.cfgimpl_get_home_by_path(path,
|
||||
self.config_bag)
|
||||
t_option = TiramisuOption(name,
|
||||
path,
|
||||
None, # index for a slave ?
|
||||
subconfig,
|
||||
config_bag)
|
||||
self.config_bag)
|
||||
if first:
|
||||
return t_option
|
||||
ret.append(t_option)
|
||||
return ret
|
||||
|
||||
@count
|
||||
def _get(self, name):
|
||||
self._get_option()
|
||||
current_option = self.option_bag.option.impl_getchild(name,
|
||||
self.config_bag,
|
||||
self.subconfig)
|
||||
path = self.option_bag.path + '.' + name
|
||||
option_bag= OptionBag()
|
||||
option_bag.set_option(current_option,
|
||||
path,
|
||||
None,
|
||||
self.config_bag)
|
||||
if current_option.impl_is_optiondescription():
|
||||
subconfig = self.subconfig.getattr(name,
|
||||
option_bag)
|
||||
else:
|
||||
subconfig = self.subconfig
|
||||
return TiramisuOption(name,
|
||||
path,
|
||||
None,
|
||||
subconfig,
|
||||
self.config_bag,
|
||||
option_bag)
|
||||
|
||||
@count
|
||||
def _group_type(self):
|
||||
"""get type for an optiondescription (only for optiondescription)"""
|
||||
@ -703,26 +720,57 @@ class TiramisuOption(CommonTiramisu):
|
||||
type='all',
|
||||
group_type=None):
|
||||
"""list options in an optiondescription (only for optiondescription)"""
|
||||
if type == 'optiondescription':
|
||||
return self.config_bag.config.getattr(self._path,
|
||||
None,
|
||||
self.config_bag
|
||||
).iter_groups(self.config_bag, group_type)
|
||||
elif type == 'all':
|
||||
return self.config_bag.config.getattr(self._path,
|
||||
None,
|
||||
self.config_bag
|
||||
).cfgimpl_get_children(self.config_bag)
|
||||
else:
|
||||
if type not in ('all', 'optiondescription'):
|
||||
raise APIError(_('unknown list type {}').format(type))
|
||||
if group_type is not None and not isinstance(group_type,
|
||||
groups.GroupType):
|
||||
raise TypeError(_("unknown group_type: {0}").format(group_type))
|
||||
def _filter(opt):
|
||||
if not self.config_bag.force_unrestraint:
|
||||
name = opt.impl_getname()
|
||||
path = subconfig._get_subpath(name)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(opt,
|
||||
path,
|
||||
None,
|
||||
self.config_bag)
|
||||
self.subconfig.getattr(name,
|
||||
option_bag)
|
||||
|
||||
option = self._get_option()
|
||||
name = option.impl_getname()
|
||||
path = self.subconfig._get_subpath(name)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
None,
|
||||
self.config_bag)
|
||||
subconfig = self.subconfig.getattr(name,
|
||||
option_bag)
|
||||
for opt in option.impl_getchildren(self.config_bag):
|
||||
try:
|
||||
subsubconfig = _filter(opt)
|
||||
except PropertiesOptionError:
|
||||
continue
|
||||
if opt.impl_is_optiondescription():
|
||||
if type == 'optiondescription' and \
|
||||
(group_type and opt.impl_get_group_type() != group_type):
|
||||
continue
|
||||
else:
|
||||
if type == 'optiondescription':
|
||||
continue
|
||||
name = opt.impl_getname()
|
||||
yield TiramisuOption(name,
|
||||
subconfig._get_subpath(name),
|
||||
None,
|
||||
subconfig,
|
||||
self.config_bag)
|
||||
|
||||
|
||||
class TiramisuContext(TiramisuHelp):
|
||||
def __init__(self,
|
||||
config_bag: Optional[ConfigBag]) -> None:
|
||||
self.config_bag = config_bag
|
||||
self.registers = {}
|
||||
registers(self.registers, self.__class__.__name__)
|
||||
|
||||
|
||||
class TiramisuContextInformation(TiramisuContext):
|
||||
@ -778,7 +826,8 @@ class TiramisuContextValue(TiramisuContext):
|
||||
def reset(self,
|
||||
path):
|
||||
"""reset value for a GroupConfig or a MetaConfig"""
|
||||
self.config_bag.config.reset(path, self.config_bag)
|
||||
self.config_bag.config.reset(path,
|
||||
self.config_bag)
|
||||
|
||||
@count
|
||||
def exportation(self):
|
||||
@ -789,7 +838,7 @@ class TiramisuContextValue(TiramisuContext):
|
||||
def importation(self, values):
|
||||
"""import values"""
|
||||
self.config_bag.config.cfgimpl_get_values()._p_.importation(values)
|
||||
self.config_bag.config.cfgimpl_reset_cache(None, None, None)
|
||||
self.config_bag.config.cfgimpl_reset_cache(None, None)
|
||||
|
||||
|
||||
class TiramisuContextOwner(TiramisuContext):
|
||||
@ -819,7 +868,10 @@ class TiramisuContextProperty(TiramisuContext):
|
||||
"""set configuration to read only mode"""
|
||||
settings = self.config_bag.config.cfgimpl_get_settings()
|
||||
settings.read_only()
|
||||
self.config_bag.delete('setting_properties')
|
||||
try:
|
||||
del self.config_bag.setting_properties
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
@count
|
||||
def read_write(self):
|
||||
@ -828,7 +880,10 @@ class TiramisuContextProperty(TiramisuContext):
|
||||
settings.read_write()
|
||||
# #FIXME ?
|
||||
settings.set_context_permissive(frozenset(['hidden']))
|
||||
self.config_bag.delete('setting_properties')
|
||||
try:
|
||||
del self.config_bag.setting_properties
|
||||
except AttributeError:
|
||||
pass
|
||||
#/FIXME ?
|
||||
|
||||
@count
|
||||
@ -859,9 +914,7 @@ class TiramisuContextProperty(TiramisuContext):
|
||||
@count
|
||||
def reset(self):
|
||||
"""remove configuration properties"""
|
||||
self.config_bag.config.cfgimpl_get_settings().reset(None,
|
||||
None,
|
||||
None)
|
||||
self.config_bag.config.cfgimpl_get_settings().reset(None)
|
||||
|
||||
@count
|
||||
def exportation(self):
|
||||
@ -872,7 +925,8 @@ class TiramisuContextProperty(TiramisuContext):
|
||||
def importation(self, properties):
|
||||
"""import configuration properties"""
|
||||
self.config_bag.config.cfgimpl_get_settings()._p_.importation(properties)
|
||||
self.config_bag.config.cfgimpl_reset_cache(None, None, None)
|
||||
self.config_bag.config.cfgimpl_reset_cache(None,
|
||||
None)
|
||||
|
||||
|
||||
class TiramisuContextPermissive(TiramisuContext):
|
||||
@ -897,7 +951,8 @@ class TiramisuContextPermissive(TiramisuContext):
|
||||
def importation(self, permissives):
|
||||
"""import configuration permissives"""
|
||||
self.config_bag.config.cfgimpl_get_settings()._pp_.importation(permissives)
|
||||
self.config_bag.config.cfgimpl_reset_cache(None, None, None)
|
||||
self.config_bag.config.cfgimpl_reset_cache(None,
|
||||
None)
|
||||
|
||||
|
||||
|
||||
@ -918,28 +973,28 @@ class TiramisuContextOption(TiramisuContext):
|
||||
bytype=type,
|
||||
#_subpath=self._path,
|
||||
config_bag=self.config_bag):
|
||||
config_bag = self.config_bag.copy('nooption')
|
||||
subconfig, name = config_bag.config.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
subconfig, name = self.config_bag.config.cfgimpl_get_home_by_path(path,
|
||||
self.config_bag)
|
||||
t_option = TiramisuOption(name,
|
||||
path,
|
||||
None, # index for a slave ?
|
||||
subconfig,
|
||||
config_bag)
|
||||
self.config_bag)
|
||||
if first:
|
||||
return t_option
|
||||
ret.append(t_option)
|
||||
return ret
|
||||
|
||||
#@count
|
||||
#def get(self, path):
|
||||
# """"""
|
||||
# config_bag = self.config_bag.copy()
|
||||
# config_bag.validate = False
|
||||
# config_bag.force_unrestraint = True
|
||||
# config_bag.setting_properties = None
|
||||
# return self.config_bag.config.unwrap_from_path(path,
|
||||
# config_bag)
|
||||
@count
|
||||
def get(self, name):
|
||||
option = self.config_bag.config.cfgimpl_get_description().impl_getchild(name,
|
||||
self.config_bag,
|
||||
self.config_bag.config)
|
||||
return TiramisuOption(name,
|
||||
name,
|
||||
None,
|
||||
self.config_bag.config,
|
||||
self.config_bag)
|
||||
|
||||
@count
|
||||
def make_dict(self,
|
||||
@ -960,11 +1015,24 @@ class TiramisuContextOption(TiramisuContext):
|
||||
group_type=None,
|
||||
recursive=False):
|
||||
"""list content of an optiondescription"""
|
||||
# FIXME should return TiramisuOption !!!
|
||||
if group_type is not None and not isinstance(group_type,
|
||||
groups.GroupType):
|
||||
raise TypeError(_("unknown group_type: {0}").format(group_type))
|
||||
|
||||
if type == 'optiondescription':
|
||||
if recursive:
|
||||
raise APIError(_('not implemented yet'))
|
||||
else:
|
||||
return self.config_bag.config.iter_groups(self.config_bag, group_type)
|
||||
if not self.config_bag.force_unrestraint:
|
||||
option = self.config_bag.config.cfgimpl_get_description()
|
||||
for opt in option.impl_getchildren(self.config_bag):
|
||||
if type == 'optiondescription' and not opt.impl_is_optiondescription():
|
||||
continue
|
||||
yield opt.impl_getname()
|
||||
else:
|
||||
# FIXME itergroups !!!
|
||||
return self.config_bag.config.iter_groups(self.config_bag, group_type)
|
||||
elif type == 'all':
|
||||
if group_type:
|
||||
raise APIError(_('not implemented yet'))
|
||||
@ -998,68 +1066,80 @@ class TiramisuDispatcher:
|
||||
pass
|
||||
|
||||
|
||||
class TiramisuAPI(TiramisuHelp):
|
||||
registers = {}
|
||||
|
||||
def __init__(self,
|
||||
config: Union[Config, GroupConfig, MetaConfig, ConfigBag]) -> None:
|
||||
self._config = config
|
||||
if not self.registers:
|
||||
registers(self.registers, 'TiramisuContext')
|
||||
registers(self.registers, 'TiramisuDispatcher')
|
||||
|
||||
def __getattr__(self, subfunc: str) -> Any:
|
||||
if subfunc == 'forcepermissive':
|
||||
if isinstance(self._config, ConfigBag):
|
||||
config = self._config.config
|
||||
force = self._config.force_unrestraint
|
||||
else:
|
||||
config = self._config
|
||||
force = None
|
||||
config_bag = ConfigBag(config=config,
|
||||
force_permissive=True)
|
||||
if force is not None:
|
||||
config_bag.force_unrestraint = force
|
||||
return TiramisuAPI(config_bag)
|
||||
elif subfunc == 'unrestraint':
|
||||
if isinstance(self._config, ConfigBag):
|
||||
config = self._config.config
|
||||
force = self._config.force_permissive
|
||||
else:
|
||||
config = self._config
|
||||
force = None
|
||||
config_bag = ConfigBag(config=config,
|
||||
force_unrestraint=True)
|
||||
if force is not None:
|
||||
config_bag.force_permissive = force
|
||||
return TiramisuAPI(config_bag)
|
||||
elif subfunc in self.registers:
|
||||
if not isinstance(self._config, ConfigBag):
|
||||
config_bag = ConfigBag(config=self._config)
|
||||
else:
|
||||
config_bag = self._config
|
||||
return self.registers[subfunc](config_bag)
|
||||
else:
|
||||
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
||||
|
||||
|
||||
class TiramisuDispatcherConfig(TiramisuDispatcher, TiramisuContextConfig):
|
||||
def __call__(self, path: Optional[str]):
|
||||
def __call__(self,
|
||||
path: Optional[str]) -> TiramisuAPI:
|
||||
"""select a child Tiramisu configuration (only with MetaConfig or GroupConfig)"""
|
||||
config = self.config_bag.config
|
||||
if path is None:
|
||||
return TiramisuAPI(config,
|
||||
force_permissive=self.config_bag.force_permissive,
|
||||
force_unrestraint=self.config_bag.force_unrestraint)
|
||||
return TiramisuAPI(self.config_bag)
|
||||
spaths = path.split('.')
|
||||
config = self.config_bag.config
|
||||
for spath in spaths:
|
||||
config = config.getconfig(spath)
|
||||
return TiramisuAPI(config,
|
||||
force_permissive=self.config_bag.force_permissive,
|
||||
force_unrestraint=self.config_bag.force_unrestraint)
|
||||
config_bag = ConfigBag(config=config,
|
||||
force_unrestraint=self.config_bag.force_unrestraint,
|
||||
force_permissive=self.config_bag.force_permissive)
|
||||
return TiramisuAPI(config_bag)
|
||||
|
||||
|
||||
class TiramisuDispatcherOption(TiramisuDispatcher, TiramisuContextOption):
|
||||
subhelp = TiramisuOption
|
||||
def __call__(self, path: str, index: Optional[int]=None) -> TiramisuOption:
|
||||
def __call__(self,
|
||||
path: str,
|
||||
index: Optional[int]=None) -> TiramisuOption:
|
||||
"""select a option (index only for slave option)"""
|
||||
config_bag = self.config_bag.copy()
|
||||
validate = not config_bag.force_unrestraint
|
||||
if not validate:
|
||||
config_bag.setting_properties = None
|
||||
subconfig, name = config_bag.config.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
subconfig, name = self.config_bag.config.cfgimpl_get_home_by_path(path,
|
||||
self.config_bag)
|
||||
return TiramisuOption(name,
|
||||
path,
|
||||
index,
|
||||
subconfig,
|
||||
config_bag)
|
||||
|
||||
|
||||
class TiramisuAPI(TiramisuHelp):
|
||||
|
||||
def __init__(self,
|
||||
config: Union[Config, GroupConfig, MetaConfig],
|
||||
force_permissive: bool=False,
|
||||
force_unrestraint: bool=False) -> None:
|
||||
self._config = config
|
||||
self.force_permissive = force_permissive
|
||||
self.force_unrestraint = force_unrestraint
|
||||
self.registers = {}
|
||||
registers(self.registers, 'TiramisuContext')
|
||||
registers(self.registers, 'TiramisuDispatcher')
|
||||
|
||||
def __getattr__(self, subfunc: str) -> Any:
|
||||
if subfunc == 'forcepermissive':
|
||||
return TiramisuAPI(config=self._config,
|
||||
force_permissive=True,
|
||||
force_unrestraint=self.force_unrestraint)
|
||||
elif subfunc == 'unrestraint':
|
||||
return TiramisuAPI(config=self._config,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=True)
|
||||
elif subfunc in self.registers:
|
||||
config_bag = ConfigBag(config=self._config,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=self.force_unrestraint)
|
||||
return self.registers[subfunc](config_bag)
|
||||
else:
|
||||
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
||||
self.config_bag)
|
||||
|
||||
|
||||
@count
|
||||
|
@ -23,7 +23,7 @@ from typing import Any, Optional, Union, Callable, Dict, List
|
||||
|
||||
from .error import PropertiesOptionError, ConfigError, SlaveError
|
||||
from .i18n import _
|
||||
from .setting import undefined, ConfigBag, Undefined
|
||||
from .setting import undefined, ConfigBag, OptionBag, Undefined
|
||||
from .option.symlinkoption import DynSymLinkOption
|
||||
from .storage import get_default_values_storages, get_default_settings_storages
|
||||
from .function import ParamValue, ParamContext, ParamIndex, ParamOption, Params
|
||||
@ -34,7 +34,7 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
|
||||
option,
|
||||
index: Optional[int],
|
||||
orig_value,
|
||||
config_bag: ConfigBag,
|
||||
option_bag: OptionBag,
|
||||
context) -> Any:
|
||||
"""replace Param by true value"""
|
||||
if isinstance(callbk, ParamValue):
|
||||
@ -55,10 +55,6 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
|
||||
path = opt.impl_getpath(context)
|
||||
else:
|
||||
path = context.cfgimpl_get_description().impl_get_path_by_opt(opt)
|
||||
# don't validate if option is option that we tried to validate
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = opt
|
||||
sconfig_bag.force_permissive = True
|
||||
if index is not None and opt.impl_is_master_slaves() and \
|
||||
opt.impl_get_master_slaves().in_same_group(option):
|
||||
if opt == option:
|
||||
@ -76,15 +72,25 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
|
||||
if opt == option and orig_value is not undefined and \
|
||||
(not opt.impl_is_master_slaves('slave') or index is None):
|
||||
return orig_value
|
||||
# don't validate if option is option that we tried to validate
|
||||
config_bag = ConfigBag(config=option_bag.config_bag.config,
|
||||
_setting_properties=option_bag.config_bag._setting_properties,
|
||||
force_permissive=True,
|
||||
force_unrestraint=option_bag.config_bag.force_unrestraint,
|
||||
_validate=option_bag.config_bag._validate)
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(opt,
|
||||
path,
|
||||
index_,
|
||||
config_bag)
|
||||
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
|
||||
if opt == option:
|
||||
sconfig_bag.setting_properties = None
|
||||
sconfig_bag.force_unrestraint= False
|
||||
sconfig_bag.validate = False
|
||||
soption_bag.config_bag.force_unrestraint = True
|
||||
soption_bag.config_bag.validate = False
|
||||
try:
|
||||
# get value
|
||||
value = context.getattr(path,
|
||||
index_,
|
||||
sconfig_bag)
|
||||
soption_bag)
|
||||
if with_index:
|
||||
return value[index]
|
||||
return value
|
||||
@ -100,7 +106,7 @@ def carry_out_calculation(option,
|
||||
callback: Callable,
|
||||
callback_params: Optional[Params],
|
||||
index: Optional[int],
|
||||
config_bag: Optional[ConfigBag],
|
||||
option_bag: Optional[OptionBag],
|
||||
orig_value=undefined,
|
||||
is_validator: int=False):
|
||||
|
||||
@ -217,7 +223,7 @@ def carry_out_calculation(option,
|
||||
kwargs = {}
|
||||
# if callback_params has a callback, launch several time calculate()
|
||||
if option.issubdyn():
|
||||
#FIXME why here? should be ParamSuffix !
|
||||
#FIXME why here? should be a ParamSuffix !
|
||||
kwargs['suffix'] = option.impl_getsuffix()
|
||||
if callback_params:
|
||||
for callbk in callback_params.args:
|
||||
@ -226,7 +232,7 @@ def carry_out_calculation(option,
|
||||
option,
|
||||
index,
|
||||
orig_value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
context)
|
||||
if value is undefined:
|
||||
return undefined
|
||||
@ -239,7 +245,7 @@ def carry_out_calculation(option,
|
||||
option,
|
||||
index,
|
||||
orig_value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
context)
|
||||
if value is undefined:
|
||||
return undefined
|
||||
|
@ -20,7 +20,6 @@
|
||||
# ____________________________________________________________
|
||||
"options handler global entry point"
|
||||
import weakref
|
||||
from time import time
|
||||
from copy import copy
|
||||
|
||||
|
||||
@ -29,7 +28,7 @@ from .option.syndynoptiondescription import SynDynOptionDescription
|
||||
from .option.dynoptiondescription import DynOptionDescription
|
||||
from .option.masterslave import MasterSlaves
|
||||
from .option.baseoption import BaseOption, valid_name
|
||||
from .setting import ConfigBag, groups, Settings, undefined
|
||||
from .setting import OptionBag, ConfigBag, groups, Settings, undefined
|
||||
from .storage import get_storages, get_default_values_storages
|
||||
from .value import Values # , Multi
|
||||
from .i18n import _
|
||||
@ -50,7 +49,8 @@ class SubConfig(object):
|
||||
descr,
|
||||
context,
|
||||
config_bag,
|
||||
subpath=None):
|
||||
subpath=None,
|
||||
fromconsistency=None):
|
||||
""" Configuration option management master class
|
||||
|
||||
:param descr: describes the configuration schema
|
||||
@ -73,23 +73,38 @@ class SubConfig(object):
|
||||
descr.impl_get_group_type() == groups.master:
|
||||
master = descr.getmaster()
|
||||
masterpath = master.impl_getname()
|
||||
mconfig_bag = config_bag.copy('nooption')
|
||||
mconfig_bag.option = master
|
||||
mconfig_bag.validate = False
|
||||
full_masterpath = self._get_subpath(masterpath)
|
||||
cconfig_bag = ConfigBag(config=config_bag.config,
|
||||
_setting_properties=config_bag._setting_properties,
|
||||
force_permissive=config_bag.force_permissive,
|
||||
force_unrestraint=config_bag.force_unrestraint,
|
||||
_validate=False)
|
||||
moption_bag = OptionBag()
|
||||
moption_bag.set_option(master,
|
||||
full_masterpath,
|
||||
None,
|
||||
cconfig_bag)
|
||||
if fromconsistency:
|
||||
moption_bag.fromconsistency = fromconsistency
|
||||
value = self.getattr(masterpath,
|
||||
None,
|
||||
mconfig_bag)
|
||||
moption_bag)
|
||||
self._impl_length = len(value)
|
||||
|
||||
def cfgimpl_get_length(self):
|
||||
return self._impl_length
|
||||
|
||||
def cfgimpl_get_length_slave(self, option, config_bag):
|
||||
if option.impl_is_symlinkoption():
|
||||
def cfgimpl_get_length_slave(self,
|
||||
option_bag):
|
||||
if option_bag.option.impl_is_symlinkoption():
|
||||
context = self.cfgimpl_get_context()
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
subconfig, _ = context.cfgimpl_get_home_by_path(option.impl_getopt().impl_getpath(context),
|
||||
sconfig_bag)
|
||||
#soption_bag = OptionBag()
|
||||
#soption_bag.set_option(option_bag.option.impl_getopt(),
|
||||
# option_bag.option.impl_getopt().impl_getpath(context),
|
||||
# None,
|
||||
# option_bag.config_bag)
|
||||
path = option_bag.option.impl_getopt().impl_getpath(context)
|
||||
subconfig, _ = context.cfgimpl_get_home_by_path(path,
|
||||
option_bag.config_bag)
|
||||
return subconfig.cfgimpl_get_length()
|
||||
else:
|
||||
return self.cfgimpl_get_length()
|
||||
@ -99,54 +114,65 @@ class SubConfig(object):
|
||||
values,
|
||||
settings,
|
||||
resetted_opts,
|
||||
config_bag,
|
||||
opt,
|
||||
path):
|
||||
option_bag):
|
||||
|
||||
if path in resetted_opts:
|
||||
if option_bag.path in resetted_opts:
|
||||
return
|
||||
resetted_opts.append(path)
|
||||
for woption in opt._get_dependencies(self):
|
||||
resetted_opts.append(option_bag.path)
|
||||
for woption in option_bag.option._get_dependencies(self):
|
||||
option = woption()
|
||||
if option.impl_is_dynoptiondescription():
|
||||
for doption in option.get_syndynoptiondescriptions(config_bag):
|
||||
for doption in option.get_syndynoptiondescriptions(option_bag):
|
||||
doption_path = doption.impl_getpath(self)
|
||||
doption_bag = OptionBag()
|
||||
doption_bag.set_option(doption,
|
||||
doption_path,
|
||||
option_bag.index,
|
||||
option_bag.config_bag)
|
||||
self.reset_one_option_cache(desc,
|
||||
values,
|
||||
settings,
|
||||
resetted_opts,
|
||||
config_bag,
|
||||
doption,
|
||||
doption_path)
|
||||
doption_bag)
|
||||
elif option.issubdyn():
|
||||
for doption in desc.build_dynoptions(option, config_bag):
|
||||
doption_bag = OptionBag()
|
||||
doption_path = option.impl_getpath(self)
|
||||
doption_bag.set_option(option,
|
||||
doption_path,
|
||||
option_bag.index,
|
||||
option_bag.config_bag)
|
||||
for doption in desc.build_dynoptions(doption_bag):
|
||||
doption_path = doption.impl_getpath(self)
|
||||
doption_bag = OptionBag()
|
||||
doption_bag.set_option(doption,
|
||||
doption_path,
|
||||
option_bag.index,
|
||||
option_bag.config_bag)
|
||||
self.reset_one_option_cache(desc,
|
||||
values,
|
||||
settings,
|
||||
resetted_opts,
|
||||
config_bag,
|
||||
doption,
|
||||
doption_path)
|
||||
doption_bag)
|
||||
else:
|
||||
option_path = option.impl_getpath(self)
|
||||
doption_bag = OptionBag()
|
||||
doption_bag.set_option(option,
|
||||
option_path,
|
||||
option_bag.index,
|
||||
option_bag.config_bag)
|
||||
self.reset_one_option_cache(desc,
|
||||
values,
|
||||
settings,
|
||||
resetted_opts,
|
||||
config_bag,
|
||||
option,
|
||||
option_path)
|
||||
doption_bag)
|
||||
del option
|
||||
opt.reset_cache(path,
|
||||
values,
|
||||
settings,
|
||||
resetted_opts)
|
||||
option_bag.option.reset_cache(option_bag.path,
|
||||
values,
|
||||
settings,
|
||||
resetted_opts)
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
opt,
|
||||
path,
|
||||
config_bag,
|
||||
option_bag,
|
||||
resetted_opts=None):
|
||||
"""reset all settings in cache
|
||||
"""
|
||||
@ -158,79 +184,40 @@ class SubConfig(object):
|
||||
values = context.cfgimpl_get_values()
|
||||
settings = context.cfgimpl_get_settings()
|
||||
|
||||
if not None in (opt, path):
|
||||
if option_bag is not None:
|
||||
self.reset_one_option_cache(desc,
|
||||
values,
|
||||
settings,
|
||||
resetted_opts,
|
||||
config_bag,
|
||||
opt,
|
||||
path)
|
||||
option_bag)
|
||||
else:
|
||||
values._p_.reset_all_cache()
|
||||
settings._p_.reset_all_cache()
|
||||
|
||||
def cfgimpl_get_home_by_path(self,
|
||||
path,
|
||||
config_bag):
|
||||
config_bag,
|
||||
fromconsistency=None):
|
||||
""":returns: tuple (config, name)"""
|
||||
path = path.split('.')
|
||||
for step in path[:-1]:
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
option_bag = OptionBag()
|
||||
option = self.cfgimpl_get_description().impl_getchild(step,
|
||||
config_bag,
|
||||
self)
|
||||
subpath = self._get_subpath(step)
|
||||
option_bag.set_option(option,
|
||||
subpath,
|
||||
None,
|
||||
config_bag)
|
||||
if fromconsistency is not None:
|
||||
option_bag.fromconsistency = fromconsistency
|
||||
self = self.getattr(step,
|
||||
None,
|
||||
sconfig_bag)
|
||||
option_bag)
|
||||
if not isinstance(self, SubConfig):
|
||||
raise AttributeError(_('unknown option {}').format(path[-1]))
|
||||
return self, path[-1]
|
||||
|
||||
# ______________________________________________________________________
|
||||
def iter_groups(self,
|
||||
config_bag,
|
||||
group_type=None):
|
||||
"""iteration on groups objects only.
|
||||
All groups are returned if `group_type` is `None`, otherwise the groups
|
||||
can be filtered by categories (families, or whatever).
|
||||
|
||||
:param group_type: if defined, is an instance of `groups.GroupType`
|
||||
or `groups.MasterGroupType` that lives in
|
||||
`setting.groups`
|
||||
"""
|
||||
if group_type is not None and not isinstance(group_type,
|
||||
groups.GroupType):
|
||||
raise TypeError(_("unknown group_type: {0}").format(group_type))
|
||||
for child in self.cfgimpl_get_description().impl_getchildren(config_bag):
|
||||
if child.impl_is_optiondescription():
|
||||
nconfig_bag = config_bag.copy('nooption')
|
||||
nconfig_bag.option = child
|
||||
try:
|
||||
if group_type is None or (group_type is not None and
|
||||
child.impl_get_group_type()
|
||||
== group_type):
|
||||
name = child.impl_getname()
|
||||
yield name, self.getattr(name,
|
||||
None,
|
||||
nconfig_bag)
|
||||
except PropertiesOptionError:
|
||||
pass
|
||||
|
||||
def cfgimpl_get_children(self,
|
||||
config_bag):
|
||||
context = self.cfgimpl_get_context()
|
||||
for opt in self.cfgimpl_get_description().impl_getchildren(config_bag):
|
||||
nconfig_bag = config_bag.copy('nooption')
|
||||
nconfig_bag.option = opt
|
||||
name = opt.impl_getname()
|
||||
if nconfig_bag.setting_properties is not None:
|
||||
subpath = self._get_subpath(name)
|
||||
try:
|
||||
context.cfgimpl_get_settings().validate_properties(subpath,
|
||||
None,
|
||||
nconfig_bag)
|
||||
except PropertiesOptionError:
|
||||
continue
|
||||
yield name
|
||||
|
||||
# ______________________________________________________________________
|
||||
def cfgimpl_get_context(self):
|
||||
"""context could be None, we need to test it
|
||||
@ -245,7 +232,7 @@ class SubConfig(object):
|
||||
|
||||
def cfgimpl_get_description(self):
|
||||
if self._impl_descr is None:
|
||||
raise ConfigError(_('no option description found for this config'
|
||||
raise ConfigError(_('there is no option description for this config'
|
||||
' (may be GroupConfig)'))
|
||||
else:
|
||||
return self._impl_descr
|
||||
@ -257,63 +244,39 @@ class SubConfig(object):
|
||||
return self.cfgimpl_get_context()._impl_values
|
||||
|
||||
def setattr(self,
|
||||
name,
|
||||
index,
|
||||
value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
_commit=True):
|
||||
|
||||
context = self.cfgimpl_get_context()
|
||||
if '.' in name:
|
||||
# when set_value
|
||||
self, name = self.cfgimpl_get_home_by_path(name,
|
||||
config_bag)
|
||||
if config_bag.option is None:
|
||||
config_bag.option = self.cfgimpl_get_description().impl_getchild(name,
|
||||
config_bag,
|
||||
self)
|
||||
if config_bag.option.impl_is_symlinkoption():
|
||||
#self, name = self.cfgimpl_get_home_by_path(option_bag.path,
|
||||
# option_bag.config_bag)
|
||||
#if config_bag.option is None:
|
||||
# config_bag.option = self.cfgimpl_get_description().impl_getchild(name,
|
||||
# config_bag,
|
||||
# self)
|
||||
if option_bag.option.impl_is_symlinkoption():
|
||||
raise ConfigError(_("can't assign to a SymLinkOption"))
|
||||
else:
|
||||
path = self._get_subpath(name)
|
||||
if config_bag.setting_properties:
|
||||
context.cfgimpl_get_settings().validate_properties(path,
|
||||
index,
|
||||
config_bag)
|
||||
self.cfgimpl_get_description().impl_validate_value(config_bag.option,
|
||||
context = self.cfgimpl_get_context()
|
||||
if option_bag.config_bag.setting_properties:
|
||||
context.cfgimpl_get_settings().validate_properties(option_bag)
|
||||
self.cfgimpl_get_description().impl_validate_value(option_bag.option,
|
||||
value,
|
||||
self)
|
||||
return context.cfgimpl_get_values().setvalue(path,
|
||||
index,
|
||||
value,
|
||||
config_bag,
|
||||
return context.cfgimpl_get_values().setvalue(value,
|
||||
option_bag,
|
||||
_commit)
|
||||
|
||||
def delattr(self,
|
||||
name,
|
||||
index,
|
||||
config_bag):
|
||||
if '.' in name:
|
||||
self, name = self.cfgimpl_get_home_by_path(name,
|
||||
config_bag)
|
||||
option = config_bag.option
|
||||
option_bag):
|
||||
option = option_bag.option
|
||||
if option.impl_is_symlinkoption():
|
||||
raise TypeError(_("can't delete a SymLinkOption"))
|
||||
subpath = self._get_subpath(name)
|
||||
values = self.cfgimpl_get_values()
|
||||
if index is not None:
|
||||
if option.impl_is_master_slaves('master'):
|
||||
values.reset_master(self,
|
||||
subpath,
|
||||
index,
|
||||
config_bag)
|
||||
elif option.impl_is_master_slaves('slave'):
|
||||
values.reset_slave(subpath,
|
||||
index,
|
||||
config_bag)
|
||||
if option_bag.index is not None:
|
||||
values.reset_slave(option_bag)
|
||||
else:
|
||||
values.reset(subpath,
|
||||
config_bag)
|
||||
values.reset(option_bag)
|
||||
|
||||
def _get_subpath(self, name):
|
||||
if self._impl_path is None:
|
||||
@ -324,71 +287,73 @@ class SubConfig(object):
|
||||
|
||||
def getattr(self,
|
||||
name,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag):
|
||||
"""
|
||||
attribute notation mechanism for accessing the value of an option
|
||||
:param name: attribute name
|
||||
:return: option's value if name is an option name, OptionDescription
|
||||
otherwise
|
||||
"""
|
||||
config_bag = option_bag.config_bag
|
||||
if '.' in name:
|
||||
if option_bag.fromconsistency:
|
||||
fromconsistency = option_bag.fromconsistency.copy()
|
||||
else:
|
||||
fromconsistency = None
|
||||
self, name = self.cfgimpl_get_home_by_path(name,
|
||||
config_bag)
|
||||
config_bag,
|
||||
fromconsistency)
|
||||
|
||||
context = self.cfgimpl_get_context()
|
||||
option = config_bag.option
|
||||
if option is None:
|
||||
option = self.cfgimpl_get_description().impl_getchild(name,
|
||||
config_bag,
|
||||
self)
|
||||
config_bag.option = option
|
||||
option = option_bag.option
|
||||
if option.impl_is_symlinkoption():
|
||||
opt = option.impl_getopt()
|
||||
path = context.cfgimpl_get_description().impl_get_path_by_opt(opt)
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.ori_option = option
|
||||
sconfig_bag.option = opt
|
||||
return context.getattr(path,
|
||||
index,
|
||||
sconfig_bag)
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(option.impl_getopt(),
|
||||
None,
|
||||
option_bag.index,
|
||||
config_bag)
|
||||
soption_bag.ori_option = option
|
||||
context = self.cfgimpl_get_context()
|
||||
return context.getattr(soption_bag.path,
|
||||
soption_bag)
|
||||
|
||||
subpath = self._get_subpath(name)
|
||||
if config_bag.setting_properties:
|
||||
self.cfgimpl_get_settings().validate_properties(subpath,
|
||||
index,
|
||||
config_bag)
|
||||
self.cfgimpl_get_settings().validate_properties(option_bag)
|
||||
if option.impl_is_optiondescription():
|
||||
if option_bag.fromconsistency:
|
||||
fromconsistency = option_bag.fromconsistency.copy()
|
||||
else:
|
||||
fromconsistency = None
|
||||
return SubConfig(option,
|
||||
self._impl_context,
|
||||
config_bag,
|
||||
subpath)
|
||||
option_bag.path,
|
||||
fromconsistency)
|
||||
|
||||
if option.impl_is_master_slaves('slave'):
|
||||
length = self.cfgimpl_get_length_slave(option, config_bag)
|
||||
slave_len = self.cfgimpl_get_values()._p_.get_max_length(subpath)
|
||||
length = self.cfgimpl_get_length_slave(option_bag)
|
||||
slave_len = self.cfgimpl_get_values()._p_.get_max_length(option_bag.path)
|
||||
if slave_len > length:
|
||||
raise SlaveError(_('slave option "{}" has higher length "{}" than the master '
|
||||
'length "{}"').format(option.impl_get_display_name(),
|
||||
slave_len,
|
||||
length,
|
||||
subpath))
|
||||
if option.impl_is_master_slaves('slave') and index is None:
|
||||
option_bag.index))
|
||||
if option.impl_is_master_slaves('slave') and option_bag.index is None:
|
||||
value = []
|
||||
for idx in range(length):
|
||||
config_bag.properties = None
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(option,
|
||||
option_bag.path,
|
||||
idx,
|
||||
config_bag)
|
||||
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
|
||||
value.append(self.getattr(name,
|
||||
idx,
|
||||
config_bag))
|
||||
soption_bag))
|
||||
else:
|
||||
value = self.cfgimpl_get_values().get_cached_value(subpath,
|
||||
index,
|
||||
config_bag)
|
||||
value = self.cfgimpl_get_values().get_cached_value(option_bag)
|
||||
if config_bag.validate_properties:
|
||||
self.cfgimpl_get_settings().validate_mandatory(subpath,
|
||||
index,
|
||||
value,
|
||||
config_bag)
|
||||
self.cfgimpl_get_settings().validate_mandatory(value,
|
||||
option_bag)
|
||||
return value
|
||||
|
||||
def find(self,
|
||||
@ -406,11 +371,10 @@ class SubConfig(object):
|
||||
:param first: return only one option if True, a list otherwise
|
||||
:return: find list or an exception if nothing has been found
|
||||
"""
|
||||
def _filter_by_value(sconfig_bag):
|
||||
def _filter_by_value(soption_bag):
|
||||
try:
|
||||
value = self.getattr(path,
|
||||
None,
|
||||
sconfig_bag)
|
||||
soption_bag)
|
||||
except PropertiesOptionError:
|
||||
return False
|
||||
if isinstance(value, list):
|
||||
@ -427,18 +391,19 @@ class SubConfig(object):
|
||||
_subpath,
|
||||
config_bag)
|
||||
for path, option in options:
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = option
|
||||
if byvalue is not undefined and not _filter_by_value(sconfig_bag):
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
None,
|
||||
config_bag)
|
||||
if byvalue is not undefined and not _filter_by_value(option_bag):
|
||||
continue
|
||||
elif sconfig_bag.validate_properties:
|
||||
elif config_bag.validate_properties:
|
||||
#remove option with propertyerror, ...
|
||||
try:
|
||||
self.unwrap_from_path(path,
|
||||
sconfig_bag)
|
||||
self.cfgimpl_get_settings().validate_properties(path,
|
||||
None,
|
||||
sconfig_bag)
|
||||
config_bag)
|
||||
self.cfgimpl_get_settings().validate_properties(option_bag)
|
||||
except PropertiesOptionError:
|
||||
continue
|
||||
found = True
|
||||
@ -513,8 +478,11 @@ class SubConfig(object):
|
||||
path = '.'.join(path.split('.')[:-1])
|
||||
opt = context.unwrap_from_path(path,
|
||||
config_bag)
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = opt
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(opt,
|
||||
path,
|
||||
None,
|
||||
config_bag)
|
||||
if mypath is not None:
|
||||
if mypath == path:
|
||||
withoption = None
|
||||
@ -531,19 +499,24 @@ class SubConfig(object):
|
||||
pathsvalues,
|
||||
_currpath,
|
||||
flatten,
|
||||
sconfig_bag,
|
||||
soption_bag,
|
||||
fullpath=fullpath)
|
||||
#withoption can be set to None below !
|
||||
if withoption is None:
|
||||
for opt in self.cfgimpl_get_description().impl_getchildren(config_bag, context):
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = opt
|
||||
path = opt.impl_getname()
|
||||
self._make_sub_dict(path,
|
||||
name = opt.impl_getname()
|
||||
path = self._get_subpath(name)
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(opt,
|
||||
path,
|
||||
None,
|
||||
config_bag)
|
||||
#path = self._get_subpath(name)
|
||||
self._make_sub_dict(name,
|
||||
pathsvalues,
|
||||
_currpath,
|
||||
flatten,
|
||||
sconfig_bag,
|
||||
soption_bag,
|
||||
fullpath=fullpath)
|
||||
if _currpath == []:
|
||||
options = dict(pathsvalues)
|
||||
@ -555,33 +528,32 @@ class SubConfig(object):
|
||||
pathsvalues,
|
||||
_currpath,
|
||||
flatten,
|
||||
config_bag,
|
||||
option_bag,
|
||||
fullpath=False):
|
||||
try:
|
||||
option = config_bag.option
|
||||
option = option_bag.option
|
||||
if not option.impl_is_optiondescription() and option.impl_is_master_slaves('slave'):
|
||||
ret = []
|
||||
length = self.cfgimpl_get_length_slave(option, config_bag)
|
||||
length = self.cfgimpl_get_length_slave(option_bag)
|
||||
if length:
|
||||
for idx in range(length):
|
||||
config_bag.properties = None
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(option,
|
||||
option_bag.path,
|
||||
idx,
|
||||
option_bag.config_bag)
|
||||
ret.append(self.getattr(name,
|
||||
idx,
|
||||
config_bag))
|
||||
elif config_bag.setting_properties:
|
||||
path = self._get_subpath(name)
|
||||
self.cfgimpl_get_settings().validate_properties(path,
|
||||
None,
|
||||
config_bag)
|
||||
soption_bag))
|
||||
elif option_bag.config_bag.setting_properties:
|
||||
self.cfgimpl_get_settings().validate_properties(option_bag)
|
||||
else:
|
||||
ret = self.getattr(name,
|
||||
None,
|
||||
config_bag)
|
||||
option_bag)
|
||||
except PropertiesOptionError:
|
||||
pass
|
||||
else:
|
||||
if option.impl_is_optiondescription():
|
||||
pathsvalues += ret.make_dict(config_bag,
|
||||
pathsvalues += ret.make_dict(option_bag.config_bag,
|
||||
flatten=flatten,
|
||||
_currpath=_currpath + [name],
|
||||
fullpath=fullpath)
|
||||
@ -638,12 +610,12 @@ class _CommonConfig(SubConfig):
|
||||
true_option = option.impl_getopt()
|
||||
context = self.cfgimpl_get_context()
|
||||
true_path = true_option.impl_getpath(context)
|
||||
self, path = context.cfgimpl_get_home_by_path(true_path,
|
||||
self, path = context.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
config_bag.option = true_option
|
||||
else:
|
||||
true_path = path
|
||||
config_bag.option = option
|
||||
#config_bag.option = option
|
||||
return option
|
||||
|
||||
def cfgimpl_get_path(self, dyn=True):
|
||||
@ -816,25 +788,15 @@ class GroupConfig(_CommonConfig):
|
||||
return self._impl_children
|
||||
|
||||
def cfgimpl_reset_cache(self,
|
||||
opt,
|
||||
path,
|
||||
config_bag,
|
||||
option_bag,
|
||||
resetted_opts=None):
|
||||
if resetted_opts is None:
|
||||
resetted_opts = []
|
||||
if isinstance(self, MetaConfig):
|
||||
super(GroupConfig, self).cfgimpl_reset_cache(opt,
|
||||
path,
|
||||
config_bag=config_bag,
|
||||
super(GroupConfig, self).cfgimpl_reset_cache(option_bag,
|
||||
resetted_opts=copy(resetted_opts))
|
||||
for child in self._impl_children:
|
||||
if config_bag is None:
|
||||
nconfig_bag = config_bag
|
||||
else:
|
||||
nconfig_bag = config_bag.copy('nooption')
|
||||
child.cfgimpl_reset_cache(opt,
|
||||
path,
|
||||
config_bag=nconfig_bag,
|
||||
child.cfgimpl_reset_cache(option_bag,
|
||||
resetted_opts=copy(resetted_opts))
|
||||
|
||||
def set_value(self,
|
||||
@ -857,16 +819,21 @@ class GroupConfig(_CommonConfig):
|
||||
only_config=only_config,
|
||||
_commit=False))
|
||||
else:
|
||||
nconfig_bag = config_bag.copy('nooption')
|
||||
child.setattr(path,
|
||||
index,
|
||||
value,
|
||||
nconfig_bag,
|
||||
subconfig, name = child.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
option = subconfig.cfgimpl_get_description().impl_getchild(name,
|
||||
config_bag,
|
||||
child)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
index,
|
||||
config_bag)
|
||||
child.setattr(value,
|
||||
option_bag,
|
||||
_commit=False)
|
||||
except PropertiesOptionError as err:
|
||||
ret.append(PropertiesOptionError(err._path,
|
||||
err._index,
|
||||
err._config_bag,
|
||||
ret.append(PropertiesOptionError(err._option_bag,
|
||||
err.proptype,
|
||||
err._settings,
|
||||
err._opt_type,
|
||||
@ -905,8 +872,6 @@ class GroupConfig(_CommonConfig):
|
||||
|
||||
ret = []
|
||||
for child in self._impl_children:
|
||||
nconfig_bag = config_bag.copy('nooption')
|
||||
nconfig_bag.option = child
|
||||
if isinstance(child, GroupConfig):
|
||||
ret.extend(child.find_firsts(byname=byname,
|
||||
bypath=bypath,
|
||||
@ -1011,59 +976,77 @@ class MetaConfig(GroupConfig):
|
||||
' cannot be set together'))
|
||||
opt = self.cfgimpl_get_description().impl_get_opt_by_path(path)
|
||||
for child in self._impl_children:
|
||||
nconfig_bag = config_bag.copy('nooption')
|
||||
nconfig_bag.option = opt
|
||||
subconfig, name = child.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
option = subconfig.cfgimpl_get_description().impl_getchild(name,
|
||||
config_bag,
|
||||
child)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
index,
|
||||
config_bag)
|
||||
if force_default_if_same:
|
||||
if not child.cfgimpl_get_values()._p_.hasvalue(path):
|
||||
child_value = undefined
|
||||
else:
|
||||
child_value = child.getattr(path,
|
||||
None,
|
||||
nconfig_bag)
|
||||
child_value = child.getattr(name,
|
||||
option_bag)
|
||||
if force_default or (force_default_if_same and value == child_value):
|
||||
child.cfgimpl_get_values().reset(path,
|
||||
nconfig_bag,
|
||||
child.cfgimpl_get_values().reset(option_bag,
|
||||
_commit=False)
|
||||
continue
|
||||
if force_dont_change_value:
|
||||
try:
|
||||
child_value = child.getattr(path,
|
||||
None,
|
||||
nconfig_bag)
|
||||
child_value = child.getattr(name,
|
||||
option_bag)
|
||||
if value != child_value:
|
||||
child.setattr(path,
|
||||
None,
|
||||
child_value,
|
||||
nconfig_bag,
|
||||
child.setattr(child_value,
|
||||
option_bag,
|
||||
_commit=False)
|
||||
except (PropertiesOptionError, ValueError, SlaveError) as err:
|
||||
ret.append(err)
|
||||
|
||||
nconfig_bag = config_bag.copy('nooption')
|
||||
try:
|
||||
self.setattr(path,
|
||||
index,
|
||||
value,
|
||||
nconfig_bag,
|
||||
_commit=_commit)
|
||||
subconfig, name = self.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
option = subconfig.cfgimpl_get_description().impl_getchild(name,
|
||||
config_bag,
|
||||
self)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
index,
|
||||
config_bag)
|
||||
self.setattr(value,
|
||||
option_bag,
|
||||
_commit=False)
|
||||
except (PropertiesOptionError, ValueError, SlaveError) as err:
|
||||
ret.append(err)
|
||||
return ret
|
||||
|
||||
def reset(self, path, config_bag):
|
||||
#FIXME not working with DynSymLinkOption
|
||||
#FIXME fonctionne avec sous metaconfig ??
|
||||
opt = self.cfgimpl_get_description().impl_get_opt_by_path(path)
|
||||
config_bag.option = opt
|
||||
config_bag.validate = False
|
||||
def reset(self,
|
||||
path,
|
||||
config_bag):
|
||||
rconfig_bag = ConfigBag(config=config_bag.config,
|
||||
_setting_properties=config_bag._setting_properties,
|
||||
force_permissive=config_bag.force_permissive,
|
||||
force_unrestraint=config_bag.force_unrestraint,
|
||||
_validate=False)
|
||||
subconfig, name = self.cfgimpl_get_home_by_path(path,
|
||||
config_bag)
|
||||
option = subconfig.cfgimpl_get_description().impl_getchild(name,
|
||||
config_bag,
|
||||
self)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
option,
|
||||
rconfig_bag)
|
||||
for child in self._impl_children:
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = opt
|
||||
child.cfgimpl_get_values().reset(path,
|
||||
sconfig_bag,
|
||||
child.cfgimpl_get_values().reset(option_bag,
|
||||
_commit=False)
|
||||
self.cfgimpl_get_values().reset(path,
|
||||
config_bag)
|
||||
self.cfgimpl_get_values().reset(option_bag)
|
||||
|
||||
def new_config(self,
|
||||
session_id,
|
||||
|
@ -53,31 +53,27 @@ def display_list(lst, separator='and', add_quote=False):
|
||||
class PropertiesOptionError(AttributeError):
|
||||
"attempt to access to an option with a property that is not allowed"
|
||||
def __init__(self,
|
||||
path,
|
||||
index,
|
||||
config_bag,
|
||||
option_bag,
|
||||
proptype,
|
||||
settings,
|
||||
opt_type=None,
|
||||
requires=None,
|
||||
name=None,
|
||||
orig_opt=None):
|
||||
self._path = path
|
||||
self._index = index
|
||||
if opt_type:
|
||||
self._opt_type = opt_type
|
||||
self._requires = requires
|
||||
self._name = name
|
||||
self._orig_opt = orig_opt
|
||||
else:
|
||||
if config_bag.option.impl_is_optiondescription():
|
||||
if option_bag.option.impl_is_optiondescription():
|
||||
self._opt_type = 'optiondescription'
|
||||
else:
|
||||
self._opt_type = 'option'
|
||||
self._requires = config_bag.option.impl_getrequires()
|
||||
self._name = config_bag.option.impl_get_display_name()
|
||||
self._requires = option_bag.option.impl_getrequires()
|
||||
self._name = option_bag.option.impl_get_display_name()
|
||||
self._orig_opt = None
|
||||
self._config_bag = config_bag.copy()
|
||||
self._option_bag = option_bag
|
||||
self.proptype = proptype
|
||||
self._settings = settings
|
||||
self.msg = None
|
||||
@ -90,12 +86,8 @@ class PropertiesOptionError(AttributeError):
|
||||
#this part is a bit slow, so only execute when display
|
||||
if self.msg:
|
||||
return self.msg
|
||||
req = self._settings.apply_requires(self._path,
|
||||
self._requires,
|
||||
self._index,
|
||||
True,
|
||||
self._config_bag,
|
||||
self._name)
|
||||
req = self._settings.apply_requires(self._option_bag,
|
||||
True)
|
||||
#if req != {} or self._orig_opt is not None:
|
||||
if req != {}:
|
||||
only_one = len(req) == 1
|
||||
@ -123,7 +115,7 @@ class PropertiesOptionError(AttributeError):
|
||||
self._name,
|
||||
prop_msg,
|
||||
msg))
|
||||
del self._path, self._index, self._requires, self._opt_type, self._name, self._config_bag
|
||||
del self._requires, self._opt_type, self._name, self._option_bag
|
||||
del self._settings, self._orig_opt
|
||||
return self.msg
|
||||
|
||||
|
@ -81,22 +81,26 @@ class ChoiceOption(Option):
|
||||
warnings_only=warnings_only)
|
||||
|
||||
def impl_get_values(self,
|
||||
config_bag,
|
||||
option_bag,
|
||||
current_opt=undefined):
|
||||
if current_opt is undefined:
|
||||
current_opt = self
|
||||
#FIXME cache? but in context...
|
||||
values = self._choice_values
|
||||
if isinstance(values, FunctionType):
|
||||
if config_bag is undefined:
|
||||
if option_bag is undefined:
|
||||
values = undefined
|
||||
else:
|
||||
if option_bag.config_bag == undefined:
|
||||
config = undefined
|
||||
else:
|
||||
config = option_bag.config_bag.config
|
||||
values = carry_out_calculation(current_opt,
|
||||
config_bag.config,
|
||||
values,
|
||||
getattr(self, '_choice_values_params', {}),
|
||||
None,
|
||||
config_bag)
|
||||
context=config,
|
||||
callback=values,
|
||||
callback_params=getattr(self, '_choice_values_params', {}),
|
||||
index=None,
|
||||
option_bag=option_bag)
|
||||
if values is not undefined and not isinstance(values, list):
|
||||
raise ConfigError(_('calculated values for {0} is not a list'
|
||||
'').format(self.impl_getname()))
|
||||
@ -105,9 +109,9 @@ class ChoiceOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
current_opt=undefined):
|
||||
values = self.impl_get_values(config_bag,
|
||||
values = self.impl_get_values(option_bag,
|
||||
current_opt=current_opt)
|
||||
if values is not undefined and not value in values:
|
||||
if len(values) == 1:
|
||||
|
@ -72,14 +72,14 @@ class DynOptionDescription(OptionDescription):
|
||||
'').format(self.impl_get_display_name()))
|
||||
|
||||
def _impl_get_suffixes(self,
|
||||
config_bag):
|
||||
option_bag):
|
||||
callback, callback_params = self.impl_get_callback()
|
||||
values = carry_out_calculation(self,
|
||||
config_bag.config,
|
||||
option_bag.config_bag.config,
|
||||
callback,
|
||||
callback_params,
|
||||
None,
|
||||
config_bag)
|
||||
option_bag)
|
||||
if not isinstance(values, list):
|
||||
raise ValueError(_('DynOptionDescription callback for option "{}", is not a list ({})'
|
||||
'').format(self.impl_get_display_name(), values))
|
||||
@ -92,9 +92,9 @@ class DynOptionDescription(OptionDescription):
|
||||
self.impl_get_display_name()))
|
||||
return values
|
||||
|
||||
def get_syndynoptiondescriptions(self, config_bag):
|
||||
subpath = self.impl_getpath(config_bag.config).rsplit('.', 1)[0]
|
||||
for suffix in self._impl_get_suffixes(config_bag):
|
||||
def get_syndynoptiondescriptions(self, option_bag):
|
||||
subpath = self.impl_getpath(option_bag.config_bag.config).rsplit('.', 1)[0]
|
||||
for suffix in self._impl_get_suffixes(option_bag):
|
||||
yield SynDynOptionDescription(self,
|
||||
subpath,
|
||||
suffix)
|
||||
|
@ -24,7 +24,7 @@ from itertools import chain
|
||||
|
||||
|
||||
from ..i18n import _
|
||||
from ..setting import groups, undefined
|
||||
from ..setting import groups, undefined, OptionBag, ConfigBag
|
||||
from .optiondescription import OptionDescription
|
||||
from .option import Option
|
||||
from ..error import SlaveError, PropertiesOptionError
|
||||
@ -104,35 +104,49 @@ class MasterSlaves(OptionDescription):
|
||||
|
||||
def reset(self,
|
||||
values,
|
||||
config_bag,
|
||||
option_bag,
|
||||
_commit=True):
|
||||
|
||||
config_bag = ConfigBag(config=option_bag.config_bag.config,
|
||||
_setting_properties=option_bag.config_bag._setting_properties,
|
||||
force_permissive=option_bag.config_bag.force_permissive,
|
||||
force_unrestraint=option_bag.config_bag.force_unrestraint,
|
||||
_validate=False)
|
||||
for slave in self.getslaves():
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = slave
|
||||
sconfig_bag.validate = False
|
||||
slave_path = slave.impl_getpath(values._getcontext())
|
||||
values.reset(slave_path,
|
||||
sconfig_bag,
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(slave,
|
||||
slave_path,
|
||||
None,
|
||||
config_bag)
|
||||
values.reset(soption_bag,
|
||||
_commit=_commit)
|
||||
|
||||
def pop(self,
|
||||
values,
|
||||
index,
|
||||
config_bag,
|
||||
option_bag,
|
||||
slaves=undefined):
|
||||
|
||||
context = values._getcontext()
|
||||
if slaves is undefined:
|
||||
slaves = self.getslaves()
|
||||
config_bag = ConfigBag(config=option_bag.config_bag.config,
|
||||
_setting_properties=None,
|
||||
force_permissive=option_bag.config_bag.force_permissive,
|
||||
force_unrestraint=option_bag.config_bag.force_unrestraint,
|
||||
_validate=False)
|
||||
for slave in slaves:
|
||||
slave_path = slave.impl_getpath(context)
|
||||
slavelen = values._p_.get_max_length(slave_path)
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = slave
|
||||
if not values.is_default_owner(slave_path,
|
||||
index,
|
||||
config_bag,
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(slave,
|
||||
slave_path,
|
||||
index,
|
||||
config_bag)
|
||||
# do not check force_default_on_freeze
|
||||
soption_bag.properties = {}
|
||||
if not values.is_default_owner(soption_bag,
|
||||
validate_meta=False):
|
||||
if slavelen > index:
|
||||
values._p_.resetvalue_index(slave_path,
|
||||
|
@ -95,9 +95,15 @@ class NetmaskOption(Option):
|
||||
if make_net and ip.prefixlen() != 32:
|
||||
val_ip = IP(val_ipnetwork)
|
||||
if ip.net() == val_ip:
|
||||
msg = _('this is a network with netmask "{0}" ("{1}")')
|
||||
if current_opt == opts[1]:
|
||||
msg = _('this is a network with netmask "{0}" ("{1}")')
|
||||
else:
|
||||
msg = _('this is a network with {2} "{0}" ("{1}")')
|
||||
if ip.broadcast() == val_ip:
|
||||
msg = _('this is a broadcast with netmask "{0}" ("{1}")')
|
||||
if current_opt == opts[1]:
|
||||
msg = _('this is a broadcast with netmask "{0}" ("{1}")')
|
||||
else:
|
||||
msg = _('this is a broadcast with {2} "{0}" ("{1}")')
|
||||
|
||||
except ValueError:
|
||||
if not make_net:
|
||||
@ -106,5 +112,10 @@ class NetmaskOption(Option):
|
||||
else:
|
||||
raise ValueError(_('with {2} "{0}" ("{1}")').format(val_ipnetwork, opts[1].impl_get_display_name(), typ))
|
||||
if msg is not None:
|
||||
raise ValueError(msg.format(val_netmask,
|
||||
opts[1].impl_get_display_name()))
|
||||
if current_opt == opts[1]:
|
||||
raise ValueError(msg.format(val_netmask,
|
||||
opts[1].impl_get_display_name()))
|
||||
else:
|
||||
raise ValueError(msg.format(val_ipnetwork,
|
||||
opts[0].impl_get_display_name(),
|
||||
typ))
|
||||
|
@ -25,7 +25,7 @@ import weakref
|
||||
from .baseoption import OnlyOption, submulti, STATIC_TUPLE
|
||||
from .symlinkoption import DynSymLinkOption
|
||||
from ..i18n import _
|
||||
from ..setting import log, undefined, debug
|
||||
from ..setting import log, undefined, debug, OptionBag, ConfigBag
|
||||
from ..autolib import carry_out_calculation
|
||||
from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
|
||||
display_list)
|
||||
@ -145,9 +145,13 @@ class Option(OnlyOption):
|
||||
_setattr(self, '_default_multi', default_multi)
|
||||
if unique is not undefined:
|
||||
_setattr(self, '_unique', unique)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(self,
|
||||
undefined,
|
||||
None,
|
||||
undefined)
|
||||
self.impl_validate(default,
|
||||
is_multi=is_multi,
|
||||
config_bag=undefined)
|
||||
option_bag)
|
||||
if (is_multi and default != []) or \
|
||||
(not is_multi and default is not None):
|
||||
if is_multi:
|
||||
@ -180,34 +184,25 @@ class Option(OnlyOption):
|
||||
|
||||
def impl_validate(self,
|
||||
value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
context=undefined,
|
||||
force_index=None,
|
||||
current_opt=undefined,
|
||||
is_multi=None,
|
||||
check_error=True,
|
||||
multi=None):
|
||||
check_error=True):
|
||||
"""
|
||||
:param value: the option's value
|
||||
:param context: Config's context
|
||||
:type context: :class:`tiramisu.config.Config`
|
||||
:type validate: boolean
|
||||
:param force_index: if multi, value has to be a list
|
||||
not if force_index is not None
|
||||
:type force_index: integer
|
||||
"""
|
||||
if current_opt is undefined:
|
||||
current_opt = self
|
||||
if option_bag:
|
||||
config_bag = option_bag.config_bag
|
||||
force_index = option_bag.index
|
||||
else:
|
||||
config_bag = undefined
|
||||
force_index = None
|
||||
|
||||
if check_error and config_bag is not undefined and \
|
||||
not config_bag.validate:
|
||||
# just to check propertieserror
|
||||
self.valid_consistency(current_opt,
|
||||
self.valid_consistency(option_bag,
|
||||
value,
|
||||
context,
|
||||
force_index,
|
||||
check_error,
|
||||
config_bag)
|
||||
check_error)
|
||||
return
|
||||
|
||||
def _is_not_unique(value):
|
||||
@ -233,13 +228,13 @@ class Option(OnlyOption):
|
||||
args.insert(0, ParamValue(val))
|
||||
validator_params_ = Params(tuple(args), kwargs)
|
||||
# Raise ValueError if not valid
|
||||
carry_out_calculation(current_opt,
|
||||
carry_out_calculation(option_bag.ori_option,
|
||||
context=context,
|
||||
callback=validator,
|
||||
callback_params=validator_params_,
|
||||
index=_index,
|
||||
option_bag=option_bag,
|
||||
orig_value=value,
|
||||
config_bag=config_bag,
|
||||
is_validator=True)
|
||||
|
||||
def do_validation(_value,
|
||||
@ -251,13 +246,9 @@ class Option(OnlyOption):
|
||||
if _value is not None:
|
||||
if check_error:
|
||||
# option validation
|
||||
if config_bag is undefined:
|
||||
setting_properties = None
|
||||
else:
|
||||
setting_properties = config_bag.setting_properties
|
||||
self._validate(_value,
|
||||
config_bag,
|
||||
current_opt)
|
||||
option_bag,
|
||||
option_bag.ori_option)
|
||||
if ((check_error and not is_warnings_only) or
|
||||
(not check_error and is_warnings_only)):
|
||||
calculation_validator(_value,
|
||||
@ -265,13 +256,13 @@ class Option(OnlyOption):
|
||||
self._second_level_validation(_value,
|
||||
is_warnings_only)
|
||||
|
||||
if is_multi is None:
|
||||
is_multi = self.impl_is_multi()
|
||||
#if is_multi is None:
|
||||
# is_multi = self.impl_is_multi()
|
||||
|
||||
is_warnings_only = getattr(self, '_warnings_only', False)
|
||||
try:
|
||||
val = value
|
||||
if not is_multi:
|
||||
if not self.impl_is_multi():
|
||||
do_validation(val, None)
|
||||
elif force_index is not None:
|
||||
if self.impl_is_submulti():
|
||||
@ -282,14 +273,6 @@ class Option(OnlyOption):
|
||||
do_validation(val,
|
||||
force_index)
|
||||
else:
|
||||
if multi is not None and self.impl_is_unique() and value in multi:
|
||||
if not self.impl_is_submulti() and len(multi) - 1 >= force_index:
|
||||
lst = list(multi)
|
||||
lst.pop(force_index)
|
||||
else:
|
||||
lst = multi
|
||||
if value in lst:
|
||||
raise ValueError(_('this value is not uniq'))
|
||||
do_validation(val,
|
||||
force_index)
|
||||
elif not isinstance(value, list):
|
||||
@ -309,17 +292,15 @@ class Option(OnlyOption):
|
||||
do_validation(val,
|
||||
idx)
|
||||
|
||||
self.valid_consistency(current_opt,
|
||||
self.valid_consistency(option_bag,
|
||||
value,
|
||||
context,
|
||||
force_index,
|
||||
check_error,
|
||||
config_bag)
|
||||
check_error)
|
||||
except ValueError as err:
|
||||
if debug: # pragma: no cover
|
||||
log.debug('do_validation: value: {0}, index: {1}:'
|
||||
' {2}'.format(val,
|
||||
_index,
|
||||
force_index,
|
||||
err),
|
||||
exc_info=True)
|
||||
if is_warnings_only:
|
||||
@ -443,15 +424,16 @@ class Option(OnlyOption):
|
||||
all_cons_opts,
|
||||
params)
|
||||
#validate default value when add consistency
|
||||
#FIXME validation!
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(self,
|
||||
undefined,
|
||||
None,
|
||||
undefined)
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
undefined)
|
||||
option_bag)
|
||||
self.impl_validate(self.impl_getdefault(),
|
||||
undefined,
|
||||
option_bag,
|
||||
check_error=False)
|
||||
#FIXME
|
||||
#if err:
|
||||
# self._del_consistency()
|
||||
if func != '_cons_not_equal':
|
||||
#consistency could generate warnings or errors
|
||||
self._has_dependency = True
|
||||
@ -465,37 +447,45 @@ class Option(OnlyOption):
|
||||
opt._add_dependency(self)
|
||||
|
||||
def valid_consistency(self,
|
||||
option,
|
||||
option_bag,
|
||||
value,
|
||||
context,
|
||||
index,
|
||||
check_error,
|
||||
config_bag):
|
||||
check_error):
|
||||
if context is not undefined:
|
||||
descr = context.cfgimpl_get_description()
|
||||
# no consistency found at all
|
||||
if descr._cache_consistencies is None:
|
||||
return
|
||||
# get consistencies for this option
|
||||
if isinstance(option, DynSymLinkOption):
|
||||
consistencies = descr._cache_consistencies.get(option.impl_getopt())
|
||||
if isinstance(option_bag.option, DynSymLinkOption):
|
||||
consistencies = descr._cache_consistencies.get(option_bag.option.impl_getopt())
|
||||
else:
|
||||
consistencies = descr._cache_consistencies.get(option)
|
||||
consistencies = descr._cache_consistencies.get(option_bag.option)
|
||||
else:
|
||||
# is no context, get consistencies in option
|
||||
consistencies = option.get_consistencies()
|
||||
if consistencies is not None:
|
||||
consistencies = option_bag.option.get_consistencies()
|
||||
if consistencies:
|
||||
if option_bag.config_bag is undefined:
|
||||
cconfig_bag = undefined
|
||||
elif option_bag.config_bag.force_permissive != True:
|
||||
cconfig_bag = ConfigBag(config=option_bag.config_bag.config,
|
||||
_setting_properties=option_bag.config_bag._setting_properties,
|
||||
force_permissive=True,
|
||||
force_unrestraint=option_bag.config_bag.force_unrestraint,
|
||||
_validate=option_bag.config_bag._validate)
|
||||
else:
|
||||
cconfig_bag = option_bag.config_bag
|
||||
for cons_id, func, all_cons_opts, params in consistencies:
|
||||
warnings_only = params.get('warnings_only', False)
|
||||
if (warnings_only and not check_error) or (not warnings_only and check_error):
|
||||
transitive = params.get('transitive', True)
|
||||
#all_cons_opts[0] is the option where func is set
|
||||
if isinstance(option, DynSymLinkOption):
|
||||
if isinstance(option_bag.ori_option, DynSymLinkOption):
|
||||
opts = []
|
||||
for opt in all_cons_opts:
|
||||
opts.append(DynSymLinkOption(opt(),
|
||||
option._rootpath,
|
||||
option._suffix))
|
||||
option_bag.ori_option._rootpath,
|
||||
option_bag.ori_option._suffix))
|
||||
wopt = opts[0]
|
||||
else:
|
||||
opts = all_cons_opts
|
||||
@ -503,25 +493,23 @@ class Option(OnlyOption):
|
||||
wopt.launch_consistency(self,
|
||||
func,
|
||||
cons_id,
|
||||
option,
|
||||
option_bag,
|
||||
value,
|
||||
context,
|
||||
index,
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive,
|
||||
config_bag)
|
||||
cconfig_bag)
|
||||
|
||||
def _get_consistency_value(self,
|
||||
orig_option,
|
||||
option_bag,
|
||||
current_option,
|
||||
index,
|
||||
cons_id,
|
||||
context,
|
||||
config_bag,
|
||||
value,
|
||||
transitive,
|
||||
func):
|
||||
index = option_bag.index
|
||||
if func in ALLOWED_CONST_LIST:
|
||||
index = None
|
||||
index_ = None
|
||||
@ -529,7 +517,7 @@ class Option(OnlyOption):
|
||||
index_ = None
|
||||
else:
|
||||
index_ = index
|
||||
if orig_option == current_option:
|
||||
if option_bag.ori_option == current_option:
|
||||
# orig_option is current option
|
||||
# we have already value, so use it
|
||||
return value
|
||||
@ -537,14 +525,18 @@ class Option(OnlyOption):
|
||||
#if no context get default value
|
||||
return current_option.impl_getdefault()
|
||||
#otherwise calculate value
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = current_option
|
||||
sconfig_bag.fromconsistency.append(cons_id)
|
||||
sconfig_bag.force_permissive = True
|
||||
path = current_option.impl_getpath(context)
|
||||
coption_bag = OptionBag()
|
||||
coption_bag.set_option(current_option,
|
||||
path,
|
||||
index_,
|
||||
config_bag)
|
||||
cons_ids = option_bag.fromconsistency.copy()
|
||||
cons_ids.append(cons_id)
|
||||
coption_bag.fromconsistency = cons_ids
|
||||
|
||||
opt_value = context.getattr(path,
|
||||
index_,
|
||||
sconfig_bag)
|
||||
coption_bag)
|
||||
if index_ is None and index is not None:
|
||||
if len(opt_value) <= index:
|
||||
opt_value = current_option.impl_getdefault_multi()
|
||||
@ -556,10 +548,9 @@ class Option(OnlyOption):
|
||||
current_opt,
|
||||
func,
|
||||
cons_id,
|
||||
option,
|
||||
option_bag,
|
||||
value,
|
||||
context,
|
||||
index,
|
||||
opts,
|
||||
warnings_only,
|
||||
transitive,
|
||||
@ -583,9 +574,7 @@ class Option(OnlyOption):
|
||||
:param transitive: propertyerror is transitive
|
||||
:type transitive: `boolean`
|
||||
"""
|
||||
#if context is not undefined:
|
||||
# descr = context.cfgimpl_get_description()
|
||||
if config_bag is not undefined and cons_id in config_bag.fromconsistency:
|
||||
if cons_id in option_bag.fromconsistency:
|
||||
return
|
||||
all_cons_vals = []
|
||||
all_cons_opts = []
|
||||
@ -595,31 +584,30 @@ class Option(OnlyOption):
|
||||
opt = opt()
|
||||
is_multi = False
|
||||
try:
|
||||
opt_value = self._get_consistency_value(option,
|
||||
opt_value = self._get_consistency_value(option_bag,
|
||||
opt,
|
||||
index,
|
||||
cons_id,
|
||||
context,
|
||||
config_bag,
|
||||
value,
|
||||
transitive,
|
||||
func)
|
||||
except PropertiesOptionError as err:
|
||||
if debug: # pragma: no cover
|
||||
log.debug('propertyerror in launch_consistency: {0}'.format(err))
|
||||
if transitive:
|
||||
err.set_orig_opt(option)
|
||||
err.set_orig_opt(option_bag.option)
|
||||
raise err
|
||||
else:
|
||||
if opt.impl_is_multi() and index is None and func not in ALLOWED_CONST_LIST:
|
||||
if opt.impl_is_multi() and option_bag.index is None and \
|
||||
func not in ALLOWED_CONST_LIST:
|
||||
len_value = len(opt_value)
|
||||
if length is not None and length != len_value:
|
||||
if context is undefined:
|
||||
return
|
||||
raise ValueError(_('unexpected length of "{}" in constency "{}", should be "{}"'
|
||||
'').format(len(opt_value),
|
||||
opt.impl_get_display_name(),
|
||||
length))
|
||||
raise ValueError(_('unexpected length of "{}" in constency "{}", '
|
||||
'should be "{}"').format(len(opt_value),
|
||||
opt.impl_get_display_name(),
|
||||
length))
|
||||
else:
|
||||
length = len_value
|
||||
is_multi = True
|
||||
|
@ -22,7 +22,7 @@ from copy import copy
|
||||
|
||||
|
||||
from ..i18n import _
|
||||
from ..setting import ConfigBag, groups, undefined, owners
|
||||
from ..setting import ConfigBag, OptionBag, groups, undefined, owners
|
||||
from .baseoption import BaseOption, OnlyOption
|
||||
from .option import ALLOWED_CONST_LIST, DynSymLinkOption
|
||||
from .syndynoptiondescription import SynDynOptionDescription
|
||||
@ -173,11 +173,14 @@ class CacheOptionDescription(BaseOption):
|
||||
'"force_store_value" property').format(
|
||||
option.impl_get_display_name()))
|
||||
if not values._p_.hasvalue(subpath):
|
||||
config_bag = ConfigBag(config=context, option=option)
|
||||
config_bag.properties = frozenset()
|
||||
value = values.getvalue(subpath,
|
||||
None,
|
||||
config_bag)
|
||||
config_bag = ConfigBag(config=context)
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
subpath,
|
||||
None,
|
||||
config_bag)
|
||||
option_bag.properties = frozenset()
|
||||
value = values.getvalue(option_bag)
|
||||
value_setted = True
|
||||
values._p_.setvalue(subpath,
|
||||
value,
|
||||
@ -224,13 +227,14 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
__slots__ = ('_children',)
|
||||
|
||||
def build_dynoptions(self,
|
||||
option,
|
||||
config_bag):
|
||||
option_bag):
|
||||
option = option_bag.option
|
||||
dynopt = option.getsubdyn()
|
||||
rootpath = self.impl_get_path_by_opt(dynopt)
|
||||
ori_index = len(rootpath) + 1
|
||||
subpaths = [rootpath] + option.impl_getpath(config_bag.config)[ori_index:].split('.')[:-1]
|
||||
for suffix in dynopt._impl_get_suffixes(config_bag):
|
||||
subpaths = [rootpath] + option.impl_getpath(
|
||||
option_bag.config_bag.config)[ori_index:].split('.')[:-1]
|
||||
for suffix in dynopt._impl_get_suffixes(option_bag):
|
||||
subpath = '.'.join([subp + suffix for subp in subpaths])
|
||||
if isinstance(option, OnlyOption):
|
||||
yield DynSymLinkOption(option,
|
||||
@ -257,7 +261,12 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
name = option.impl_getname()
|
||||
if option.issubdyn():
|
||||
if byname.startswith(name):
|
||||
for doption in self.build_dynoptions(option, config_bag):
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
None,
|
||||
config_bag)
|
||||
for doption in self.build_dynoptions(option_bag):
|
||||
if byname == doption.impl_getname():
|
||||
dpath = doption.impl_getpath(config_bag.config)
|
||||
return (dpath, doption)
|
||||
@ -319,9 +328,12 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
subpath = ''
|
||||
else:
|
||||
subpath = self.impl_getpath(config_bag.config)
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = child
|
||||
for suffix in child._impl_get_suffixes(sconfig_bag):
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(child,
|
||||
subpath,
|
||||
None,
|
||||
config_bag)
|
||||
for suffix in child._impl_get_suffixes(option_bag):
|
||||
yield SynDynOptionDescription(child,
|
||||
subpath,
|
||||
suffix)
|
||||
@ -339,11 +351,16 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
subconfig,
|
||||
config_bag):
|
||||
for child in self._impl_st_getchildren(only_dyn=True):
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = child
|
||||
#sconfig_bag = config_bag.copy('nooption')
|
||||
#sconfig_bag.option = child
|
||||
cname = child.impl_getname()
|
||||
if name.startswith(cname):
|
||||
for value in child._impl_get_suffixes(sconfig_bag):
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(child,
|
||||
subconfig.cfgimpl_get_path(),
|
||||
None,
|
||||
config_bag)
|
||||
for value in child._impl_get_suffixes(option_bag):
|
||||
if name == cname + value:
|
||||
return SynDynOptionDescription(child,
|
||||
subconfig.cfgimpl_get_path(),
|
||||
|
@ -20,7 +20,7 @@
|
||||
# ____________________________________________________________
|
||||
from .baseoption import OnlyOption
|
||||
from ..i18n import _
|
||||
from ..setting import undefined
|
||||
from ..setting import undefined, OptionBag
|
||||
|
||||
|
||||
class SymLinkOption(OnlyOption):
|
||||
@ -104,22 +104,21 @@ class DynSymLinkOption(object):
|
||||
|
||||
def impl_validate(self,
|
||||
value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
context=undefined,
|
||||
force_index=None,
|
||||
current_opt=undefined,
|
||||
is_multi=None,
|
||||
check_error=True,
|
||||
multi=None):
|
||||
# add current_opt !
|
||||
check_error=True):
|
||||
context = option_bag.config_bag.config
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(self._opt,
|
||||
self.impl_getpath(context),
|
||||
option_bag.index,
|
||||
option_bag.config_bag)
|
||||
soption_bag.ori_option = option_bag.option
|
||||
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
|
||||
self._opt.impl_validate(value,
|
||||
config_bag,
|
||||
context,
|
||||
force_index,
|
||||
current_opt=self,
|
||||
is_multi=is_multi,
|
||||
check_error=check_error,
|
||||
multi=multi)
|
||||
soption_bag,
|
||||
context=context,
|
||||
check_error=check_error)
|
||||
|
||||
def impl_is_dynsymlinkoption(self):
|
||||
return True
|
||||
|
@ -117,77 +117,99 @@ debug = False
|
||||
static_set = frozenset()
|
||||
|
||||
|
||||
class ConfigBag(object):
|
||||
__slots__ = ('default',
|
||||
'config',
|
||||
'option',
|
||||
'ori_option',
|
||||
'properties',
|
||||
'setting_properties',
|
||||
'force_permissive',
|
||||
'force_unrestraint',
|
||||
'trusted_cached_properties',
|
||||
'fromconsistency',
|
||||
'_validator'
|
||||
class OptionBag:
|
||||
__slots__ = ('option', # current option
|
||||
'path',
|
||||
'index',
|
||||
'config_bag',
|
||||
'ori_option', # original option (for example useful for symlinkoption)
|
||||
'properties', # properties of current option
|
||||
'apply_requires',
|
||||
'fromconsistency' # history for consistency
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
self.option = None
|
||||
self.fromconsistency = []
|
||||
|
||||
def set_option(self,
|
||||
option,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
if self.option != None:
|
||||
raise Exception('hu?')
|
||||
if path is None:
|
||||
path = config_bag.config.cfgimpl_get_description().impl_get_path_by_opt(option)
|
||||
self.path = path
|
||||
self.index = index
|
||||
self.option = option
|
||||
self.config_bag = config_bag
|
||||
|
||||
def __getattr__(self, key):
|
||||
if key == 'properties':
|
||||
settings = self.config_bag.config.cfgimpl_get_settings()
|
||||
self.properties = settings.getproperties(self, apply_requires=self.apply_requires)
|
||||
return self.properties
|
||||
elif key == 'ori_option':
|
||||
return self.option
|
||||
elif key == 'apply_requires':
|
||||
return True
|
||||
raise KeyError('unknown key {} for OptionBag'.format(key))
|
||||
|
||||
|
||||
class ConfigBag:
|
||||
__slots__ = ('config', # link to the current config (context)
|
||||
'_setting_properties', # properties for current config
|
||||
'force_permissive', # force permissive
|
||||
'force_unrestraint', # do not validate properties
|
||||
'_validate', # validate
|
||||
)
|
||||
def __init__(self, config, **kwargs):
|
||||
self.default = {'force_permissive': False,
|
||||
'force_unrestraint': False,
|
||||
'trusted_cached_properties': True,
|
||||
}
|
||||
self.force_permissive = False
|
||||
self.force_unrestraint = False
|
||||
self.config = config
|
||||
self._validator = True
|
||||
self.fromconsistency = []
|
||||
self._validate = True
|
||||
for key, value in kwargs.items():
|
||||
if value != self.default.get(key):
|
||||
setattr(self, key, value)
|
||||
setattr(self, key, value)
|
||||
|
||||
def __getattr__(self, key):
|
||||
if key == 'validate_properties':
|
||||
return not self.force_unrestraint
|
||||
if key == 'validate':
|
||||
if self.setting_properties is not None:
|
||||
return 'validator' in self.setting_properties
|
||||
return self._validator
|
||||
if self._validate and self._setting_properties is not None:
|
||||
return 'validator' in self._setting_properties
|
||||
return self._validate
|
||||
if key == 'setting_properties':
|
||||
if self.force_unrestraint:
|
||||
return None
|
||||
self.setting_properties = self.config.cfgimpl_get_settings().get_context_properties()
|
||||
return self.setting_properties
|
||||
return self._setting_properties
|
||||
if key == '_setting_properties':
|
||||
self._setting_properties = self.config.cfgimpl_get_settings().get_context_properties()
|
||||
if self._validate is False:
|
||||
self._setting_properties = self._setting_properties - {'validator'}
|
||||
return self._setting_properties
|
||||
if key not in self.__slots__:
|
||||
raise KeyError('unknown key {}'.format(key))
|
||||
return self.default.get(key)
|
||||
raise KeyError('unknown key {} for ConfigBag'.format(key))
|
||||
return None
|
||||
|
||||
def __setattr__(self, key, value):
|
||||
if key == 'validate':
|
||||
if self.setting_properties is not None:
|
||||
if value is False:
|
||||
self.setting_properties = frozenset(set(self.setting_properties) - {'validator'})
|
||||
else:
|
||||
self.setting_properties = frozenset(set(self.setting_properties) | {'validator'})
|
||||
else:
|
||||
self._validator = value
|
||||
try:
|
||||
del self._setting_properties
|
||||
except AttributeError:
|
||||
pass
|
||||
self._validate = value
|
||||
else:
|
||||
super().__setattr__(key, value)
|
||||
|
||||
def delete(self, key):
|
||||
try:
|
||||
return self.__delattr__(key)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def copy(self, filters='all'):
|
||||
def copy(self):
|
||||
kwargs = {}
|
||||
for key in self.__slots__:
|
||||
if filters == 'nooption' and (key.startswith('option') or \
|
||||
key == 'properties'):
|
||||
continue
|
||||
if key == 'fromconsistency':
|
||||
if key == 'fromconsistency' and self.fromconsistency != []:
|
||||
kwargs['fromconsistency'] = copy(self.fromconsistency)
|
||||
elif key != 'default':
|
||||
value = getattr(self, key)
|
||||
if value != self.default.get(key):
|
||||
kwargs[key] = value
|
||||
else:
|
||||
kwargs[key] = getattr(self, key)
|
||||
return ConfigBag(**kwargs)
|
||||
|
||||
|
||||
@ -357,13 +379,14 @@ class Settings(object):
|
||||
return props
|
||||
|
||||
def getproperties(self,
|
||||
path,
|
||||
index,
|
||||
config_bag,
|
||||
option_bag,
|
||||
apply_requires=True):
|
||||
"""
|
||||
"""
|
||||
opt = config_bag.option
|
||||
opt = option_bag.option
|
||||
config_bag = option_bag.config_bag
|
||||
path = option_bag.path
|
||||
index = option_bag.index
|
||||
if opt.impl_is_symlinkoption():
|
||||
opt = opt.impl_getopt()
|
||||
path = opt.impl_getpath(self._getcontext())
|
||||
@ -384,17 +407,11 @@ class Settings(object):
|
||||
props = self._p_.getproperties(path,
|
||||
opt.impl_getproperties())
|
||||
else:
|
||||
props = meta.cfgimpl_get_settings().getproperties(path,
|
||||
index,
|
||||
config_bag,
|
||||
props = meta.cfgimpl_get_settings().getproperties(option_bag,
|
||||
apply_requires)
|
||||
if apply_requires:
|
||||
props |= self.apply_requires(path,
|
||||
opt.impl_getrequires(),
|
||||
index,
|
||||
False,
|
||||
config_bag,
|
||||
opt.impl_get_display_name())
|
||||
props |= self.apply_requires(option_bag,
|
||||
False)
|
||||
props -= self.getpermissive(opt,
|
||||
path)
|
||||
if apply_requires:
|
||||
@ -421,12 +438,8 @@ class Settings(object):
|
||||
return self._pp_.getpermissive(path)
|
||||
|
||||
def apply_requires(self,
|
||||
path,
|
||||
current_requires,
|
||||
index,
|
||||
readable,
|
||||
config_bag,
|
||||
name):
|
||||
option_bag,
|
||||
readable):
|
||||
"""carries out the jit (just in time) requirements between options
|
||||
|
||||
a requirement is a tuple of this form that comes from the option's
|
||||
@ -470,7 +483,7 @@ class Settings(object):
|
||||
:param path: the option's path in the config
|
||||
:type path: str
|
||||
"""
|
||||
#current_requires = opt.impl_getrequires()
|
||||
current_requires = option_bag.option.impl_getrequires()
|
||||
|
||||
# filters the callbacks
|
||||
if readable:
|
||||
@ -489,32 +502,38 @@ class Settings(object):
|
||||
breaked = False
|
||||
for option, expected in exps:
|
||||
reqpath = option.impl_getpath(context)
|
||||
#FIXME c'est un peut tard !
|
||||
if reqpath.startswith(path + '.'):
|
||||
#FIXME c'est un peu tard !
|
||||
if reqpath.startswith(option_bag.path + '.'):
|
||||
raise RequirementError(_("malformed requirements "
|
||||
"imbrication detected for option:"
|
||||
" '{0}' with requirement on: "
|
||||
"'{1}'").format(path, reqpath))
|
||||
"'{1}'").format(option_bag.path, reqpath))
|
||||
idx = None
|
||||
is_indexed = False
|
||||
if option.impl_is_master_slaves('slave'):
|
||||
idx = index
|
||||
idx = option_bag.index
|
||||
elif option.impl_is_multi():
|
||||
is_indexed = True
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
if config_bag.option == option:
|
||||
sconfig_bag.setting_properties = None
|
||||
sconfig_bag.force_unrestraint= False
|
||||
sconfig_bag.validate = False
|
||||
else:
|
||||
sconfig_bag.force_permissive = True
|
||||
sconfig_bag.option = option
|
||||
config_bag = ConfigBag(config=option_bag.config_bag.config,
|
||||
_setting_properties=option_bag.config_bag._setting_properties,
|
||||
force_permissive=True,
|
||||
force_unrestraint=option_bag.config_bag.force_unrestraint,
|
||||
_validate=option_bag.config_bag._validate)
|
||||
soption_bag = OptionBag()
|
||||
soption_bag.set_option(option,
|
||||
reqpath,
|
||||
idx,
|
||||
config_bag)
|
||||
soption_bag.config_bag.force_permissive = True
|
||||
if option_bag.option == option:
|
||||
soption_bag.config_bag.force_unrestraint = True
|
||||
soption_bag.config_bag.validate = False
|
||||
soption_bag.apply_requires = False
|
||||
try:
|
||||
value = context.getattr(reqpath,
|
||||
idx,
|
||||
sconfig_bag)
|
||||
soption_bag)
|
||||
if is_indexed:
|
||||
value = value[index]
|
||||
value = value[option_bag.index]
|
||||
except PropertiesOptionError as err:
|
||||
properties = err.proptype
|
||||
if not transitive:
|
||||
@ -532,19 +551,15 @@ class Settings(object):
|
||||
prop_msg = _('properties')
|
||||
raise RequirementError(_('cannot access to option "{0}" because '
|
||||
'required option "{1}" has {2} {3}'
|
||||
'').format(name,
|
||||
'').format(option_bag.option.impl_get_display_name(),
|
||||
option.impl_get_display_name(),
|
||||
prop_msg,
|
||||
display_list(list(properties), add_quote=True)))
|
||||
# transitive action, add action
|
||||
if operator != 'and':
|
||||
if readable:
|
||||
for msg in self.apply_requires(err._path,
|
||||
err._requires,
|
||||
err._index,
|
||||
True,
|
||||
err._config_bag,
|
||||
err._name).values():
|
||||
for msg in self.apply_requires(err._option_bag,
|
||||
True).values():
|
||||
calc_properties.setdefault(action, []).extend(msg)
|
||||
else:
|
||||
calc_properties.add(action)
|
||||
@ -587,23 +602,25 @@ class Settings(object):
|
||||
def setproperties(self,
|
||||
path,
|
||||
properties,
|
||||
config_bag):
|
||||
option_bag):
|
||||
"""save properties for specified path
|
||||
(never save properties if same has option properties)
|
||||
"""
|
||||
# should have index !!!
|
||||
if self._getcontext().cfgimpl_get_meta() is not None:
|
||||
raise ConfigError(_('cannot change property with metaconfig'))
|
||||
if path is not None and config_bag.option.impl_getrequires() is not None:
|
||||
not_allowed_props = properties & getattr(config_bag.option, '_calc_properties', static_set)
|
||||
if path is not None and option_bag.option.impl_getrequires() is not None:
|
||||
not_allowed_props = properties & \
|
||||
getattr(option_bag.option, '_calc_properties', static_set)
|
||||
if not_allowed_props:
|
||||
raise ValueError(_('cannot set property {} for option "{}" this property is calculated'
|
||||
'').format(display_list(list(not_allowed_props), add_quote=True),
|
||||
config_bag.option.impl_get_display_name()))
|
||||
if config_bag is None:
|
||||
raise ValueError(_('cannot set property {} for option "{}" this property is '
|
||||
'calculated').format(display_list(list(not_allowed_props),
|
||||
add_quote=True),
|
||||
option_bag.option.impl_get_display_name()))
|
||||
if option_bag is None:
|
||||
opt = None
|
||||
else:
|
||||
opt = config_bag.option
|
||||
opt = option_bag.option
|
||||
if opt and opt.impl_is_symlinkoption():
|
||||
raise TypeError(_("can't assign property to the symlinkoption \"{}\""
|
||||
"").format(opt.impl_get_display_name()))
|
||||
@ -616,21 +633,20 @@ class Settings(object):
|
||||
self._p_.setproperties(path,
|
||||
properties)
|
||||
#values too because of slave values could have a PropertiesOptionError has value
|
||||
self._getcontext().cfgimpl_reset_cache(opt,
|
||||
path,
|
||||
config_bag)
|
||||
self._getcontext().cfgimpl_reset_cache(option_bag)
|
||||
if option_bag is not None:
|
||||
try:
|
||||
del option_bag.properties
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def set_context_permissive(self,
|
||||
permissive):
|
||||
self.setpermissive(None,
|
||||
None,
|
||||
None,
|
||||
permissive)
|
||||
|
||||
def setpermissive(self,
|
||||
opt,
|
||||
path,
|
||||
config_bag,
|
||||
option_bag,
|
||||
permissives):
|
||||
"""
|
||||
enables us to put the permissives in the storage
|
||||
@ -645,51 +661,55 @@ class Settings(object):
|
||||
raise ConfigError(_('cannot change permissive with metaconfig'))
|
||||
if not isinstance(permissives, frozenset):
|
||||
raise TypeError(_('permissive must be a frozenset'))
|
||||
if opt and opt.impl_is_symlinkoption():
|
||||
raise TypeError(_("can't assign permissive to the symlinkoption \"{}\""
|
||||
"").format(opt.impl_get_display_name()))
|
||||
if option_bag is not None:
|
||||
opt = option_bag.option
|
||||
if opt and opt.impl_is_symlinkoption():
|
||||
raise TypeError(_("can't assign permissive to the symlinkoption \"{}\""
|
||||
"").format(opt.impl_get_display_name()))
|
||||
path = option_bag.path
|
||||
else:
|
||||
path = None
|
||||
forbidden_permissives = FORBIDDEN_SET_PERMISSIVES & permissives
|
||||
if forbidden_permissives:
|
||||
raise ConfigError(_('cannot add those permissives: {0}').format(
|
||||
' '.join(forbidden_permissives)))
|
||||
self._pp_.setpermissive(path, permissives)
|
||||
self._getcontext().cfgimpl_reset_cache(opt,
|
||||
path,
|
||||
config_bag)
|
||||
if option_bag is not None:
|
||||
self._getcontext().cfgimpl_reset_cache(option_bag)
|
||||
|
||||
#____________________________________________________________
|
||||
# reset methods
|
||||
|
||||
def reset(self,
|
||||
opt,
|
||||
path,
|
||||
config_bag,
|
||||
all_properties=False):
|
||||
option_bag):
|
||||
# all_properties=False):
|
||||
if self._getcontext().cfgimpl_get_meta() is not None:
|
||||
raise ConfigError(_('cannot change property with metaconfig'))
|
||||
if option_bag is None:
|
||||
opt = None
|
||||
else:
|
||||
opt = option_bag.option
|
||||
if opt and opt.impl_is_symlinkoption():
|
||||
raise TypeError(_("can't reset properties to the symlinkoption \"{}\""
|
||||
"").format(opt.impl_get_display_name()))
|
||||
if all_properties and (path or opt):
|
||||
raise ValueError(_('opt and all_properties must not be set '
|
||||
'together in reset'))
|
||||
if all_properties:
|
||||
self._p_.reset_all_properties()
|
||||
#if all_properties and (path or opt):
|
||||
# raise ValueError(_('opt and all_properties must not be set '
|
||||
# 'together in reset'))
|
||||
#if all_properties:
|
||||
# self._p_.reset_all_properties()
|
||||
else:
|
||||
if opt is not None and path is None:
|
||||
path = opt.impl_getpath(self._getcontext())
|
||||
if opt is not None:
|
||||
path = option_bag.path
|
||||
else:
|
||||
path = None
|
||||
self._p_.delproperties(path)
|
||||
self._getcontext().cfgimpl_reset_cache(opt,
|
||||
path,
|
||||
config_bag)
|
||||
self._getcontext().cfgimpl_reset_cache(option_bag)
|
||||
|
||||
#____________________________________________________________
|
||||
# validate properties
|
||||
|
||||
def validate_properties(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag):
|
||||
"""
|
||||
validation upon the properties related to `opt`
|
||||
|
||||
@ -697,70 +717,56 @@ class Settings(object):
|
||||
:param force_permissive: behaves as if the permissive property
|
||||
was present
|
||||
"""
|
||||
opt = config_bag.option
|
||||
|
||||
# calc properties
|
||||
self_properties = config_bag.properties
|
||||
if self_properties is None:
|
||||
self_properties = self.getproperties(path,
|
||||
index,
|
||||
config_bag)
|
||||
config_bag.properties = self_properties
|
||||
self_properties = option_bag.properties
|
||||
config_bag = option_bag.config_bag
|
||||
properties = self_properties & config_bag.setting_properties - {'frozen', 'mandatory', 'empty'}
|
||||
|
||||
# remove permissive properties
|
||||
if (config_bag.force_permissive is True or 'permissive' in config_bag.setting_properties) and properties:
|
||||
if (config_bag.force_permissive is True or \
|
||||
'permissive' in config_bag.setting_properties) and properties:
|
||||
# remove global permissive if need
|
||||
properties -= self.get_context_permissive()
|
||||
# at this point an option should not remain in properties
|
||||
if properties != frozenset():
|
||||
raise PropertiesOptionError(path,
|
||||
index,
|
||||
config_bag,
|
||||
raise PropertiesOptionError(option_bag,
|
||||
properties,
|
||||
self)
|
||||
|
||||
def validate_mandatory(self,
|
||||
path,
|
||||
index,
|
||||
value,
|
||||
config_bag):
|
||||
option_bag):
|
||||
values = self._getcontext().cfgimpl_get_values()
|
||||
opt = config_bag.option
|
||||
opt = option_bag.option
|
||||
config_bag = option_bag.config_bag
|
||||
is_mandatory = False
|
||||
if config_bag.setting_properties and 'mandatory' in config_bag.setting_properties:
|
||||
if (config_bag.force_permissive is True or 'permissive' in config_bag.setting_properties) and \
|
||||
'mandatory' in self.get_context_permissive():
|
||||
pass
|
||||
elif 'mandatory' in config_bag.properties and values.isempty(opt,
|
||||
elif 'mandatory' in option_bag.properties and values.isempty(opt,
|
||||
value,
|
||||
index=index):
|
||||
index=option_bag.index):
|
||||
is_mandatory = True
|
||||
if 'empty' in config_bag.properties and values.isempty(opt,
|
||||
if 'empty' in option_bag.properties and values.isempty(opt,
|
||||
value,
|
||||
force_allow_empty_list=True,
|
||||
index=index):
|
||||
index=option_bag.index):
|
||||
is_mandatory = True
|
||||
if is_mandatory:
|
||||
raise PropertiesOptionError(path,
|
||||
index,
|
||||
config_bag,
|
||||
raise PropertiesOptionError(option_bag,
|
||||
['mandatory'],
|
||||
self)
|
||||
|
||||
def validate_frozen(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
if config_bag.setting_properties and \
|
||||
('everything_frozen' in config_bag.setting_properties or
|
||||
'frozen' in config_bag.properties) and \
|
||||
not ((config_bag.force_permissive is True or
|
||||
'permissive' in config_bag.setting_properties) and
|
||||
option_bag):
|
||||
if option_bag.config_bag.setting_properties and \
|
||||
('everything_frozen' in option_bag.config_bag.setting_properties or
|
||||
'frozen' in option_bag.properties) and \
|
||||
not ((option_bag.config_bag.force_permissive is True or
|
||||
'permissive' in option_bag.config_bag.setting_properties) and
|
||||
'frozen' in self.get_context_permissive()):
|
||||
raise PropertiesOptionError(path,
|
||||
index,
|
||||
config_bag,
|
||||
raise PropertiesOptionError(option_bag,
|
||||
['frozen'],
|
||||
self)
|
||||
return False
|
||||
|
@ -44,13 +44,14 @@ class Cache(DictCache):
|
||||
_display_classname(self),
|
||||
id(self)))
|
||||
self._setcache(path, index, val, time())
|
||||
if DEBUG:
|
||||
print('not setcache {} with index {} and value {} in {} ({})'.format(path,
|
||||
index,
|
||||
val,
|
||||
_display_classname(self),
|
||||
id(self)))
|
||||
return
|
||||
elif DEBUG:
|
||||
print('not setcache {} with index {} and value {} and props {} and {} in {} ({})'.format(path,
|
||||
index,
|
||||
val,
|
||||
props,
|
||||
self_props,
|
||||
_display_classname(self),
|
||||
id(self)))
|
||||
|
||||
def getcache(self,
|
||||
path,
|
||||
@ -119,5 +120,5 @@ class Cache(DictCache):
|
||||
example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}}
|
||||
"""
|
||||
if DEBUG:
|
||||
print('get_chached', self._cache)
|
||||
print('get_chached {} for {} ({})'.format(self._cache, _display_classname(self), id(self)))
|
||||
return self._get_cached()
|
||||
|
@ -17,7 +17,7 @@
|
||||
# ____________________________________________________________
|
||||
import weakref
|
||||
from .error import ConfigError, PropertiesOptionError
|
||||
from .setting import owners, expires_time, undefined, forbidden_owners
|
||||
from .setting import owners, expires_time, undefined, forbidden_owners, OptionBag, ConfigBag
|
||||
from .autolib import carry_out_calculation
|
||||
from .i18n import _
|
||||
|
||||
@ -63,9 +63,7 @@ class Values(object):
|
||||
# get value
|
||||
|
||||
def get_cached_value(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag):
|
||||
"""get value directly in cache if set
|
||||
otherwise calculated value and set it in cache
|
||||
|
||||
@ -81,40 +79,36 @@ class Values(object):
|
||||
:returns: value
|
||||
"""
|
||||
# try to retrive value in cache
|
||||
setting_properties = config_bag.setting_properties
|
||||
is_cached, value = self._p_.getcache(path,
|
||||
setting_properties = option_bag.config_bag.setting_properties
|
||||
is_cached, value = self._p_.getcache(option_bag.path,
|
||||
expires_time,
|
||||
index,
|
||||
option_bag.index,
|
||||
setting_properties,
|
||||
config_bag.properties,
|
||||
option_bag.properties,
|
||||
'value')
|
||||
|
||||
if not is_cached:
|
||||
# no cached value so get value
|
||||
value = self.getvalue(path,
|
||||
index,
|
||||
config_bag)
|
||||
value = self.getvalue(option_bag)
|
||||
# validate value
|
||||
context = self._getcontext()
|
||||
opt = config_bag.option
|
||||
opt = option_bag.option
|
||||
opt.impl_validate(value,
|
||||
option_bag,
|
||||
context=context,
|
||||
force_index=index,
|
||||
check_error=True,
|
||||
config_bag=config_bag)
|
||||
check_error=True)
|
||||
if setting_properties and 'warnings' in setting_properties:
|
||||
opt.impl_validate(value,
|
||||
option_bag,
|
||||
context=context,
|
||||
force_index=index,
|
||||
check_error=False,
|
||||
config_bag=config_bag)
|
||||
check_error=False)
|
||||
# store value in cache
|
||||
if not is_cached:
|
||||
self._p_.setcache(path,
|
||||
index,
|
||||
self._p_.setcache(option_bag.path,
|
||||
option_bag.index,
|
||||
value,
|
||||
setting_properties,
|
||||
config_bag.properties)
|
||||
option_bag.properties)
|
||||
if isinstance(value, list):
|
||||
# return a copy, so value cannot be modified
|
||||
return value.copy()
|
||||
@ -122,9 +116,7 @@ class Values(object):
|
||||
return value
|
||||
|
||||
def getvalue(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag):
|
||||
"""actually retrieves the value
|
||||
|
||||
:param path: the path of the `Option`
|
||||
@ -134,37 +126,22 @@ class Values(object):
|
||||
"""
|
||||
# get owner and value from store
|
||||
# index allowed only for slave
|
||||
opt = config_bag.option
|
||||
is_slave = opt.impl_is_master_slaves('slave')
|
||||
index = option_bag.index
|
||||
is_slave = option_bag.option.impl_is_master_slaves('slave')
|
||||
if index is None or not is_slave:
|
||||
_index = None
|
||||
else:
|
||||
_index = index
|
||||
owner, value = self._p_.getowner(path,
|
||||
owner, value = self._p_.getowner(option_bag.path,
|
||||
owners.default,
|
||||
index=_index,
|
||||
with_value=True)
|
||||
|
||||
if owner != owners.default:
|
||||
if config_bag.setting_properties is None:
|
||||
# get property without apply requires
|
||||
settings = self._getcontext().cfgimpl_get_settings()
|
||||
self_properties = settings.getproperties(path,
|
||||
index,
|
||||
config_bag,
|
||||
apply_requires=False)
|
||||
else:
|
||||
# if a value is store in storage, check if not frozen + force_default_on_freeze
|
||||
# if frozen + force_default_on_freeze => force default value
|
||||
self_properties = config_bag.properties
|
||||
if self_properties is None:
|
||||
settings = self._getcontext().cfgimpl_get_settings()
|
||||
self_properties = settings.getproperties(path,
|
||||
index,
|
||||
config_bag)
|
||||
config_bag.properties = self_properties
|
||||
if not ('frozen' in self_properties and \
|
||||
'force_default_on_freeze' in self_properties):
|
||||
# if a value is store in storage, check if not frozen + force_default_on_freeze
|
||||
# if frozen + force_default_on_freeze => force default value
|
||||
if not ('frozen' in option_bag.properties and \
|
||||
'force_default_on_freeze' in option_bag.properties):
|
||||
if index is not None and not is_slave:
|
||||
if len(value) > index:
|
||||
return value[index]
|
||||
@ -172,14 +149,10 @@ class Values(object):
|
||||
#so return default value
|
||||
else:
|
||||
return value
|
||||
return self.getdefaultvalue(path,
|
||||
index,
|
||||
config_bag)
|
||||
return self.getdefaultvalue(option_bag)
|
||||
|
||||
def getdefaultvalue(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag):
|
||||
"""get default value:
|
||||
- get meta config value or
|
||||
- get calculated value or
|
||||
@ -192,36 +165,43 @@ class Values(object):
|
||||
:returns: default value
|
||||
"""
|
||||
context = self._getcontext()
|
||||
opt = config_bag.option
|
||||
config_bag = option_bag.config_bag
|
||||
opt = option_bag.option
|
||||
index = option_bag.index
|
||||
def _reset_cache(_value):
|
||||
is_cache, cache_value = self._p_.getcache(path,
|
||||
is_cache, cache_value = self._p_.getcache(option_bag.path,
|
||||
expires_time,
|
||||
index,
|
||||
config_bag.setting_properties,
|
||||
config_bag.properties,
|
||||
option_bag.properties,
|
||||
'value')
|
||||
if is_cache and cache_value == _value:
|
||||
# calculation return same value as previous value,
|
||||
# so do not invalidate cache
|
||||
return
|
||||
# calculated value is a new value, so reset cache
|
||||
context.cfgimpl_reset_cache(opt,
|
||||
path,
|
||||
config_bag)
|
||||
context.cfgimpl_reset_cache(option_bag)
|
||||
|
||||
if opt.impl_is_master_slaves('slave'):
|
||||
index_ = index
|
||||
else:
|
||||
index_ = None
|
||||
if self._is_meta(path,
|
||||
index_,
|
||||
config_bag):
|
||||
if option_bag.index != index_:
|
||||
moption_bag = OptionBag()
|
||||
moption_bag.set_option(opt,
|
||||
option_bag.path,
|
||||
index_,
|
||||
config_bag)
|
||||
moption_bag.fromconsistency = option_bag.fromconsistency.copy()
|
||||
else:
|
||||
moption_bag = option_bag
|
||||
if self._is_meta(moption_bag):
|
||||
meta = context.cfgimpl_get_meta()
|
||||
# retrieved value from meta config
|
||||
try:
|
||||
value = meta.getattr(path,
|
||||
index,
|
||||
config_bag)
|
||||
# FIXME could have different property!
|
||||
value = meta.getattr(moption_bag.path,
|
||||
moption_bag)
|
||||
except PropertiesOptionError:
|
||||
# if properties error, return an other default value
|
||||
# unexpected error, should not happened
|
||||
@ -237,7 +217,7 @@ class Values(object):
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
index=index,
|
||||
config_bag=config_bag)
|
||||
option_bag=option_bag)
|
||||
if isinstance(value, list) and index is not None:
|
||||
# if value is a list and index is set
|
||||
if opt.impl_is_submulti() and (value == [] or not isinstance(value[0], list)):
|
||||
@ -309,116 +289,94 @@ class Values(object):
|
||||
# set value
|
||||
|
||||
def setvalue(self,
|
||||
path,
|
||||
index,
|
||||
value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
_commit):
|
||||
|
||||
context = self._getcontext()
|
||||
owner = context.cfgimpl_get_settings().getowner()
|
||||
if config_bag.validate:
|
||||
if index is not None or config_bag.option._has_consistencies(context):
|
||||
if option_bag.config_bag.validate:
|
||||
if option_bag.index is not None or option_bag.option._has_consistencies(context):
|
||||
# set value to a fake config when option has dependency
|
||||
# validation will be complet in this case (consistency, ...)
|
||||
tested_context = context._gen_fake_values()
|
||||
sconfig_bag = config_bag.copy()
|
||||
sconfig_bag.validate = False
|
||||
tested_context.cfgimpl_get_values().setvalue(path,
|
||||
index,
|
||||
value,
|
||||
sconfig_bag,
|
||||
True)
|
||||
sconfig_bag.validate = True
|
||||
tested_context.getattr(path,
|
||||
index,
|
||||
sconfig_bag)
|
||||
#sconfig_bag = config_bag.copy()
|
||||
ori_validate = option_bag.config_bag.validate
|
||||
if ori_validate is True:
|
||||
option_bag.config_bag.validate = False
|
||||
try:
|
||||
tested_context.cfgimpl_get_values().setvalue(value,
|
||||
option_bag,
|
||||
True)
|
||||
option_bag.config_bag.validate = True
|
||||
tested_context.getattr(option_bag.path,
|
||||
option_bag)
|
||||
except Exception as exc:
|
||||
if ori_validate is True:
|
||||
option_bag.config_bag.validate = True
|
||||
raise exc
|
||||
else:
|
||||
self.setvalue_validation(path,
|
||||
index,
|
||||
value,
|
||||
config_bag)
|
||||
self.setvalue_validation(value,
|
||||
option_bag)
|
||||
|
||||
self._setvalue(path,
|
||||
index,
|
||||
self._setvalue(option_bag,
|
||||
value,
|
||||
owner,
|
||||
config_bag,
|
||||
commit=_commit)
|
||||
|
||||
def setvalue_validation(self,
|
||||
path,
|
||||
index,
|
||||
value,
|
||||
config_bag):
|
||||
option_bag):
|
||||
|
||||
context = self._getcontext()
|
||||
settings = context.cfgimpl_get_settings()
|
||||
# First validate properties with this value
|
||||
self_properties = config_bag.properties
|
||||
if self_properties is None:
|
||||
self_properties = settings.getproperties(path,
|
||||
index,
|
||||
config_bag)
|
||||
config_bag.properties = self_properties
|
||||
opt = config_bag.option
|
||||
settings.validate_frozen(path,
|
||||
index,
|
||||
config_bag)
|
||||
settings.validate_mandatory(path,
|
||||
index,
|
||||
value,
|
||||
config_bag)
|
||||
opt = option_bag.option
|
||||
settings.validate_frozen(option_bag)
|
||||
settings.validate_mandatory(value,
|
||||
option_bag)
|
||||
# Value must be valid for option
|
||||
opt.impl_validate(value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
context,
|
||||
check_error=True,
|
||||
force_index=index)
|
||||
if config_bag.setting_properties and 'warnings' in config_bag.setting_properties:
|
||||
check_error=True)
|
||||
if option_bag.config_bag.setting_properties and \
|
||||
'warnings' in option_bag.config_bag.setting_properties:
|
||||
# No error found so emit warnings
|
||||
opt.impl_validate(value,
|
||||
config_bag,
|
||||
option_bag,
|
||||
context,
|
||||
check_error=False,
|
||||
force_index=index)
|
||||
check_error=False)
|
||||
|
||||
def _setvalue(self,
|
||||
path,
|
||||
index,
|
||||
option_bag,
|
||||
value,
|
||||
owner,
|
||||
config_bag,
|
||||
commit=True):
|
||||
|
||||
|
||||
self._getcontext().cfgimpl_reset_cache(config_bag.option,
|
||||
path,
|
||||
config_bag)
|
||||
self._getcontext().cfgimpl_reset_cache(option_bag)
|
||||
if isinstance(value, list):
|
||||
# copy
|
||||
value = list(value)
|
||||
self._p_.setvalue(path,
|
||||
value = value.copy()
|
||||
self._p_.setvalue(option_bag.path,
|
||||
value,
|
||||
owner,
|
||||
index,
|
||||
option_bag.index,
|
||||
commit)
|
||||
|
||||
def _is_meta(self,
|
||||
path,
|
||||
index,
|
||||
config_bag,
|
||||
option_bag,
|
||||
force_owner_is_default=False):
|
||||
|
||||
if not force_owner_is_default and self._p_.hasvalue(path,
|
||||
index=index):
|
||||
if not force_owner_is_default and self._p_.hasvalue(option_bag.path,
|
||||
index=option_bag.index):
|
||||
# has already a value, so not meta
|
||||
return False
|
||||
context = self._getcontext()
|
||||
meta = context.cfgimpl_get_meta()
|
||||
if meta is None:
|
||||
return False
|
||||
opt = config_bag.option
|
||||
opt = option_bag.option
|
||||
if opt.impl_is_master_slaves('slave'):
|
||||
master = opt.impl_get_master_slaves().getmaster()
|
||||
masterp = master.impl_getpath(context)
|
||||
@ -426,29 +384,23 @@ class Values(object):
|
||||
if self._p_.hasvalue(masterp,
|
||||
index=None):
|
||||
return False
|
||||
return not meta.cfgimpl_get_values().is_default_owner(path,
|
||||
index,
|
||||
config_bag)
|
||||
return not meta.cfgimpl_get_values().is_default_owner(option_bag)
|
||||
|
||||
|
||||
#______________________________________________________________________
|
||||
# owner
|
||||
|
||||
def is_default_owner(self,
|
||||
path,
|
||||
index,
|
||||
config_bag,
|
||||
option_bag,
|
||||
validate_meta=undefined):
|
||||
return self._getowner(path,
|
||||
index,
|
||||
config_bag,
|
||||
validate_meta=validate_meta,
|
||||
only_default=True) == owners.default
|
||||
return self.getowner(option_bag,
|
||||
validate_meta=validate_meta,
|
||||
only_default=True) == owners.default
|
||||
|
||||
def getowner(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag,
|
||||
validate_meta=True,
|
||||
only_default=False):
|
||||
"""
|
||||
retrieves the option's owner
|
||||
|
||||
@ -457,199 +409,144 @@ class Values(object):
|
||||
was present
|
||||
:returns: a `setting.owners.Owner` object
|
||||
"""
|
||||
return self._getowner(path,
|
||||
index,
|
||||
config_bag)
|
||||
|
||||
def _getowner(self,
|
||||
path,
|
||||
index,
|
||||
config_bag,
|
||||
validate_meta=True,
|
||||
only_default=False):
|
||||
"""get owner of an option
|
||||
"""
|
||||
context = self._getcontext()
|
||||
opt = config_bag.option
|
||||
opt = option_bag.option
|
||||
if opt.impl_is_symlinkoption():
|
||||
config_bag.ori_option = opt
|
||||
option_bag.ori_option = opt
|
||||
opt = opt.impl_getopt()
|
||||
config_bag.option = opt
|
||||
path = opt.impl_getpath(context)
|
||||
self_properties = config_bag.properties
|
||||
option_bag.option = opt
|
||||
option_bag.path = opt.impl_getpath(context)
|
||||
self_properties = option_bag.properties
|
||||
settings = context.cfgimpl_get_settings()
|
||||
if self_properties is None:
|
||||
self_properties = settings.getproperties(path,
|
||||
index,
|
||||
config_bag)
|
||||
config_bag.properties = self_properties
|
||||
if config_bag.setting_properties is not None:
|
||||
settings.validate_properties(path,
|
||||
index,
|
||||
config_bag)
|
||||
if option_bag.config_bag.setting_properties is not None:
|
||||
settings.validate_properties(option_bag)
|
||||
if 'frozen' in self_properties and 'force_default_on_freeze' in self_properties:
|
||||
return owners.default
|
||||
if only_default:
|
||||
if self._p_.hasvalue(path,
|
||||
index):
|
||||
if self._p_.hasvalue(option_bag.path,
|
||||
option_bag.index):
|
||||
owner = undefined
|
||||
else:
|
||||
owner = owners.default
|
||||
else:
|
||||
owner = self._p_.getowner(path,
|
||||
owner = self._p_.getowner(option_bag.path,
|
||||
owners.default,
|
||||
index=index)
|
||||
index=option_bag.index)
|
||||
if owner is owners.default and validate_meta is not False:
|
||||
meta = context.cfgimpl_get_meta()
|
||||
if meta is not None and self._is_meta(path,
|
||||
index,
|
||||
config_bag):
|
||||
owner = meta.cfgimpl_get_values()._getowner(path,
|
||||
index,
|
||||
config_bag,
|
||||
only_default=only_default)
|
||||
if meta is not None and self._is_meta(option_bag):
|
||||
owner = meta.cfgimpl_get_values().getowner(option_bag,
|
||||
only_default=only_default)
|
||||
return owner
|
||||
|
||||
def setowner(self,
|
||||
path,
|
||||
index,
|
||||
owner,
|
||||
config_bag):
|
||||
option_bag):
|
||||
"""
|
||||
sets a owner to an option
|
||||
|
||||
:param opt: the `option.Option` object
|
||||
:param owner: a valid owner, that is a `setting.owners.Owner` object
|
||||
"""
|
||||
opt = config_bag.option
|
||||
opt = option_bag.option
|
||||
if opt.impl_is_symlinkoption():
|
||||
raise ConfigError(_("can't set owner for the symlinkoption \"{}\""
|
||||
"").format(opt.impl_get_display_name()))
|
||||
if owner in forbidden_owners:
|
||||
raise ConfigError(_('set owner "{0}" is forbidden').format(str(owner)))
|
||||
|
||||
if not self._p_.hasvalue(path):
|
||||
if not self._p_.hasvalue(option_bag.path):
|
||||
raise ConfigError(_('no value for {0} cannot change owner to {1}'
|
||||
'').format(path, owner))
|
||||
self.setowner_validation(path,
|
||||
index,
|
||||
config_bag)
|
||||
self._p_.setowner(path, owner, index=index)
|
||||
'').format(option_bag.path, owner))
|
||||
self._getcontext().cfgimpl_get_settings().validate_frozen(option_bag)
|
||||
self._p_.setowner(option_bag.path,
|
||||
owner,
|
||||
index=option_bag.index)
|
||||
#______________________________________________________________________
|
||||
# reset
|
||||
|
||||
def reset(self,
|
||||
path,
|
||||
config_bag,
|
||||
option_bag,
|
||||
_commit=True):
|
||||
|
||||
context = self._getcontext()
|
||||
setting = context.cfgimpl_get_settings()
|
||||
hasvalue = self._p_.hasvalue(path)
|
||||
hasvalue = self._p_.hasvalue(option_bag.path)
|
||||
|
||||
if hasvalue and config_bag.validate:
|
||||
if hasvalue and option_bag.config_bag.validate:
|
||||
ori_validate = option_bag.config_bag.validate
|
||||
if ori_validate is True:
|
||||
option_bag.config_bag.validate = False
|
||||
fake_context = context._gen_fake_values()
|
||||
fake_value = fake_context.cfgimpl_get_values()
|
||||
sconfig_bag = config_bag.copy()
|
||||
sconfig_bag.validate = False
|
||||
fake_value.reset(path,
|
||||
sconfig_bag)
|
||||
value = fake_value.getdefaultvalue(path,
|
||||
None,
|
||||
config_bag)
|
||||
fake_value.setvalue_validation(path,
|
||||
None,
|
||||
value,
|
||||
config_bag)
|
||||
opt = config_bag.option
|
||||
fake_value.reset(option_bag)
|
||||
if ori_validate is True:
|
||||
option_bag.config_bag.validate = True
|
||||
value = fake_value.getdefaultvalue(option_bag)
|
||||
fake_value.setvalue_validation(value,
|
||||
option_bag)
|
||||
opt = option_bag.option
|
||||
if opt.impl_is_master_slaves('master'):
|
||||
opt.impl_get_master_slaves().reset(self,
|
||||
config_bag,
|
||||
option_bag,
|
||||
_commit=_commit)
|
||||
if hasvalue:
|
||||
if 'force_store_value' in setting.getproperties(path,
|
||||
None,
|
||||
config_bag):
|
||||
value = self.getdefaultvalue(path,
|
||||
None,
|
||||
config_bag)
|
||||
self._setvalue(path,
|
||||
None,
|
||||
if 'force_store_value' in option_bag.properties:
|
||||
value = self.getdefaultvalue(option_bag)
|
||||
|
||||
self._setvalue(option_bag,
|
||||
value,
|
||||
owners.forced,
|
||||
config_bag,
|
||||
commit=_commit)
|
||||
else:
|
||||
self._p_.resetvalue(path,
|
||||
self._p_.resetvalue(option_bag.path,
|
||||
_commit)
|
||||
context.cfgimpl_reset_cache(config_bag.option,
|
||||
path,
|
||||
config_bag)
|
||||
if not opt.impl_is_master_slaves('master'):
|
||||
# if master, already reset behind
|
||||
pass
|
||||
context.cfgimpl_reset_cache(option_bag)
|
||||
|
||||
def reset_slave(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag):
|
||||
|
||||
if self._p_.hasvalue(path, index=index):
|
||||
if self._p_.hasvalue(option_bag.path, index=option_bag.index):
|
||||
context = self._getcontext()
|
||||
if config_bag.validate:
|
||||
if option_bag.config_bag.validate:
|
||||
fake_context = context._gen_fake_values()
|
||||
fake_value = fake_context.cfgimpl_get_values()
|
||||
sconfig_bag = config_bag.copy()
|
||||
sconfig_bag.validate = False
|
||||
fake_value.reset_slave(path,
|
||||
index,
|
||||
sconfig_bag)
|
||||
value = fake_value.getdefaultvalue(path,
|
||||
index,
|
||||
config_bag)
|
||||
fake_value.setvalue_validation(path,
|
||||
index,
|
||||
value,
|
||||
config_bag)
|
||||
self._p_.resetvalue_index(path, index)
|
||||
context.cfgimpl_reset_cache(config_bag.option,
|
||||
path,
|
||||
config_bag)
|
||||
ori_validate = option_bag.config_bag.validate
|
||||
option_bag.config_bag.validate = False
|
||||
try:
|
||||
fake_value.reset_slave(option_bag)
|
||||
value = fake_value.getdefaultvalue(option_bag)
|
||||
fake_value.setvalue_validation(value,
|
||||
option_bag)
|
||||
option_bag.config_bag.validate = ori_validate
|
||||
except Exception as err:
|
||||
option_bag.config_bag.validate = ori_validate
|
||||
raise err
|
||||
self._p_.resetvalue_index(option_bag.path, option_bag.index)
|
||||
context.cfgimpl_reset_cache(option_bag)
|
||||
|
||||
def reset_master(self,
|
||||
subconfig,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
option_bag,
|
||||
subconfig):
|
||||
|
||||
current_value = self.get_cached_value(path,
|
||||
None,
|
||||
config_bag)
|
||||
current_value = self.get_cached_value(option_bag)
|
||||
length = len(current_value)
|
||||
if index >= length:
|
||||
raise IndexError(_('index "{}" is higher than the length "{}" '
|
||||
'for option "{}"').format(index,
|
||||
length,
|
||||
config_bag.option.impl_get_display_name()))
|
||||
option_bag.option.impl_get_display_name()))
|
||||
current_value.pop(index)
|
||||
self.setvalue(path,
|
||||
None,
|
||||
current_value,
|
||||
config_bag,
|
||||
self.setvalue(current_value,
|
||||
option_bag,
|
||||
_commit=True)
|
||||
subconfig.cfgimpl_get_description().pop(self,
|
||||
index,
|
||||
config_bag)
|
||||
|
||||
def setowner_validation(self,
|
||||
path,
|
||||
index,
|
||||
config_bag):
|
||||
|
||||
context = self._getcontext()
|
||||
settings = context.cfgimpl_get_settings()
|
||||
# First validate properties with this value
|
||||
self_properties = config_bag.properties
|
||||
settings.validate_frozen(path,
|
||||
index,
|
||||
config_bag)
|
||||
option_bag)
|
||||
|
||||
#______________________________________________________________________
|
||||
# information
|
||||
@ -684,24 +581,26 @@ class Values(object):
|
||||
settings = context.cfgimpl_get_settings()
|
||||
# for option in config.cfgimpl_get_children(self.config_bag):
|
||||
for option in description.impl_getchildren(config_bag, context):
|
||||
sconfig_bag = config_bag.copy('nooption')
|
||||
sconfig_bag.option = option
|
||||
name = option.impl_getname()
|
||||
path = '.'.join(currpath + [name])
|
||||
|
||||
if option.impl_is_optiondescription():
|
||||
ori_setting_properties = sconfig_bag.setting_properties
|
||||
sconfig_bag.setting_properties = od_setting_properties
|
||||
ori_setting_properties = config_bag._setting_properties
|
||||
config_bag._setting_properties = od_setting_properties
|
||||
try:
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
None,
|
||||
config_bag)
|
||||
subconfig = config.getattr(name,
|
||||
None,
|
||||
sconfig_bag)
|
||||
option_bag)
|
||||
except PropertiesOptionError as err:
|
||||
pass
|
||||
else:
|
||||
sconfig_bag.setting_properties = ori_setting_properties
|
||||
config_bag._setting_properties = ori_setting_properties
|
||||
for path in self._mandatory_warnings(context,
|
||||
sconfig_bag,
|
||||
config_bag,
|
||||
option,
|
||||
currpath + [name],
|
||||
subconfig,
|
||||
@ -711,26 +610,24 @@ class Values(object):
|
||||
# don't verifying symlink
|
||||
try:
|
||||
if not option.impl_is_master_slaves('slave'):
|
||||
self_properties = settings.getproperties(path,
|
||||
None,
|
||||
sconfig_bag)
|
||||
|
||||
sconfig_bag.properties = self_properties
|
||||
if 'mandatory' in self_properties or 'empty' in self_properties:
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
None,
|
||||
config_bag)
|
||||
if 'mandatory' in option_bag.properties or 'empty' in option_bag.properties:
|
||||
config.getattr(name,
|
||||
None,
|
||||
sconfig_bag)
|
||||
option_bag)
|
||||
else:
|
||||
for index in range(config.cfgimpl_get_length()):
|
||||
self_properties = settings.getproperties(path,
|
||||
index,
|
||||
sconfig_bag)
|
||||
|
||||
sconfig_bag.properties = self_properties
|
||||
if 'mandatory' in self_properties:
|
||||
option_bag = OptionBag()
|
||||
option_bag.set_option(option,
|
||||
path,
|
||||
index,
|
||||
config_bag)
|
||||
if 'mandatory' in option_bag.properties:
|
||||
config.getattr(name,
|
||||
index,
|
||||
sconfig_bag)
|
||||
option_bag)
|
||||
except PropertiesOptionError as err:
|
||||
if err.proptype == ['mandatory']:
|
||||
yield path
|
||||
@ -750,7 +647,8 @@ class Values(object):
|
||||
od_setting_properties = config_bag.setting_properties - {'mandatory', 'empty'}
|
||||
setting_properties = set(config_bag.setting_properties) - {'warnings'}
|
||||
setting_properties.update(['mandatory', 'empty'])
|
||||
config_bag.setting_properties = frozenset(setting_properties)
|
||||
config_bag = ConfigBag(config=config_bag.config)
|
||||
config_bag._setting_properties = frozenset(setting_properties)
|
||||
config_bag.force_permissive = True
|
||||
|
||||
descr = context.cfgimpl_get_description()
|
||||
|
Loading…
Reference in New Issue
Block a user