refactor
This commit is contained in:
parent
5d1be8a11a
commit
119ca85041
11 changed files with 1141 additions and 1199 deletions
|
@ -220,16 +220,12 @@ def _autocheck_set_value(api, path, **kwargs):
|
||||||
submulti_ = api.unrestraint.option(path).option.issubmulti()
|
submulti_ = api.unrestraint.option(path).option.issubmulti()
|
||||||
ismaster = api.unrestraint.option(path).option.ismaster()
|
ismaster = api.unrestraint.option(path).option.ismaster()
|
||||||
isslave = api.unrestraint.option(path).option.isslave()
|
isslave = api.unrestraint.option(path).option.isslave()
|
||||||
# empty_value = _getdefault(api, path, multi, isslave, submulti_)
|
|
||||||
if not multi:
|
if not multi:
|
||||||
first_value = FIRST_VALUE
|
first_value = FIRST_VALUE
|
||||||
# second_value = SECOND_VALUE
|
|
||||||
elif submulti_ is False:
|
elif submulti_ is False:
|
||||||
first_value = LIST_FIRST_VALUE
|
first_value = LIST_FIRST_VALUE
|
||||||
# second_value = LIST_SECOND_VALUE
|
|
||||||
else:
|
else:
|
||||||
first_value = SUBLIST_FIRST_VALUE
|
first_value = SUBLIST_FIRST_VALUE
|
||||||
# second_value = SUBLIST_SECOND_VALUE
|
|
||||||
|
|
||||||
# for slave should have an index and good length
|
# for slave should have an index and good length
|
||||||
# for master must append, not set
|
# for master must append, not set
|
||||||
|
@ -509,7 +505,7 @@ def _getproperties(multi, isslave, kwargs):
|
||||||
if extra_properties:
|
if extra_properties:
|
||||||
properties.extend(extra_properties)
|
properties.extend(extra_properties)
|
||||||
default_props.extend(extra_properties)
|
default_props.extend(extra_properties)
|
||||||
return default_props, tuple(properties)
|
return default_props, frozenset(properties)
|
||||||
|
|
||||||
|
|
||||||
def _check_default_properties(api, path, kwargs, props_permissive, props):
|
def _check_default_properties(api, path, kwargs, props_permissive, props):
|
||||||
|
@ -540,17 +536,6 @@ def _autocheck_property(api, path, **kwargs):
|
||||||
multi = api.unrestraint.option(path).option.ismulti()
|
multi = api.unrestraint.option(path).option.ismulti()
|
||||||
isslave = api.unrestraint.option(path).option.isslave()
|
isslave = api.unrestraint.option(path).option.isslave()
|
||||||
|
|
||||||
# define properties
|
|
||||||
properties = copy(PROPERTIES_LIST)
|
|
||||||
if multi and not isslave:
|
|
||||||
default_props = ['empty']
|
|
||||||
properties.append('empty')
|
|
||||||
else:
|
|
||||||
default_props = []
|
|
||||||
extra_properties = kwargs.get('extra_properties')
|
|
||||||
if extra_properties:
|
|
||||||
properties.extend(extra_properties)
|
|
||||||
default_props.extend(extra_properties)
|
|
||||||
default_props, properties = _getproperties(multi, isslave, kwargs)
|
default_props, properties = _getproperties(multi, isslave, kwargs)
|
||||||
|
|
||||||
_check_default_properties(api, path, kwargs, default_props, default_props)
|
_check_default_properties(api, path, kwargs, default_props, default_props)
|
||||||
|
@ -863,7 +848,7 @@ def autocheck_permissive(api, path, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def check_all(cfg, path, meta, multi, default, default_multi, **kwargs):
|
def check_all(cfg, path, meta, multi, default, default_multi, require, consistency, **kwargs):
|
||||||
if DISPLAY:
|
if DISPLAY:
|
||||||
text = u' {} launch tests for {}'.format(ICON, path)
|
text = u' {} launch tests for {}'.format(ICON, path)
|
||||||
if multi is True:
|
if multi is True:
|
||||||
|
@ -882,22 +867,37 @@ def check_all(cfg, path, meta, multi, default, default_multi, **kwargs):
|
||||||
if api.unrestraint.option(path).option.isslave():
|
if api.unrestraint.option(path).option.isslave():
|
||||||
master_path = path.rsplit('.', 1)[0] + '.master'
|
master_path = path.rsplit('.', 1)[0] + '.master'
|
||||||
api.option(master_path).value.set(LIST_SECOND_VALUE)
|
api.option(master_path).value.set(LIST_SECOND_VALUE)
|
||||||
for func in autocheck_registers:
|
if not require:
|
||||||
api = getapi(cfg.duplicate())
|
requires = [False]
|
||||||
if DISPLAY:
|
else:
|
||||||
print(u' {} {}'.format(ICON, func.__name__))
|
requires = [False, True]
|
||||||
try:
|
for req in requires:
|
||||||
func(api, path, **kwargs)
|
for func in autocheck_registers:
|
||||||
except Exception as err:
|
api = getapi(cfg.duplicate())
|
||||||
msg = u'error in function {} for {}'.format(func.__name__, path)
|
#FIXME devrait etre dans la config ca ...
|
||||||
if multi is True:
|
api.read_write()
|
||||||
msg += u' as a multi'
|
ckwargs = copy(kwargs)
|
||||||
elif multi is submulti:
|
if req:
|
||||||
msg += u' as a submulti'
|
api.option('extraoptrequire').value.set('value')
|
||||||
if multi is True:
|
if 'permissive' in ckwargs and not 'permissive_od' in ckwargs or \
|
||||||
msg += u' with default value'
|
'propertyerror' in ckwargs and not 'propertyerror_od' in ckwargs:
|
||||||
print(u'{}: {}'.format(msg, kwargs))
|
for to_del in ['permissive', 'propertyerror', 'extra_properties']:
|
||||||
raise err
|
if to_del in ckwargs:
|
||||||
|
del ckwargs[to_del]
|
||||||
|
if DISPLAY:
|
||||||
|
print(u' {} {}'.format(ICON, func.__name__))
|
||||||
|
try:
|
||||||
|
func(api, path, **ckwargs)
|
||||||
|
except Exception as err:
|
||||||
|
msg = u'error in function {} for {}'.format(func.__name__, path)
|
||||||
|
if multi is True:
|
||||||
|
msg += u' as a multi'
|
||||||
|
elif multi is submulti:
|
||||||
|
msg += u' as a submulti'
|
||||||
|
if multi is True:
|
||||||
|
msg += u' with default value'
|
||||||
|
print(u'{}: {}'.format(msg, ckwargs))
|
||||||
|
raise err
|
||||||
|
|
||||||
|
|
||||||
def check_deref(weakrefs):
|
def check_deref(weakrefs):
|
||||||
|
@ -907,23 +907,32 @@ def check_deref(weakrefs):
|
||||||
assert wrf() is None
|
assert wrf() is None
|
||||||
|
|
||||||
|
|
||||||
def make_conf(options, meta, multi, default, default_multi):
|
def make_conf(options, meta, multi, default, default_multi, require, consistency):
|
||||||
weakrefs = []
|
weakrefs = []
|
||||||
|
dyn = []
|
||||||
|
goptions = []
|
||||||
def make_option(path, option_infos):
|
def make_option(path, option_infos):
|
||||||
#FIXME
|
#FIXME
|
||||||
option_type = 'str'
|
option_type = 'str'
|
||||||
option_properties = []
|
option_properties = []
|
||||||
|
option_requires = []
|
||||||
isslave = False
|
isslave = False
|
||||||
if option_infos is not None:
|
if option_infos is not None:
|
||||||
for prop in PROPERTIES:
|
for prop in PROPERTIES:
|
||||||
if option_infos.get(prop, False) is True:
|
if option_infos.get(prop, False) is True:
|
||||||
option_properties.append(prop)
|
if not require:
|
||||||
|
option_properties.append(prop)
|
||||||
|
else:
|
||||||
|
option_requires.append({'option': goptions[0], 'expected': None,
|
||||||
|
'action': prop})
|
||||||
isslave = option_infos.get('slave', False)
|
isslave = option_infos.get('slave', False)
|
||||||
args = [path, "{}'s option".format(path)]
|
args = [path, "{}'s option".format(path)]
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
if option_properties != []:
|
if option_properties != []:
|
||||||
kwargs['properties'] = tuple(option_properties)
|
kwargs['properties'] = tuple(option_properties)
|
||||||
if multi:
|
if option_requires != []:
|
||||||
|
kwargs['requires'] = option_requires
|
||||||
|
if multi and path is not 'extraoptrequire':
|
||||||
kwargs['multi'] = multi
|
kwargs['multi'] = multi
|
||||||
if default and not submulti:
|
if default and not submulti:
|
||||||
if multi is False:
|
if multi is False:
|
||||||
|
@ -933,7 +942,7 @@ def make_conf(options, meta, multi, default, default_multi):
|
||||||
else:
|
else:
|
||||||
value = SUBLIST_EMPTY_VALUE
|
value = SUBLIST_EMPTY_VALUE
|
||||||
kwargs['default'] = value
|
kwargs['default'] = value
|
||||||
if default_multi:
|
if default_multi and path is not 'extraoptrequire':
|
||||||
if multi is not submulti:
|
if multi is not submulti:
|
||||||
value = SECOND_VALUE
|
value = SECOND_VALUE
|
||||||
else:
|
else:
|
||||||
|
@ -942,6 +951,12 @@ def make_conf(options, meta, multi, default, default_multi):
|
||||||
|
|
||||||
tiramisu_option = OPTIONS_TYPE[option_type]['option']
|
tiramisu_option = OPTIONS_TYPE[option_type]['option']
|
||||||
obj = tiramisu_option(*args, **kwargs)
|
obj = tiramisu_option(*args, **kwargs)
|
||||||
|
if not 'extraopt' in path and consistency:
|
||||||
|
if require:
|
||||||
|
gopt = goptions[1]
|
||||||
|
else:
|
||||||
|
gopt = goptions[0]
|
||||||
|
obj.impl_add_consistency('not_equal', gopt, warnings_only=True)
|
||||||
weakrefs.append(weakref.ref(obj))
|
weakrefs.append(weakref.ref(obj))
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
@ -961,6 +976,7 @@ def make_conf(options, meta, multi, default, default_multi):
|
||||||
if infos.get('dyn', False) is True:
|
if infos.get('dyn', False) is True:
|
||||||
optiondescription = DynOptionDescription
|
optiondescription = DynOptionDescription
|
||||||
kwargs['callback'] = return_list
|
kwargs['callback'] = return_list
|
||||||
|
dyn.append(path)
|
||||||
options = []
|
options = []
|
||||||
if 'options' in collected:
|
if 'options' in collected:
|
||||||
options.extend(collected['options'])
|
options.extend(collected['options'])
|
||||||
|
@ -978,7 +994,22 @@ def make_conf(options, meta, multi, default, default_multi):
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
collect_options = {}
|
collect_options = {}
|
||||||
for path, option in options.items():
|
if require or consistency:
|
||||||
|
noptions = OrderedDict()
|
||||||
|
if require:
|
||||||
|
noptions['extraoptrequire'] = {}
|
||||||
|
if consistency:
|
||||||
|
subpath = list(options.keys())[0]
|
||||||
|
if '.' in subpath:
|
||||||
|
subpath = subpath.rsplit('.', 1)[0] + '.'
|
||||||
|
else:
|
||||||
|
subpath = ''
|
||||||
|
noptions[subpath + 'extraoptconsistency'] = {}
|
||||||
|
noptions.update(options)
|
||||||
|
else:
|
||||||
|
noptions = options
|
||||||
|
|
||||||
|
for path, option in noptions.items():
|
||||||
if option is None:
|
if option is None:
|
||||||
continue
|
continue
|
||||||
local_collect_options = collect_options
|
local_collect_options = collect_options
|
||||||
|
@ -987,8 +1018,9 @@ def make_conf(options, meta, multi, default, default_multi):
|
||||||
local_collect_options = local_collect_options[optiondescription]
|
local_collect_options = local_collect_options[optiondescription]
|
||||||
local_collect_options['properties'].update(option.get(optiondescription, {}))
|
local_collect_options['properties'].update(option.get(optiondescription, {}))
|
||||||
option_name = path.split('.')[-1]
|
option_name = path.split('.')[-1]
|
||||||
path = '.'.join(path.split('.')[:-1])
|
obj = make_option(option_name, option.get(option_name))
|
||||||
local_collect_options.setdefault('options', []).append(make_option(option_name, option.get(option_name)))
|
goptions.append(obj)
|
||||||
|
local_collect_options.setdefault('options', []).append(obj)
|
||||||
|
|
||||||
rootod = make_optiondescriptions('root', collect_options)
|
rootod = make_optiondescriptions('root', collect_options)
|
||||||
if rootod is None:
|
if rootod is None:
|
||||||
|
@ -998,7 +1030,8 @@ def make_conf(options, meta, multi, default, default_multi):
|
||||||
if meta:
|
if meta:
|
||||||
cfg = MetaConfig([cfg], session_id='metatest')
|
cfg = MetaConfig([cfg], session_id='metatest')
|
||||||
weakrefs.append(weakref.ref(cfg))
|
weakrefs.append(weakref.ref(cfg))
|
||||||
return cfg, weakrefs
|
del goptions
|
||||||
|
return cfg, weakrefs, dyn
|
||||||
|
|
||||||
|
|
||||||
DICT_PATHS = [
|
DICT_PATHS = [
|
||||||
|
@ -1091,24 +1124,35 @@ def test_options(paths):
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
lpaths = list(paths.keys())
|
lpaths = list(paths.keys())
|
||||||
for meta in (False, True):
|
meta = False
|
||||||
for default_multi in (False, True):
|
#for meta in (False, True):
|
||||||
for default in (False, True):
|
for consistency in (False, True):
|
||||||
for multi in (False, True, submulti):
|
for require in (False, True):
|
||||||
if multi is False and default_multi:
|
for default_multi in (False, True):
|
||||||
continue
|
for default in (False, True):
|
||||||
cfg, weakrefs = make_conf(paths, meta, multi, default, default_multi)
|
for multi in (False, True, submulti):
|
||||||
if cfg is None:
|
if multi is submulti and consistency:
|
||||||
continue
|
continue
|
||||||
if len(lpaths) == 9:
|
if multi is False and default_multi:
|
||||||
check_all(cfg, lpaths[3], meta, multi, default, default_multi, **get_kwargs(lpaths[0]))
|
continue
|
||||||
check_all(cfg, lpaths[4], meta, multi, default, default_multi, **get_kwargs(lpaths[1]))
|
cfg, weakrefs, dyn = make_conf(paths, meta, multi, default, default_multi, require, consistency)
|
||||||
check_all(cfg, lpaths[5], meta, multi, default, default_multi, **get_kwargs(lpaths[2]))
|
if cfg is None:
|
||||||
check_all(cfg, lpaths[6], meta, multi, default, default_multi, **get_kwargs(lpaths[0]))
|
continue
|
||||||
check_all(cfg, lpaths[7], meta, multi, default, default_multi, **get_kwargs(lpaths[1]))
|
if dyn:
|
||||||
check_all(cfg, lpaths[8], meta, multi, default, default_multi, **get_kwargs(lpaths[2]))
|
cnt = 0
|
||||||
else:
|
idx = 0
|
||||||
for lpath in lpaths:
|
for index, lpath in enumerate(lpaths):
|
||||||
check_all(cfg, lpath, meta, multi, default, default_multi, **get_kwargs(lpath))
|
if paths[lpath]:
|
||||||
del cfg
|
cnt += 1
|
||||||
check_deref(weakrefs)
|
else:
|
||||||
|
check_all(cfg, lpaths[index], meta, multi, default,
|
||||||
|
default_multi, require, consistency, **get_kwargs(lpaths[idx]))
|
||||||
|
idx += 1
|
||||||
|
if idx == cnt:
|
||||||
|
idx = 0
|
||||||
|
else:
|
||||||
|
for lpath in lpaths:
|
||||||
|
check_all(cfg, lpath, meta, multi, default,
|
||||||
|
default_multi, require, consistency, **get_kwargs(lpath))
|
||||||
|
del cfg
|
||||||
|
check_deref(weakrefs)
|
||||||
|
|
|
@ -145,6 +145,7 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||||
setting_properties,
|
setting_properties,
|
||||||
force_permissive,
|
force_permissive,
|
||||||
force_unrestraint):
|
force_unrestraint):
|
||||||
|
|
||||||
super(TiramisuOptionOwner, self).__init__(opt,
|
super(TiramisuOptionOwner, self).__init__(opt,
|
||||||
path,
|
path,
|
||||||
index,
|
index,
|
||||||
|
@ -158,12 +159,16 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||||
def get(self):
|
def get(self):
|
||||||
"""get owner for a specified option"""
|
"""get owner for a specified option"""
|
||||||
return self.values.getowner(self.opt,
|
return self.values.getowner(self.opt,
|
||||||
|
self.path,
|
||||||
|
self.setting_properties,
|
||||||
index=self.index,
|
index=self.index,
|
||||||
force_permissive=self.force_permissive)
|
force_permissive=self.force_permissive)
|
||||||
|
|
||||||
def isdefault(self):
|
def isdefault(self):
|
||||||
"""is option has defaut value"""
|
"""is option has defaut value"""
|
||||||
return self.values.is_default_owner(self.opt,
|
return self.values.is_default_owner(self.opt,
|
||||||
|
self.path,
|
||||||
|
self.setting_properties,
|
||||||
index=self.index,
|
index=self.index,
|
||||||
force_permissive=self.force_permissive)
|
force_permissive=self.force_permissive)
|
||||||
|
|
||||||
|
@ -174,10 +179,9 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
owners.addowner(owner)
|
owners.addowner(owner)
|
||||||
obj_owner = getattr(owners, owner)
|
obj_owner = getattr(owners, owner)
|
||||||
self.values.setowner(self.opt,
|
self.values.setowner(self.path,
|
||||||
obj_owner,
|
obj_owner,
|
||||||
self.index,
|
self.index)
|
||||||
force_permissive=self.force_permissive)
|
|
||||||
|
|
||||||
|
|
||||||
class TiramisuOptionProperty(CommonTiramisuOption):
|
class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
|
@ -207,14 +211,14 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
self._test_slave_index()
|
self._test_slave_index()
|
||||||
return self.settings.getproperties(self.opt,
|
return self.settings.getproperties(self.opt,
|
||||||
self.path,
|
self.path,
|
||||||
index=self.index,
|
self.setting_properties,
|
||||||
obj=False)
|
index=self.index)
|
||||||
|
|
||||||
def set(self, properties):
|
def set(self, properties):
|
||||||
"""set properties for a specified option"""
|
"""set properties for a specified option"""
|
||||||
self.settings.setproperties(set(properties),
|
self.settings.setproperties(self.opt,
|
||||||
self.opt,
|
self.path,
|
||||||
self.path)
|
properties)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
"""reset all personalised properties
|
"""reset all personalised properties
|
||||||
|
@ -247,16 +251,17 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
"""get permissive value for a specified path"""
|
"""get permissive value for a specified path"""
|
||||||
return self.settings.getpermissive(self.setting_properties, self.path)
|
return self.settings.getpermissive(self.path)
|
||||||
|
|
||||||
def set(self, permissive):
|
def set(self, permissive):
|
||||||
self.settings.setpermissive(permissive, opt=self.opt, path=self.path)
|
self.settings.setpermissive(self.opt,
|
||||||
|
self.path,
|
||||||
|
permissive)
|
||||||
|
|
||||||
#def reset(self, path):
|
def reset(self, path):
|
||||||
# """reset all personalised properties
|
"""reset all personalised permissive
|
||||||
# """
|
"""
|
||||||
# self._get_obj_by_path(path)
|
self.set(tuple())
|
||||||
# self.settings.reset(_path=path)
|
|
||||||
|
|
||||||
|
|
||||||
class TiramisuOptionValue(CommonTiramisuOption):
|
class TiramisuOptionValue(CommonTiramisuOption):
|
||||||
|
@ -409,11 +414,6 @@ class TiramisuAPI(object):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.force_permissive = force_permissive
|
self.force_permissive = force_permissive
|
||||||
self.force_unrestraint = force_unrestraint
|
self.force_unrestraint = force_unrestraint
|
||||||
settings = self.config.cfgimpl_get_settings()
|
|
||||||
# #FIXME ?
|
|
||||||
self.config.read_write()
|
|
||||||
settings.setpermissive(('hidden',))
|
|
||||||
#/FIXME ?
|
|
||||||
|
|
||||||
def option(self, path, index=None):
|
def option(self, path, index=None):
|
||||||
validate = not self.force_unrestraint
|
validate = not self.force_unrestraint
|
||||||
|
@ -464,6 +464,16 @@ class TiramisuAPI(object):
|
||||||
txt.append(module(None, None).help)
|
txt.append(module(None, None).help)
|
||||||
return '\n'.join(txt)
|
return '\n'.join(txt)
|
||||||
|
|
||||||
|
def read_only(self):
|
||||||
|
self.config.read_write()
|
||||||
|
|
||||||
|
def read_write(self):
|
||||||
|
settings = self.config.cfgimpl_get_settings()
|
||||||
|
self.config.read_write()
|
||||||
|
# #FIXME ?
|
||||||
|
settings.set_context_permissive(frozenset(['hidden']))
|
||||||
|
#/FIXME ?
|
||||||
|
|
||||||
|
|
||||||
def getapi(config):
|
def getapi(config):
|
||||||
"""instanciate TiramisuAPI
|
"""instanciate TiramisuAPI
|
||||||
|
|
|
@ -90,31 +90,39 @@ class SubConfig(object):
|
||||||
def cfgimpl_get_length(self):
|
def cfgimpl_get_length(self):
|
||||||
return self._impl_length
|
return self._impl_length
|
||||||
|
|
||||||
def reset_one_option_cache(self, values, settings, resetted_opts, opt, only):
|
def reset_one_option_cache(self,
|
||||||
if 'values' in only:
|
values,
|
||||||
tresetted_opts = copy(resetted_opts)
|
settings,
|
||||||
opt.reset_cache(opt, values, 'values', tresetted_opts)
|
resetted_opts,
|
||||||
|
opt,
|
||||||
if 'settings' in only:
|
path):
|
||||||
tresetted_opts = copy(resetted_opts)
|
tresetted_opts = copy(resetted_opts)
|
||||||
opt.reset_cache(opt, settings, 'settings', tresetted_opts)
|
opt.reset_cache(opt,
|
||||||
else:
|
path,
|
||||||
if 'properties' in only:
|
values,
|
||||||
tresetted_opts = copy(resetted_opts)
|
'values',
|
||||||
opt.reset_cache(opt, settings, 'properties', tresetted_opts)
|
tresetted_opts)
|
||||||
if 'permissives' in only:
|
tresetted_opts = copy(resetted_opts)
|
||||||
tresetted_opts = copy(resetted_opts)
|
opt.reset_cache(opt,
|
||||||
opt.reset_cache(opt, settings, 'permissives', tresetted_opts)
|
path,
|
||||||
|
settings,
|
||||||
|
'settings',
|
||||||
|
tresetted_opts)
|
||||||
resetted_opts |= tresetted_opts
|
resetted_opts |= tresetted_opts
|
||||||
for option in opt._get_dependencies(self):
|
for woption in opt._get_dependencies(self):
|
||||||
|
option = woption()
|
||||||
if option in resetted_opts:
|
if option in resetted_opts:
|
||||||
continue
|
continue
|
||||||
self.reset_one_option_cache(values, settings, resetted_opts, option(), only)
|
option_path = opt.impl_getpath(self)
|
||||||
del(option)
|
self.reset_one_option_cache(values,
|
||||||
|
settings,
|
||||||
|
resetted_opts,
|
||||||
|
option,
|
||||||
|
option_path)
|
||||||
|
del option
|
||||||
|
|
||||||
def cfgimpl_reset_cache(self,
|
def cfgimpl_reset_cache(self,
|
||||||
only_expired=False,
|
only_expired=False,
|
||||||
only=('values', 'properties', 'permissives', 'settings'),
|
|
||||||
opt=None,
|
opt=None,
|
||||||
path=None,
|
path=None,
|
||||||
resetted_opts=None):
|
resetted_opts=None):
|
||||||
|
@ -127,33 +135,19 @@ class SubConfig(object):
|
||||||
def reset_expired_cache():
|
def reset_expired_cache():
|
||||||
# reset cache for expired cache value ony
|
# reset cache for expired cache value ony
|
||||||
datetime = int(time())
|
datetime = int(time())
|
||||||
if 'values' in only:
|
values._p_.reset_expired_cache(datetime)
|
||||||
values._p_.reset_expired_cache(datetime)
|
settings._p_.reset_expired_cache(datetime)
|
||||||
if 'settings' in only or 'properties' in only:
|
|
||||||
settings._p_.reset_expired_cache(datetime)
|
|
||||||
if 'settings' in only or 'permissives' in only:
|
|
||||||
settings._pp_.reset_expired_cache(datetime)
|
|
||||||
|
|
||||||
def reset_all_cache():
|
def reset_all_cache():
|
||||||
if 'values' in only:
|
values._p_.reset_all_cache()
|
||||||
values._p_.reset_all_cache()
|
settings._p_.reset_all_cache()
|
||||||
if 'settings' in only:
|
|
||||||
settings._p_.reset_all_cache()
|
|
||||||
settings._pp_.reset_all_cache()
|
|
||||||
else:
|
|
||||||
if 'properties' in only:
|
|
||||||
settings._p_.reset_all_cache()
|
|
||||||
if 'permissives' in only:
|
|
||||||
settings._pp_.reset_all_cache()
|
|
||||||
|
|
||||||
if resetted_opts is None:
|
if resetted_opts is None:
|
||||||
resetted_opts = set()
|
resetted_opts = set()
|
||||||
|
|
||||||
context = self._cfgimpl_get_context()
|
context = self._cfgimpl_get_context()
|
||||||
if 'values' in only:
|
values = context.cfgimpl_get_values()
|
||||||
values = context.cfgimpl_get_values()
|
settings = context.cfgimpl_get_settings()
|
||||||
if 'settings' in only or 'properties' in only or 'permissives' in only:
|
|
||||||
settings = context.cfgimpl_get_settings()
|
|
||||||
|
|
||||||
if not None in (opt, path):
|
if not None in (opt, path):
|
||||||
if opt not in resetted_opts:
|
if opt not in resetted_opts:
|
||||||
|
@ -161,7 +155,7 @@ class SubConfig(object):
|
||||||
settings,
|
settings,
|
||||||
resetted_opts,
|
resetted_opts,
|
||||||
opt,
|
opt,
|
||||||
only)
|
path)
|
||||||
|
|
||||||
elif only_expired:
|
elif only_expired:
|
||||||
reset_expired_cache()
|
reset_expired_cache()
|
||||||
|
@ -308,7 +302,6 @@ class SubConfig(object):
|
||||||
name,
|
name,
|
||||||
value,
|
value,
|
||||||
force_permissive=False,
|
force_permissive=False,
|
||||||
not_raises=False,
|
|
||||||
index=None,
|
index=None,
|
||||||
setting_properties=undefined,
|
setting_properties=undefined,
|
||||||
_commit=True):
|
_commit=True):
|
||||||
|
@ -319,7 +312,7 @@ class SubConfig(object):
|
||||||
value)
|
value)
|
||||||
context = self._cfgimpl_get_context()
|
context = self._cfgimpl_get_context()
|
||||||
if setting_properties is undefined:
|
if setting_properties is undefined:
|
||||||
setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=True)
|
setting_properties = context.cfgimpl_get_settings().get_context_properties()
|
||||||
if '.' in name: # pragma: optional cover
|
if '.' in name: # pragma: optional cover
|
||||||
self, name = self.cfgimpl_get_home_by_path(name,
|
self, name = self.cfgimpl_get_home_by_path(name,
|
||||||
force_permissive=force_permissive,
|
force_permissive=force_permissive,
|
||||||
|
@ -332,21 +325,17 @@ class SubConfig(object):
|
||||||
not isinstance(child, DynSymLinkOption): # pragma: no dynoptiondescription cover
|
not isinstance(child, DynSymLinkOption): # pragma: no dynoptiondescription cover
|
||||||
raise TypeError(_("can't assign to a SymlinkOption"))
|
raise TypeError(_("can't assign to a SymlinkOption"))
|
||||||
else:
|
else:
|
||||||
msg = self.cfgimpl_get_description().impl_validate_value(child, value, self)
|
self.cfgimpl_get_description().impl_validate_value(child,
|
||||||
if msg is not None:
|
value,
|
||||||
if not_raises:
|
self)
|
||||||
return msg
|
|
||||||
else:
|
|
||||||
raise msg
|
|
||||||
subpath = self._get_subpath(name)
|
subpath = self._get_subpath(name)
|
||||||
return self.cfgimpl_get_values().setitem(child,
|
return self.cfgimpl_get_values().setvalue(child,
|
||||||
value,
|
value,
|
||||||
subpath,
|
subpath,
|
||||||
force_permissive,
|
force_permissive,
|
||||||
not_raises,
|
index,
|
||||||
index,
|
setting_properties,
|
||||||
setting_properties,
|
_commit)
|
||||||
_commit)
|
|
||||||
|
|
||||||
def __delattr__(self, name):
|
def __delattr__(self, name):
|
||||||
self.delattr(name)
|
self.delattr(name)
|
||||||
|
@ -467,12 +456,12 @@ class SubConfig(object):
|
||||||
index=index)
|
index=index)
|
||||||
elif option.impl_is_optiondescription():
|
elif option.impl_is_optiondescription():
|
||||||
if setting_properties:
|
if setting_properties:
|
||||||
props = self.cfgimpl_get_settings().validate_properties(option,
|
self.cfgimpl_get_settings().validate_properties(option,
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
path=subpath,
|
path=subpath,
|
||||||
force_permissive=force_permissive,
|
force_permissive=force_permissive,
|
||||||
setting_properties=setting_properties)
|
setting_properties=setting_properties)
|
||||||
if returns_option is True:
|
if returns_option is True:
|
||||||
return option
|
return option
|
||||||
return SubConfig(option,
|
return SubConfig(option,
|
||||||
|
@ -618,7 +607,7 @@ class SubConfig(object):
|
||||||
fullpath=False):
|
fullpath=False):
|
||||||
"""exports the whole config into a `dict`, for example:
|
"""exports the whole config into a `dict`, for example:
|
||||||
|
|
||||||
>>> print cfg.make_dict()
|
>>> print(cfg.make_dict())
|
||||||
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None}
|
{'od2.var4': None, 'od2.var5': None, 'od2.var6': None}
|
||||||
|
|
||||||
|
|
||||||
|
@ -626,13 +615,13 @@ class SubConfig(object):
|
||||||
:param flatten: returns a dict(name=value) instead of a dict(path=value)
|
:param flatten: returns a dict(name=value) instead of a dict(path=value)
|
||||||
::
|
::
|
||||||
|
|
||||||
>>> print cfg.make_dict(flatten=True)
|
>>> print(cfg.make_dict(flatten=True))
|
||||||
{'var5': None, 'var4': None, 'var6': None}
|
{'var5': None, 'var4': None, 'var6': None}
|
||||||
|
|
||||||
:param withoption: returns the options that are present in the very same
|
:param withoption: returns the options that are present in the very same
|
||||||
`OptionDescription` than the `withoption` itself::
|
`OptionDescription` than the `withoption` itself::
|
||||||
|
|
||||||
>>> print cfg.make_dict(withoption='var1')
|
>>> print(cfg.make_dict(withoption='var1'))
|
||||||
{'od2.var4': None, 'od2.var5': None,
|
{'od2.var4': None, 'od2.var5': None,
|
||||||
'od2.var6': None,
|
'od2.var6': None,
|
||||||
'od2.var1': u'value',
|
'od2.var1': u'value',
|
||||||
|
@ -643,8 +632,8 @@ class SubConfig(object):
|
||||||
:param withvalue: returns the options that have the value `withvalue`
|
:param withvalue: returns the options that have the value `withvalue`
|
||||||
::
|
::
|
||||||
|
|
||||||
>>> print c.make_dict(withoption='var1',
|
>>> print(c.make_dict(withoption='var1',
|
||||||
withvalue=u'value')
|
withvalue=u'value'))
|
||||||
{'od2.var4': None,
|
{'od2.var4': None,
|
||||||
'od2.var5': None,
|
'od2.var5': None,
|
||||||
'od2.var6': None,
|
'od2.var6': None,
|
||||||
|
@ -798,14 +787,12 @@ class _CommonConfig(SubConfig):
|
||||||
else:
|
else:
|
||||||
if index is None and option.impl_is_master_slaves('slave'):
|
if index is None and option.impl_is_master_slaves('slave'):
|
||||||
subpath = self._get_subpath(path)
|
subpath = self._get_subpath(path)
|
||||||
props = self.cfgimpl_get_settings().validate_properties(option,
|
self.cfgimpl_get_settings().validate_properties(option,
|
||||||
True,
|
True,
|
||||||
False,
|
False,
|
||||||
path=subpath,
|
path=subpath,
|
||||||
force_permissive=force_permissive,
|
force_permissive=force_permissive,
|
||||||
setting_properties=setting_properties)
|
setting_properties=setting_properties)
|
||||||
if props:
|
|
||||||
raise props
|
|
||||||
return option
|
return option
|
||||||
else:
|
else:
|
||||||
return self.getattr(path,
|
return self.getattr(path,
|
||||||
|
@ -975,19 +962,16 @@ class GroupConfig(_CommonConfig):
|
||||||
|
|
||||||
def cfgimpl_reset_cache(self,
|
def cfgimpl_reset_cache(self,
|
||||||
only_expired=False,
|
only_expired=False,
|
||||||
only=('values', 'settings'),
|
|
||||||
opt=None,
|
opt=None,
|
||||||
path=None,
|
path=None,
|
||||||
resetted_opts=set()):
|
resetted_opts=set()):
|
||||||
if isinstance(self, MetaConfig):
|
if isinstance(self, MetaConfig):
|
||||||
super(GroupConfig, self).cfgimpl_reset_cache(only_expired=only_expired,
|
super(GroupConfig, self).cfgimpl_reset_cache(only_expired=only_expired,
|
||||||
only=only,
|
|
||||||
opt=opt,
|
opt=opt,
|
||||||
path=path,
|
path=path,
|
||||||
resetted_opts=copy(resetted_opts))
|
resetted_opts=copy(resetted_opts))
|
||||||
for child in self._impl_children:
|
for child in self._impl_children:
|
||||||
child.cfgimpl_reset_cache(only_expired=only_expired,
|
child.cfgimpl_reset_cache(only_expired=only_expired,
|
||||||
only=only,
|
|
||||||
opt=opt,
|
opt=opt,
|
||||||
path=path,
|
path=path,
|
||||||
resetted_opts=copy(resetted_opts))
|
resetted_opts=copy(resetted_opts))
|
||||||
|
|
|
@ -155,7 +155,7 @@ class ValueWarning(UserWarning): # pragma: optional cover
|
||||||
...
|
...
|
||||||
>>> w[0].message.opt == s
|
>>> w[0].message.opt == s
|
||||||
True
|
True
|
||||||
>>> print str(w[0].message)
|
>>> print(str(w[0].message))
|
||||||
invalid value val for option s: pouet
|
invalid value val for option s: pouet
|
||||||
"""
|
"""
|
||||||
def __init__(self, msg, opt):
|
def __init__(self, msg, opt):
|
||||||
|
|
|
@ -32,7 +32,7 @@ if sys.version_info[0] >= 3: # pragma: no cover
|
||||||
else:
|
else:
|
||||||
from inspect import getargspec
|
from inspect import getargspec
|
||||||
|
|
||||||
STATIC_TUPLE = tuple()
|
STATIC_TUPLE = frozenset()
|
||||||
|
|
||||||
|
|
||||||
submulti = 2
|
submulti = 2
|
||||||
|
@ -145,6 +145,8 @@ class Base(object):
|
||||||
requires = undefined
|
requires = undefined
|
||||||
if properties is None:
|
if properties is None:
|
||||||
properties = tuple()
|
properties = tuple()
|
||||||
|
if is_multi and 'empty' not in properties:
|
||||||
|
properties = tuple(list(properties) + ['empty'])
|
||||||
if not isinstance(properties, tuple):
|
if not isinstance(properties, tuple):
|
||||||
raise TypeError(_('invalid properties type {0} for {1},'
|
raise TypeError(_('invalid properties type {0} for {1},'
|
||||||
' must be a tuple').format(
|
' must be a tuple').format(
|
||||||
|
@ -406,11 +408,15 @@ class BaseOption(Base):
|
||||||
name = name.encode('utf8')
|
name = name.encode('utf8')
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def reset_cache(self, opt, obj, type_, resetted_opts):
|
def reset_cache(self,
|
||||||
|
opt,
|
||||||
|
path,
|
||||||
|
obj,
|
||||||
|
type_,
|
||||||
|
resetted_opts):
|
||||||
if opt in resetted_opts:
|
if opt in resetted_opts:
|
||||||
return
|
return
|
||||||
if not type_ == 'values' or not opt.impl_is_optiondescription():
|
if not type_ == 'values' or not opt.impl_is_optiondescription():
|
||||||
path = opt.impl_getpath(obj._getcontext())
|
|
||||||
if type_ != 'permissives':
|
if type_ != 'permissives':
|
||||||
obj._p_.delcache(path)
|
obj._p_.delcache(path)
|
||||||
if type_ in ['settings', 'permissives']:
|
if type_ in ['settings', 'permissives']:
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
import warnings
|
import warnings
|
||||||
import sys
|
import sys
|
||||||
|
import weakref
|
||||||
|
|
||||||
from .baseoption import OnlyOption, submulti, DynSymLinkOption, validate_callback, STATIC_TUPLE
|
from .baseoption import OnlyOption, submulti, DynSymLinkOption, validate_callback, STATIC_TUPLE
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
|
@ -146,9 +147,17 @@ class Option(OnlyOption):
|
||||||
def impl_is_multi(self):
|
def impl_is_multi(self):
|
||||||
return getattr(self, '_multi', 1) != 1
|
return getattr(self, '_multi', 1) != 1
|
||||||
|
|
||||||
def _launch_consistency(self, current_opt, func, option, value, context,
|
def _launch_consistency(self,
|
||||||
index, submulti_index, opts, warnings_only,
|
current_opt,
|
||||||
transitive):
|
func,
|
||||||
|
option,
|
||||||
|
value,
|
||||||
|
context,
|
||||||
|
index,
|
||||||
|
opts,
|
||||||
|
warnings_only,
|
||||||
|
transitive,
|
||||||
|
setting_properties):
|
||||||
"""Launch consistency now
|
"""Launch consistency now
|
||||||
|
|
||||||
:param func: function name, this name should start with _cons_
|
:param func: function name, this name should start with _cons_
|
||||||
|
@ -174,7 +183,8 @@ class Option(OnlyOption):
|
||||||
all_cons_vals = []
|
all_cons_vals = []
|
||||||
all_cons_opts = []
|
all_cons_opts = []
|
||||||
val_consistencies = True
|
val_consistencies = True
|
||||||
for opt in opts:
|
for wopt in opts:
|
||||||
|
opt = wopt()
|
||||||
if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
|
if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
|
||||||
option == opt:
|
option == opt:
|
||||||
# option is current option
|
# option is current option
|
||||||
|
@ -195,7 +205,9 @@ class Option(OnlyOption):
|
||||||
else:
|
else:
|
||||||
_index = index
|
_index = index
|
||||||
try:
|
try:
|
||||||
opt_value = context.getattr(path, validate=False,
|
opt_value = context.getattr(path,
|
||||||
|
setting_properties,
|
||||||
|
validate=False,
|
||||||
index=_index,
|
index=_index,
|
||||||
force_permissive=True)
|
force_permissive=True)
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
|
@ -254,7 +266,6 @@ class Option(OnlyOption):
|
||||||
context=undefined,
|
context=undefined,
|
||||||
validate=True,
|
validate=True,
|
||||||
force_index=None,
|
force_index=None,
|
||||||
force_submulti_index=None,
|
|
||||||
current_opt=undefined,
|
current_opt=undefined,
|
||||||
is_multi=None,
|
is_multi=None,
|
||||||
display_error=True,
|
display_error=True,
|
||||||
|
@ -270,9 +281,6 @@ class Option(OnlyOption):
|
||||||
:param force_index: if multi, value has to be a list
|
:param force_index: if multi, value has to be a list
|
||||||
not if force_index is not None
|
not if force_index is not None
|
||||||
:type force_index: integer
|
:type force_index: integer
|
||||||
:param force_submulti_index: if submulti, value has to be a list
|
|
||||||
not if force_submulti_index is not None
|
|
||||||
:type force_submulti_index: integer
|
|
||||||
"""
|
"""
|
||||||
if not validate:
|
if not validate:
|
||||||
return
|
return
|
||||||
|
@ -287,10 +295,12 @@ class Option(OnlyOption):
|
||||||
if display_error and self.impl_is_unique() and len(set(value)) != len(value):
|
if display_error and self.impl_is_unique() and len(set(value)) != len(value):
|
||||||
for idx, val in enumerate(value):
|
for idx, val in enumerate(value):
|
||||||
if val in value[idx+1:]:
|
if val in value[idx+1:]:
|
||||||
return ValueError(_('invalid value "{}", this value is already in "{}"').format(
|
return ValueError(_('invalid value "{}", this value is already in "{}"'
|
||||||
val, self.impl_get_display_name()))
|
'').format(val,
|
||||||
|
self.impl_get_display_name()))
|
||||||
|
|
||||||
def calculation_validator(val, _index):
|
def calculation_validator(val,
|
||||||
|
_index):
|
||||||
validator, validator_params = self.impl_get_validator()
|
validator, validator_params = self.impl_get_validator()
|
||||||
if validator is not None:
|
if validator is not None:
|
||||||
if validator_params != {}:
|
if validator_params != {}:
|
||||||
|
@ -316,9 +326,10 @@ class Option(OnlyOption):
|
||||||
if isinstance(value, Exception):
|
if isinstance(value, Exception):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def do_validation(_value, _index, submulti_index):
|
def do_validation(_value,
|
||||||
|
_index):
|
||||||
if _value is None:
|
if _value is None:
|
||||||
error = warning = None
|
error = None
|
||||||
else:
|
else:
|
||||||
if display_error:
|
if display_error:
|
||||||
# option validation
|
# option validation
|
||||||
|
@ -327,35 +338,41 @@ class Option(OnlyOption):
|
||||||
current_opt)
|
current_opt)
|
||||||
if err:
|
if err:
|
||||||
if debug: # pragma: no cover
|
if debug: # pragma: no cover
|
||||||
log.debug('do_validation: value: {0}, index: {1}, '
|
log.debug('do_validation: value: {0}, index: {1}:'
|
||||||
'submulti_index: {2}'.format(_value,
|
' {2}'.format(_value,
|
||||||
_index,
|
_index),
|
||||||
submulti_index),
|
|
||||||
exc_info=True)
|
exc_info=True)
|
||||||
err_msg = '{0}'.format(err)
|
err_msg = '{0}'.format(err)
|
||||||
if err_msg:
|
if err_msg:
|
||||||
msg = _('"{0}" is an invalid {1} for "{2}", {3}'
|
msg = _('"{0}" is an invalid {1} for "{2}", {3}'
|
||||||
'').format(_value, self._display_name,
|
'').format(_value,
|
||||||
|
self._display_name,
|
||||||
self.impl_get_display_name(), err_msg)
|
self.impl_get_display_name(), err_msg)
|
||||||
else:
|
else:
|
||||||
msg = _('"{0}" is an invalid {1} for "{2}"'
|
msg = _('"{0}" is an invalid {1} for "{2}"'
|
||||||
'').format(_value, self._display_name,
|
'').format(_value,
|
||||||
|
self._display_name,
|
||||||
self.impl_get_display_name())
|
self.impl_get_display_name())
|
||||||
return ValueError(msg)
|
return ValueError(msg)
|
||||||
error = None
|
error = None
|
||||||
is_warnings_only = getattr(self, '_warnings_only', False)
|
is_warnings_only = getattr(self, '_warnings_only', False)
|
||||||
if ((display_error and not is_warnings_only) or
|
if ((display_error and not is_warnings_only) or
|
||||||
(display_warnings and is_warnings_only)):
|
(display_warnings and is_warnings_only)):
|
||||||
error = calculation_validator(_value, _index)
|
error = calculation_validator(_value,
|
||||||
|
_index)
|
||||||
if not error:
|
if not error:
|
||||||
error = self._second_level_validation(_value, is_warnings_only)
|
error = self._second_level_validation(_value,
|
||||||
|
is_warnings_only)
|
||||||
if error:
|
if error:
|
||||||
if debug: # pragma: no cover
|
if debug: # pragma: no cover
|
||||||
log.debug(_('do_validation for {0}: error in value').format(
|
log.debug(_('do_validation for {0}: error in value').format(
|
||||||
self.impl_getname()), exc_info=True)
|
self.impl_getname()), exc_info=True)
|
||||||
if is_warnings_only:
|
if is_warnings_only:
|
||||||
msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}').format(
|
msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}'
|
||||||
_value, self._display_name, self.impl_get_display_name(), error)
|
'').format(_value,
|
||||||
|
self._display_name,
|
||||||
|
self.impl_get_display_name(),
|
||||||
|
error)
|
||||||
warnings.warn_explicit(ValueWarning(msg, self),
|
warnings.warn_explicit(ValueWarning(msg, self),
|
||||||
ValueWarning,
|
ValueWarning,
|
||||||
self.__class__.__name__, 0)
|
self.__class__.__name__, 0)
|
||||||
|
@ -367,9 +384,9 @@ class Option(OnlyOption):
|
||||||
_value,
|
_value,
|
||||||
context,
|
context,
|
||||||
_index,
|
_index,
|
||||||
submulti_index,
|
|
||||||
display_warnings,
|
display_warnings,
|
||||||
display_error)
|
display_error,
|
||||||
|
setting_properties)
|
||||||
if isinstance(ret, ValueError):
|
if isinstance(ret, ValueError):
|
||||||
error = ret
|
error = ret
|
||||||
elif ret:
|
elif ret:
|
||||||
|
@ -390,22 +407,22 @@ class Option(OnlyOption):
|
||||||
is_multi = self.impl_is_multi()
|
is_multi = self.impl_is_multi()
|
||||||
|
|
||||||
if not is_multi:
|
if not is_multi:
|
||||||
return do_validation(value, None, None)
|
return do_validation(value, None)
|
||||||
elif force_index is not None:
|
elif force_index is not None:
|
||||||
if self.impl_is_submulti() and force_submulti_index is None:
|
if self.impl_is_submulti():
|
||||||
err = _is_not_unique(value)
|
err = _is_not_unique(value)
|
||||||
if err:
|
if err:
|
||||||
return err
|
return err
|
||||||
if not isinstance(value, list):
|
if not isinstance(value, list):
|
||||||
return ValueError(_('invalid value "{0}" for "{1}" which'
|
return ValueError(_('invalid value "{0}" for "{1}" which'
|
||||||
' must be a list').format(
|
' must be a list').format(
|
||||||
value, self.impl_get_display_name()))
|
value, self.impl_get_display_name()))
|
||||||
for idx, val in enumerate(value):
|
for idx, val in enumerate(value):
|
||||||
if isinstance(val, list): # pragma: no cover
|
if isinstance(val, list): # pragma: no cover
|
||||||
return ValueError(_('invalid value "{}" for "{}" '
|
return ValueError(_('invalid value "{}" for "{}" '
|
||||||
'which must not be a list').format(val,
|
'which must not be a list').format(val,
|
||||||
self.impl_get_display_name()))
|
self.impl_get_display_name()))
|
||||||
err = do_validation(val, force_index, idx)
|
err = do_validation(val, force_index)
|
||||||
if err:
|
if err:
|
||||||
return err
|
return err
|
||||||
else:
|
else:
|
||||||
|
@ -419,12 +436,12 @@ class Option(OnlyOption):
|
||||||
return ValueError(_('invalid value "{}", this value is already'
|
return ValueError(_('invalid value "{}", this value is already'
|
||||||
' in "{}"').format(value,
|
' in "{}"').format(value,
|
||||||
self.impl_get_display_name()))
|
self.impl_get_display_name()))
|
||||||
return do_validation(value, force_index, force_submulti_index)
|
return do_validation(value, force_index)
|
||||||
elif not isinstance(value, list):
|
elif not isinstance(value, list):
|
||||||
return ValueError(_('invalid value "{0}" for "{1}" which '
|
return ValueError(_('invalid value "{0}" for "{1}" which '
|
||||||
'must be a list').format(value,
|
'must be a list').format(value,
|
||||||
self.impl_getname()))
|
self.impl_getname()))
|
||||||
elif self.impl_is_submulti() and force_submulti_index is None:
|
elif self.impl_is_submulti():
|
||||||
for idx, val in enumerate(value):
|
for idx, val in enumerate(value):
|
||||||
err = _is_not_unique(val)
|
err = _is_not_unique(val)
|
||||||
if err:
|
if err:
|
||||||
|
@ -434,8 +451,9 @@ class Option(OnlyOption):
|
||||||
'which must be a list of list'
|
'which must be a list of list'
|
||||||
'').format(val,
|
'').format(val,
|
||||||
self.impl_getname()))
|
self.impl_getname()))
|
||||||
for slave_idx, slave_val in enumerate(val):
|
for slave_val in val:
|
||||||
err = do_validation(slave_val, idx, slave_idx)
|
err = do_validation(slave_val,
|
||||||
|
idx)
|
||||||
if err:
|
if err:
|
||||||
return err
|
return err
|
||||||
else:
|
else:
|
||||||
|
@ -443,16 +461,17 @@ class Option(OnlyOption):
|
||||||
if err:
|
if err:
|
||||||
return err
|
return err
|
||||||
for idx, val in enumerate(value):
|
for idx, val in enumerate(value):
|
||||||
err = do_validation(val, idx, force_submulti_index)
|
err = do_validation(val,
|
||||||
|
idx)
|
||||||
if err:
|
if err:
|
||||||
return err
|
return err
|
||||||
return self._valid_consistency(current_opt,
|
return self._valid_consistency(current_opt,
|
||||||
None,
|
None,
|
||||||
context,
|
context,
|
||||||
None,
|
None,
|
||||||
None,
|
|
||||||
display_warnings,
|
display_warnings,
|
||||||
display_error)
|
display_error,
|
||||||
|
setting_properties)
|
||||||
|
|
||||||
def impl_is_dynsymlinkoption(self):
|
def impl_is_dynsymlinkoption(self):
|
||||||
return False
|
return False
|
||||||
|
@ -480,7 +499,10 @@ class Option(OnlyOption):
|
||||||
"accesses the Option's doc"
|
"accesses the Option's doc"
|
||||||
return self.impl_get_information('doc')
|
return self.impl_get_information('doc')
|
||||||
|
|
||||||
def _valid_consistencies(self, other_opts, init=True, func=None):
|
def _valid_consistencies(self,
|
||||||
|
other_opts,
|
||||||
|
init=True,
|
||||||
|
func=None):
|
||||||
if self._is_subdyn():
|
if self._is_subdyn():
|
||||||
dynod = self._subdyn()
|
dynod = self._subdyn()
|
||||||
else:
|
else:
|
||||||
|
@ -488,7 +510,11 @@ class Option(OnlyOption):
|
||||||
if self.impl_is_submulti():
|
if self.impl_is_submulti():
|
||||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||||
is_multi = self.impl_is_multi()
|
is_multi = self.impl_is_multi()
|
||||||
for opt in other_opts:
|
for wopt in other_opts:
|
||||||
|
if isinstance(wopt, weakref.ReferenceType):
|
||||||
|
opt = wopt()
|
||||||
|
else:
|
||||||
|
opt = wopt
|
||||||
if opt.impl_is_submulti():
|
if opt.impl_is_submulti():
|
||||||
raise ConfigError(_('cannot add consistency with submulti option'))
|
raise ConfigError(_('cannot add consistency with submulti option'))
|
||||||
if not isinstance(opt, Option):
|
if not isinstance(opt, Option):
|
||||||
|
@ -515,7 +541,10 @@ class Option(OnlyOption):
|
||||||
if func != 'not_equal':
|
if func != 'not_equal':
|
||||||
opt._has_dependency = True
|
opt._has_dependency = True
|
||||||
|
|
||||||
def impl_add_consistency(self, func, *other_opts, **params):
|
def impl_add_consistency(self,
|
||||||
|
func,
|
||||||
|
*other_opts,
|
||||||
|
**params):
|
||||||
"""Add consistency means that value will be validate with other_opts
|
"""Add consistency means that value will be validate with other_opts
|
||||||
option's values.
|
option's values.
|
||||||
|
|
||||||
|
@ -525,39 +554,51 @@ class Option(OnlyOption):
|
||||||
:type other_opts: `list` of `tiramisu.option.Option`
|
:type other_opts: `list` of `tiramisu.option.Option`
|
||||||
:param params: extra params (warnings_only and transitive are allowed)
|
:param params: extra params (warnings_only and transitive are allowed)
|
||||||
"""
|
"""
|
||||||
if self.impl_is_readonly():
|
if self.impl_is_readonly():
|
||||||
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
|
raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
|
||||||
" read-only").format(
|
" read-only").format(
|
||||||
self.__class__.__name__,
|
self.__class__.__name__,
|
||||||
self.impl_getname()))
|
self.impl_getname()))
|
||||||
self._valid_consistencies(other_opts, func=func)
|
self._valid_consistencies(other_opts,
|
||||||
|
func=func)
|
||||||
func = '_cons_{0}'.format(func)
|
func = '_cons_{0}'.format(func)
|
||||||
if func not in dir(self):
|
if func not in dir(self):
|
||||||
raise ConfigError(_('consistency {0} not available for this option').format(func))
|
raise ConfigError(_('consistency {0} not available for this option').format(func))
|
||||||
all_cons_opts = tuple([self] + list(other_opts))
|
options = [weakref.ref(self)]
|
||||||
|
for option in other_opts:
|
||||||
|
options.append(weakref.ref(option))
|
||||||
|
all_cons_opts = tuple(options)
|
||||||
unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
|
unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
|
||||||
if unknown_params != set():
|
if unknown_params != set():
|
||||||
raise ValueError(_('unknown parameter {0} in consistency').format(unknown_params))
|
raise ValueError(_('unknown parameter {0} in consistency').format(unknown_params))
|
||||||
self._add_consistency(func, all_cons_opts, params)
|
self._add_consistency(func,
|
||||||
|
all_cons_opts,
|
||||||
|
params)
|
||||||
#validate default value when add consistency
|
#validate default value when add consistency
|
||||||
err = self.impl_validate(self.impl_getdefault())
|
err = self.impl_validate(self.impl_getdefault())
|
||||||
if err:
|
if err:
|
||||||
self._del_consistency()
|
self._del_consistency()
|
||||||
raise err
|
raise err
|
||||||
if func in ALLOWED_CONST_LIST:
|
|
||||||
for opt in all_cons_opts:
|
|
||||||
if getattr(opt, '_unique', undefined) == undefined:
|
|
||||||
opt._unique = True
|
|
||||||
if func != '_cons_not_equal':
|
if func != '_cons_not_equal':
|
||||||
#consistency could generate warnings or errors
|
#consistency could generate warnings or errors
|
||||||
self._has_dependency = True
|
self._has_dependency = True
|
||||||
for opt in all_cons_opts:
|
for wopt in all_cons_opts:
|
||||||
|
opt = wopt()
|
||||||
|
if func in ALLOWED_CONST_LIST:
|
||||||
|
if getattr(opt, '_unique', undefined) == undefined:
|
||||||
|
opt._unique = True
|
||||||
if opt != self:
|
if opt != self:
|
||||||
self._add_dependency(opt)
|
self._add_dependency(opt)
|
||||||
opt._add_dependency(self)
|
opt._add_dependency(self)
|
||||||
|
|
||||||
def _valid_consistency(self, option, value, context, index, submulti_idx,
|
def _valid_consistency(self,
|
||||||
display_warnings, display_error):
|
option,
|
||||||
|
value,
|
||||||
|
context,
|
||||||
|
index,
|
||||||
|
display_warnings,
|
||||||
|
display_error,
|
||||||
|
setting_properties):
|
||||||
if context is not undefined:
|
if context is not undefined:
|
||||||
descr = context.cfgimpl_get_description()
|
descr = context.cfgimpl_get_description()
|
||||||
if descr._cache_consistencies is None:
|
if descr._cache_consistencies is None:
|
||||||
|
@ -586,10 +627,16 @@ class Option(OnlyOption):
|
||||||
opts.append(opt._impl_to_dyn(name, path))
|
opts.append(opt._impl_to_dyn(name, path))
|
||||||
else:
|
else:
|
||||||
opts = all_cons_opts
|
opts = all_cons_opts
|
||||||
err = opts[0]._launch_consistency(self, func, option, value,
|
err = opts[0]()._launch_consistency(self,
|
||||||
context, index, submulti_idx,
|
func,
|
||||||
opts, warnings_only,
|
option,
|
||||||
transitive)
|
value,
|
||||||
|
context,
|
||||||
|
index,
|
||||||
|
opts,
|
||||||
|
warnings_only,
|
||||||
|
transitive,
|
||||||
|
setting_properties)
|
||||||
if err:
|
if err:
|
||||||
return err
|
return err
|
||||||
|
|
||||||
|
@ -680,7 +727,10 @@ class Option(OnlyOption):
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
# consistency
|
# consistency
|
||||||
def _add_consistency(self, func, all_cons_opts, params):
|
def _add_consistency(self,
|
||||||
|
func,
|
||||||
|
all_cons_opts,
|
||||||
|
params):
|
||||||
cons = (func, all_cons_opts, params)
|
cons = (func, all_cons_opts, params)
|
||||||
consistencies = getattr(self, '_consistencies', None)
|
consistencies = getattr(self, '_consistencies', None)
|
||||||
if consistencies is None:
|
if consistencies is None:
|
||||||
|
|
|
@ -125,8 +125,8 @@ class CacheOptionDescription(BaseOption):
|
||||||
'must be in same master/slaves for {1}').format(
|
'must be in same master/slaves for {1}').format(
|
||||||
require_opt.impl_getname(), option.impl_getname()))
|
require_opt.impl_getname(), option.impl_getname()))
|
||||||
else:
|
else:
|
||||||
raise ValueError(_('malformed requirements option {0} '
|
raise ValueError(_('malformed requirements option "{0}" '
|
||||||
'must not be a multi for {1}').format(
|
'must not be a multi for "{1}"').format(
|
||||||
require_opt.impl_getname(), option.impl_getname()))
|
require_opt.impl_getname(), option.impl_getname()))
|
||||||
if init:
|
if init:
|
||||||
if len(cache_option) != len(set(cache_option)):
|
if len(cache_option) != len(set(cache_option)):
|
||||||
|
@ -137,7 +137,7 @@ class CacheOptionDescription(BaseOption):
|
||||||
if _consistencies != {}:
|
if _consistencies != {}:
|
||||||
self._cache_consistencies = {}
|
self._cache_consistencies = {}
|
||||||
for opt, cons in _consistencies.items():
|
for opt, cons in _consistencies.items():
|
||||||
if opt not in cache_option: # pragma: optional cover
|
if opt() not in cache_option: # pragma: optional cover
|
||||||
raise ConfigError(_('consistency with option {0} '
|
raise ConfigError(_('consistency with option {0} '
|
||||||
'which is not in Config').format(
|
'which is not in Config').format(
|
||||||
opt.impl_getname()))
|
opt.impl_getname()))
|
||||||
|
@ -437,12 +437,12 @@ class OptionDescription(OptionDescriptionWalk):
|
||||||
for child in valid_child:
|
for child in valid_child:
|
||||||
if child == old: # pragma: optional cover
|
if child == old: # pragma: optional cover
|
||||||
raise ConflictError(_('duplicate option name: '
|
raise ConflictError(_('duplicate option name: '
|
||||||
'{0}').format(child))
|
'"{0}"').format(child))
|
||||||
if dynopt_names:
|
if dynopt_names:
|
||||||
for dynopt in dynopt_names:
|
for dynopt in dynopt_names:
|
||||||
if child != dynopt and child.startswith(dynopt):
|
if child != dynopt and child.startswith(dynopt):
|
||||||
raise ConflictError(_('option must not start as '
|
raise ConflictError(_('the option\'s name "{}" start as '
|
||||||
'dynoptiondescription'))
|
'the dynoptiondescription\'s name "{}"').format(child, dynopt))
|
||||||
old = child
|
old = child
|
||||||
_setattr = object.__setattr__
|
_setattr = object.__setattr__
|
||||||
_setattr(self, '_children', (tuple(child_names), tuple(children)))
|
_setattr(self, '_children', (tuple(child_names), tuple(children)))
|
||||||
|
@ -623,7 +623,7 @@ class MasterSlaves(OptionDescription):
|
||||||
name))
|
name))
|
||||||
slaves.append(child)
|
slaves.append(child)
|
||||||
child._add_dependency(self)
|
child._add_dependency(self)
|
||||||
for child in children:
|
for idx, child in enumerate(children):
|
||||||
if child._is_symlinkoption(): # pragma: optional cover
|
if child._is_symlinkoption(): # pragma: optional cover
|
||||||
raise ValueError(_("master group {0} shall not have "
|
raise ValueError(_("master group {0} shall not have "
|
||||||
"a symlinkoption").format(self.impl_getname()))
|
"a symlinkoption").format(self.impl_getname()))
|
||||||
|
@ -635,6 +635,11 @@ class MasterSlaves(OptionDescription):
|
||||||
"in group {1}"
|
"in group {1}"
|
||||||
": this option is not a multi"
|
": this option is not a multi"
|
||||||
"").format(child.impl_getname(), self.impl_getname()))
|
"").format(child.impl_getname(), self.impl_getname()))
|
||||||
|
# no empty property for save
|
||||||
|
if idx != 0:
|
||||||
|
properties = list(child._properties)
|
||||||
|
properties.remove('empty')
|
||||||
|
child._properties = tuple(properties)
|
||||||
callback, callback_params = master.impl_get_callback()
|
callback, callback_params = master.impl_get_callback()
|
||||||
if callback is not None and callback_params != {}:
|
if callback is not None and callback_params != {}:
|
||||||
for callbacks in callback_params.values():
|
for callbacks in callback_params.values():
|
||||||
|
|
|
@ -106,7 +106,8 @@ rw_append = set(['frozen', 'disabled', 'validator', 'hidden'])
|
||||||
rw_remove = set(['permissive', 'everything_frozen', 'mandatory', 'empty'])
|
rw_remove = set(['permissive', 'everything_frozen', 'mandatory', 'empty'])
|
||||||
|
|
||||||
|
|
||||||
forbidden_set_properties = set(['force_store_value'])
|
forbidden_set_properties = frozenset(['force_store_value'])
|
||||||
|
forbidden_set_permissives = frozenset(['frozen', 'force_default_on_freeze'])
|
||||||
|
|
||||||
|
|
||||||
log = getLogger('tiramisu')
|
log = getLogger('tiramisu')
|
||||||
|
@ -124,15 +125,16 @@ class _NameSpace(object):
|
||||||
when attribute is added, we cannot delete it
|
when attribute is added, we cannot delete it
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self,
|
||||||
if name in self.__dict__: # pragma: optional cover
|
name,
|
||||||
|
value):
|
||||||
|
if name in self.__dict__:
|
||||||
raise ConstError(_("can't rebind {0}").format(name))
|
raise ConstError(_("can't rebind {0}").format(name))
|
||||||
self.__dict__[name] = value
|
self.__dict__[name] = value
|
||||||
|
|
||||||
def __delattr__(self, name): # pragma: optional cover
|
def __delattr__(self,
|
||||||
if name in self.__dict__:
|
name):
|
||||||
raise ConstError(_("can't unbind {0}").format(name))
|
raise ConstError(_("can't unbind {0}").format(name))
|
||||||
raise ValueError(name)
|
|
||||||
|
|
||||||
|
|
||||||
class GroupModule(_NameSpace):
|
class GroupModule(_NameSpace):
|
||||||
|
@ -168,69 +170,44 @@ class OwnerModule(_NameSpace):
|
||||||
"""groups that are default (typically 'default')"""
|
"""groups that are default (typically 'default')"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def addowner(self, name):
|
||||||
class MultiTypeModule(_NameSpace):
|
|
||||||
"namespace for the master/slaves"
|
|
||||||
class MultiType(str):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class DefaultMultiType(MultiType):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class MasterMultiType(MultiType):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class SlaveMultiType(MultiType):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
# ____________________________________________________________
|
|
||||||
def populate_groups():
|
|
||||||
"""populates the available groups in the appropriate namespaces
|
|
||||||
|
|
||||||
groups.default
|
|
||||||
default group set when creating a new optiondescription
|
|
||||||
|
|
||||||
groups.master
|
|
||||||
master group is a special optiondescription, all suboptions should be
|
|
||||||
multi option and all values should have same length, to find master's
|
|
||||||
option, the optiondescription's name should be same than de master's
|
|
||||||
option
|
|
||||||
|
|
||||||
groups.family
|
|
||||||
example of group, no special behavior with this group's type
|
|
||||||
"""
|
|
||||||
groups.default = groups.DefaultGroupType('default')
|
|
||||||
groups.master = groups.MasterGroupType('master')
|
|
||||||
groups.family = groups.GroupType('family')
|
|
||||||
|
|
||||||
|
|
||||||
def populate_owners():
|
|
||||||
"""populates the available owners in the appropriate namespaces
|
|
||||||
|
|
||||||
default
|
|
||||||
is the config owner after init time
|
|
||||||
|
|
||||||
user
|
|
||||||
is the generic is the generic owner
|
|
||||||
"""
|
|
||||||
setattr(owners, 'default', owners.DefaultOwner('default'))
|
|
||||||
setattr(owners, 'user', owners.Owner('user'))
|
|
||||||
setattr(owners, 'forced', owners.Owner('forced'))
|
|
||||||
|
|
||||||
def addowner(name):
|
|
||||||
"""
|
"""
|
||||||
:param name: the name of the new owner
|
:param name: the name of the new owner
|
||||||
"""
|
"""
|
||||||
setattr(owners, name, owners.Owner(name))
|
setattr(owners, name, owners.Owner(name))
|
||||||
setattr(owners, 'addowner', addowner)
|
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# populate groups and owners with default attributes
|
# populate groups
|
||||||
groups = GroupModule()
|
groups = GroupModule()
|
||||||
populate_groups()
|
"""groups.default
|
||||||
|
default group set when creating a new optiondescription"""
|
||||||
|
groups.default = groups.DefaultGroupType('default')
|
||||||
|
|
||||||
|
"""groups.master
|
||||||
|
master group is a special optiondescription, all suboptions should be
|
||||||
|
multi option and all values should have same length, to find master's
|
||||||
|
option, the optiondescription's name should be same than de master's
|
||||||
|
option"""
|
||||||
|
groups.master = groups.MasterGroupType('master')
|
||||||
|
|
||||||
|
""" groups.family
|
||||||
|
example of group, no special behavior with this group's type"""
|
||||||
|
groups.family = groups.GroupType('family')
|
||||||
|
|
||||||
|
|
||||||
|
# ____________________________________________________________
|
||||||
|
# populate owners with default attributes
|
||||||
owners = OwnerModule()
|
owners = OwnerModule()
|
||||||
populate_owners()
|
"""default
|
||||||
|
is the config owner after init time"""
|
||||||
|
owners.default = owners.DefaultOwner('default')
|
||||||
|
"""user
|
||||||
|
is the generic is the generic owner"""
|
||||||
|
owners.user = owners.Owner('user')
|
||||||
|
"""forced
|
||||||
|
special owner when value is forced"""
|
||||||
|
owners.forced = owners.Owner('forced')
|
||||||
|
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
|
@ -241,73 +218,6 @@ class Undefined(object):
|
||||||
undefined = Undefined()
|
undefined = Undefined()
|
||||||
|
|
||||||
|
|
||||||
# ____________________________________________________________
|
|
||||||
class Property(object):
|
|
||||||
"a property is responsible of the option's value access rules"
|
|
||||||
__slots__ = ('_setting', '_properties', '_opt', '_path')
|
|
||||||
|
|
||||||
def __init__(self, setting, prop, opt=None, path=None):
|
|
||||||
self._opt = opt
|
|
||||||
self._path = path
|
|
||||||
self._setting = setting
|
|
||||||
self._properties = prop
|
|
||||||
|
|
||||||
def append(self, propname):
|
|
||||||
"""Appends a property named propname
|
|
||||||
|
|
||||||
:param propname: a predefined or user defined property name
|
|
||||||
:type propname: string
|
|
||||||
"""
|
|
||||||
self._append(propname)
|
|
||||||
|
|
||||||
def _append(self, propname, save=True):
|
|
||||||
if self._opt is not None and self._opt.impl_getrequires() is not None \
|
|
||||||
and propname in getattr(self._opt, '_calc_properties', static_set): # pragma: optional cover
|
|
||||||
raise ValueError(_('cannot append {0} property for option {1}: '
|
|
||||||
'this property is calculated').format(
|
|
||||||
propname, self._opt.impl_getname()))
|
|
||||||
if propname in forbidden_set_properties:
|
|
||||||
raise ConfigError(_('cannot add those properties: {0}').format(propname))
|
|
||||||
self._properties.add(propname)
|
|
||||||
if save:
|
|
||||||
self._setting.setproperties(self._properties, self._opt, self._path, force=True)
|
|
||||||
|
|
||||||
def remove(self, propname):
|
|
||||||
"""Removes a property named propname
|
|
||||||
|
|
||||||
:param propname: a predefined or user defined property name
|
|
||||||
:type propname: string
|
|
||||||
"""
|
|
||||||
if propname in self._properties:
|
|
||||||
self._properties.remove(propname)
|
|
||||||
self._setting.setproperties(self._properties, self._opt, self._path)
|
|
||||||
|
|
||||||
def extend(self, propnames):
|
|
||||||
"""Extends properties to the existing properties
|
|
||||||
|
|
||||||
:param propnames: an iterable made of property names
|
|
||||||
:type propnames: iterable of string
|
|
||||||
"""
|
|
||||||
for propname in propnames:
|
|
||||||
self._append(propname, save=False)
|
|
||||||
self._setting.setproperties(self._properties, self._opt, self._path)
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
"""resets the properties (does not **clear** the properties,
|
|
||||||
default properties are still present)
|
|
||||||
"""
|
|
||||||
self._setting.reset(_path=self._path)
|
|
||||||
|
|
||||||
def __contains__(self, propname):
|
|
||||||
return propname in self._properties
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return str(list(self._properties))
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
return tuple(self._properties)
|
|
||||||
|
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
class Settings(object):
|
class Settings(object):
|
||||||
"``config.Config()``'s configuration options settings"
|
"``config.Config()``'s configuration options settings"
|
||||||
|
@ -341,321 +251,89 @@ class Settings(object):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
#____________________________________________________________
|
#____________________________________________________________
|
||||||
# properties methods
|
# get properties and permissive methods
|
||||||
def __contains__(self, propname):
|
|
||||||
"enables the pythonic 'in' syntaxic sugar"
|
|
||||||
return propname in self._getproperties(read_write=False)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def get_context_properties(self):
|
||||||
return str(list(self._getproperties(read_write=False)))
|
ntime = int(time())
|
||||||
|
if self._p_.hascache(None,
|
||||||
def __getitem__(self, opt):
|
None):
|
||||||
path = opt.impl_getpath(self._getcontext())
|
is_cached, props = self._p_.getcache(None,
|
||||||
return self.getproperties(opt, path)
|
ntime,
|
||||||
|
None)
|
||||||
|
else:
|
||||||
|
is_cached = False
|
||||||
|
if not is_cached or 'cache' not in props:
|
||||||
|
meta = self._getcontext().cfgimpl_get_meta()
|
||||||
|
if meta is None:
|
||||||
|
props = self._p_.getproperties(None,
|
||||||
|
default_properties)
|
||||||
|
else:
|
||||||
|
props = meta.cfgimpl_get_settings().get_context_properties()
|
||||||
|
if 'cache' in props:
|
||||||
|
if 'expire' in props:
|
||||||
|
ntime = ntime + expires_time
|
||||||
|
else:
|
||||||
|
ntime = None
|
||||||
|
self._p_.setcache(None, props, ntime, None)
|
||||||
|
return props
|
||||||
|
|
||||||
def getproperties(self,
|
def getproperties(self,
|
||||||
opt,
|
opt,
|
||||||
path,
|
path,
|
||||||
setting_properties=undefined,
|
setting_properties,
|
||||||
index=None,
|
index=None,
|
||||||
obj=True):
|
apply_requires=True):
|
||||||
"""get properties for a specified option
|
|
||||||
"""
|
|
||||||
properties = self._getproperties(opt,
|
|
||||||
path,
|
|
||||||
index=index,
|
|
||||||
setting_properties=setting_properties)
|
|
||||||
if obj:
|
|
||||||
return Property(self, properties, opt, path)
|
|
||||||
return properties
|
|
||||||
|
|
||||||
def get_context_properties(self):
|
|
||||||
return self._getproperties()
|
|
||||||
|
|
||||||
def __setitem__(self, opt, value): # pragma: optional cover
|
|
||||||
raise ValueError(_('you should only append/remove properties'))
|
|
||||||
|
|
||||||
def reset(self, opt=None, _path=None, all_properties=False):
|
|
||||||
if all_properties and (_path or opt): # pragma: optional cover
|
|
||||||
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())
|
|
||||||
self._p_.delproperties(_path)
|
|
||||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path, only=('settings', 'values'))
|
|
||||||
|
|
||||||
def _getproperties(self,
|
|
||||||
opt=None,
|
|
||||||
path=None,
|
|
||||||
setting_properties=undefined,
|
|
||||||
read_write=True,
|
|
||||||
apply_requires=True,
|
|
||||||
index=None):
|
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
if opt is None:
|
is_cached = False
|
||||||
ntime = int(time())
|
|
||||||
if self._p_.hascache(path, index):
|
|
||||||
is_cached, props = self._p_.getcache(path, ntime, None)
|
|
||||||
else:
|
|
||||||
is_cached = False
|
|
||||||
if not is_cached or 'cache' not in props:
|
|
||||||
meta = self._getcontext().cfgimpl_get_meta()
|
|
||||||
if meta is None:
|
|
||||||
props = self._p_.getproperties(path, default_properties)
|
|
||||||
else:
|
|
||||||
props = meta.cfgimpl_get_settings()._getproperties()
|
|
||||||
if 'cache' in props:
|
|
||||||
if 'expire' in props:
|
|
||||||
ntime = ntime + expires_time
|
|
||||||
else:
|
|
||||||
ntime = None
|
|
||||||
self._p_.setcache(path, props, ntime, None)
|
|
||||||
else:
|
|
||||||
if path is None: # pragma: optional cover
|
|
||||||
raise ValueError(_('if opt is not None, path should not be'
|
|
||||||
' None in _getproperties'))
|
|
||||||
if setting_properties is undefined:
|
|
||||||
setting_properties = self._getproperties(read_write=False)
|
|
||||||
is_cached = False
|
|
||||||
|
|
||||||
if apply_requires:
|
if apply_requires:
|
||||||
if 'cache' in setting_properties and 'expire' in setting_properties:
|
if 'cache' in setting_properties and 'expire' in setting_properties:
|
||||||
ntime = int(time())
|
ntime = int(time())
|
||||||
else:
|
|
||||||
ntime = None
|
|
||||||
if 'cache' in setting_properties and self._p_.hascache(path, index):
|
|
||||||
is_cached, props = self._p_.getcache(path, ntime, index)
|
|
||||||
if not is_cached:
|
|
||||||
props = self._p_.getproperties(path, opt.impl_getproperties())
|
|
||||||
if not opt.impl_is_optiondescription() and opt.impl_is_multi() and \
|
|
||||||
not opt.impl_is_master_slaves('slave'):
|
|
||||||
props.add('empty')
|
|
||||||
if apply_requires:
|
|
||||||
requires = self.apply_requires(opt, path, setting_properties, index, False)
|
|
||||||
if requires != set([]):
|
|
||||||
props = copy(props)
|
|
||||||
props |= requires
|
|
||||||
if 'cache' in setting_properties:
|
|
||||||
if 'expire' in setting_properties:
|
|
||||||
ntime = ntime + expires_time
|
|
||||||
self._p_.setcache(path, props, ntime, index)
|
|
||||||
if read_write:
|
|
||||||
props = copy(props)
|
|
||||||
return props
|
|
||||||
|
|
||||||
def append(self, propname):
|
|
||||||
"puts property propname in the Config's properties attribute"
|
|
||||||
props = self._p_.getproperties(None, default_properties)
|
|
||||||
if propname not in props:
|
|
||||||
props.add(propname)
|
|
||||||
self.setproperties(props, None, None)
|
|
||||||
|
|
||||||
def remove(self, propname):
|
|
||||||
"deletes property propname in the Config's properties attribute"
|
|
||||||
props = self._p_.getproperties(None, default_properties)
|
|
||||||
if propname in props:
|
|
||||||
props.remove(propname)
|
|
||||||
self.setproperties(props, None, None)
|
|
||||||
|
|
||||||
def extend(self, propnames):
|
|
||||||
for propname in propnames:
|
|
||||||
self.append(propname)
|
|
||||||
|
|
||||||
def _setproperties(self, properties, opt, path, force=False):
|
|
||||||
"""just for compatibility
|
|
||||||
"""
|
|
||||||
self.setproperties(properties, opt, path, force)
|
|
||||||
|
|
||||||
def setproperties(self, properties, opt, path, force=False):
|
|
||||||
"""save properties for specified path
|
|
||||||
(never save properties if same has option properties)
|
|
||||||
"""
|
|
||||||
if self._getcontext().cfgimpl_get_meta() is not None:
|
|
||||||
raise ConfigError(_('cannot change global property with metaconfig'))
|
|
||||||
if not force:
|
|
||||||
forbidden_properties = forbidden_set_properties & properties
|
|
||||||
if forbidden_properties:
|
|
||||||
raise ConfigError(_('cannot add those properties: {0}').format(
|
|
||||||
' '.join(forbidden_properties)))
|
|
||||||
self._p_.setproperties(path, properties)
|
|
||||||
#values too because of slave values could have a PropertiesOptionError has value
|
|
||||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path, only=('values', 'properties',))
|
|
||||||
|
|
||||||
def getpermissive(self, setting_properties, path=None):
|
|
||||||
if 'cache' in setting_properties and 'expire' in setting_properties:
|
|
||||||
ntime = int(time())
|
|
||||||
else:
|
|
||||||
ntime = None
|
|
||||||
if 'cache' in setting_properties and self._pp_.hascache(path, None):
|
|
||||||
is_cached, perm = self._pp_.getcache(path, ntime, None)
|
|
||||||
else:
|
|
||||||
is_cached = False
|
|
||||||
if not is_cached:
|
|
||||||
if path is not None:
|
|
||||||
perm = self._pp_.getpermissive(path)
|
|
||||||
else:
|
|
||||||
perm = self._pp_.getpermissive()
|
|
||||||
if 'cache' in setting_properties:
|
|
||||||
if 'expire' in setting_properties:
|
|
||||||
ntime = ntime + expires_time
|
|
||||||
self._pp_.setcache(path, perm, ntime, None)
|
|
||||||
return perm
|
|
||||||
|
|
||||||
#____________________________________________________________
|
|
||||||
def validate_properties(self, opt_or_descr, is_descr, check_frozen, path,
|
|
||||||
value=None, force_permissive=False,
|
|
||||||
setting_properties=undefined,
|
|
||||||
self_properties=undefined,
|
|
||||||
index=None, debug=False):
|
|
||||||
"""
|
|
||||||
validation upon the properties related to `opt_or_descr`
|
|
||||||
|
|
||||||
:param opt_or_descr: an option or an option description object
|
|
||||||
:param force_permissive: behaves as if the permissive property
|
|
||||||
was present
|
|
||||||
:param is_descr: we have to know if we are in an option description,
|
|
||||||
just because the mandatory property
|
|
||||||
doesn't exist here
|
|
||||||
|
|
||||||
:param check_frozen: in the validation process, an option is to be modified,
|
|
||||||
the behavior can be different
|
|
||||||
(typically with the `frozen` property)
|
|
||||||
"""
|
|
||||||
# opt properties
|
|
||||||
if setting_properties is undefined:
|
|
||||||
setting_properties = self._getproperties(read_write=False)
|
|
||||||
if self_properties is not undefined:
|
|
||||||
properties = copy(self_properties)
|
|
||||||
else:
|
|
||||||
properties = self._getproperties(opt_or_descr, path,
|
|
||||||
setting_properties=setting_properties,
|
|
||||||
index=index)
|
|
||||||
# calc properties
|
|
||||||
properties &= setting_properties
|
|
||||||
if not is_descr:
|
|
||||||
#mandatory
|
|
||||||
if 'mandatory' in properties and \
|
|
||||||
not self._getcontext().cfgimpl_get_values()._isempty(
|
|
||||||
opt_or_descr, value, index=index):
|
|
||||||
properties.remove('mandatory')
|
|
||||||
elif 'empty' in properties and \
|
|
||||||
'empty' in setting_properties and \
|
|
||||||
self._getcontext().cfgimpl_get_values()._isempty(
|
|
||||||
opt_or_descr, value, force_allow_empty_list=True, index=index):
|
|
||||||
properties.add('mandatory')
|
|
||||||
# should return 'frozen' only when tried to modify a value
|
|
||||||
if check_frozen and 'everything_frozen' in setting_properties:
|
|
||||||
properties.add('frozen')
|
|
||||||
elif 'frozen' in properties and not check_frozen:
|
|
||||||
properties.remove('frozen')
|
|
||||||
if 'empty' in properties:
|
|
||||||
properties.remove('empty')
|
|
||||||
|
|
||||||
# remove permissive properties
|
|
||||||
if properties != frozenset():
|
|
||||||
# remove opt permissive
|
|
||||||
# permissive affect option's permission with or without permissive
|
|
||||||
# global property
|
|
||||||
properties -= self.getpermissive(setting_properties, path)
|
|
||||||
# remove global permissive if need
|
|
||||||
if force_permissive is True or 'permissive' in setting_properties:
|
|
||||||
properties -= self.getpermissive(setting_properties)
|
|
||||||
|
|
||||||
# at this point an option should not remain in properties
|
|
||||||
if properties != frozenset():
|
|
||||||
props = list(properties)
|
|
||||||
datas = {'opt': opt_or_descr, 'path': path, 'setting_properties': setting_properties,
|
|
||||||
'index': index, 'debug': True}
|
|
||||||
if is_descr:
|
|
||||||
opt_type = 'optiondescription'
|
|
||||||
else:
|
|
||||||
opt_type = 'option'
|
|
||||||
if 'frozen' in properties:
|
|
||||||
raise PropertiesOptionError(_('cannot change the value for '
|
|
||||||
'option "{0}" this option is'
|
|
||||||
' frozen').format(
|
|
||||||
opt_or_descr.impl_getname()),
|
|
||||||
props,
|
|
||||||
self,
|
|
||||||
datas,
|
|
||||||
opt_type)
|
|
||||||
else:
|
|
||||||
if len(props) == 1:
|
|
||||||
prop_msg = _('property')
|
|
||||||
else:
|
|
||||||
prop_msg = _('properties')
|
|
||||||
raise PropertiesOptionError(_('cannot access to {0} "{1}" '
|
|
||||||
'because has {2} {3}'
|
|
||||||
'').format(opt_type,
|
|
||||||
opt_or_descr.impl_get_display_name(),
|
|
||||||
prop_msg,
|
|
||||||
display_list(props)),
|
|
||||||
props,
|
|
||||||
self,
|
|
||||||
datas,
|
|
||||||
opt_type)
|
|
||||||
|
|
||||||
def setpermissive(self, permissive, opt=None, path=None):
|
|
||||||
"""
|
|
||||||
enables us to put the permissives in the storage
|
|
||||||
|
|
||||||
:param path: the option's path
|
|
||||||
:param type: str
|
|
||||||
:param opt: if an option object is set, the path is extracted.
|
|
||||||
it is better (faster) to set the path parameter
|
|
||||||
instead of passing a :class:`tiramisu.option.Option()` object.
|
|
||||||
"""
|
|
||||||
if opt is not None and path is None:
|
|
||||||
path = opt.impl_getpath(self._getcontext())
|
|
||||||
if not isinstance(permissive, tuple): # pragma: optional cover
|
|
||||||
raise TypeError(_('permissive must be a tuple'))
|
|
||||||
self._pp_.setpermissive(path, permissive)
|
|
||||||
setting_properties = self._getproperties(read_write=False)
|
|
||||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path, only=('properties', 'values'))
|
|
||||||
if 'cache' in setting_properties:
|
|
||||||
if 'expire' in setting_properties:
|
|
||||||
ntime = int(time()) + expires_time
|
|
||||||
else:
|
else:
|
||||||
ntime = None
|
ntime = None
|
||||||
self._pp_.setcache(path, set(permissive), ntime, None)
|
if 'cache' in setting_properties and self._p_.hascache(path,
|
||||||
|
index):
|
||||||
|
is_cached, props = self._p_.getcache(path,
|
||||||
|
ntime,
|
||||||
|
index)
|
||||||
|
if not is_cached:
|
||||||
|
props = self._p_.getproperties(path,
|
||||||
|
opt.impl_getproperties())
|
||||||
|
if apply_requires:
|
||||||
|
requires = self.apply_requires(opt,
|
||||||
|
path,
|
||||||
|
setting_properties,
|
||||||
|
index,
|
||||||
|
False)
|
||||||
|
#FIXME devrait etre un frozenset!
|
||||||
|
if requires != set([]):
|
||||||
|
props = copy(props)
|
||||||
|
props |= requires
|
||||||
|
|
||||||
#____________________________________________________________
|
props -= self.getpermissive(path)
|
||||||
def setowner(self, owner):
|
if apply_requires and 'cache' in setting_properties:
|
||||||
":param owner: sets the default value for owner at the Config level"
|
if 'expire' in setting_properties:
|
||||||
if not isinstance(owner, owners.Owner): # pragma: optional cover
|
ntime = ntime + expires_time
|
||||||
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
|
self._p_.setcache(path,
|
||||||
self._owner = owner
|
props,
|
||||||
#FIXME qu'est ce qui se passe si pas de owner ??
|
ntime,
|
||||||
|
index)
|
||||||
|
return props
|
||||||
|
|
||||||
def getowner(self):
|
def get_context_permissive(self):
|
||||||
return self._owner
|
return self.getpermissive(None)
|
||||||
|
|
||||||
#____________________________________________________________
|
def getpermissive(self,
|
||||||
def _read(self, remove, append):
|
path):
|
||||||
props = self._p_.getproperties(None, default_properties)
|
return self._pp_.getpermissive(path)
|
||||||
modified = False
|
|
||||||
if remove & props != set([]):
|
|
||||||
props = props - remove
|
|
||||||
modified = True
|
|
||||||
if append & props != append:
|
|
||||||
props = props | append
|
|
||||||
modified = True
|
|
||||||
if modified:
|
|
||||||
self.setproperties(props, None, None)
|
|
||||||
|
|
||||||
def read_only(self):
|
def apply_requires(self,
|
||||||
"convenience method to freeze, hide and disable"
|
opt,
|
||||||
self._read(ro_remove, ro_append)
|
path,
|
||||||
|
setting_properties,
|
||||||
def read_write(self):
|
index,
|
||||||
"convenience method to freeze, hide and disable"
|
debug):
|
||||||
self._read(rw_remove, rw_append)
|
|
||||||
|
|
||||||
def apply_requires(self, opt, path, setting_properties, index, debug):
|
|
||||||
"""carries out the jit (just in time) requirements between options
|
"""carries out the jit (just in time) requirements between options
|
||||||
|
|
||||||
a requirement is a tuple of this form that comes from the option's
|
a requirement is a tuple of this form that comes from the option's
|
||||||
|
@ -735,16 +413,16 @@ class Settings(object):
|
||||||
idx = None
|
idx = None
|
||||||
try:
|
try:
|
||||||
value = context.getattr(reqpath,
|
value = context.getattr(reqpath,
|
||||||
|
setting_properties,
|
||||||
force_permissive=True,
|
force_permissive=True,
|
||||||
_setting_properties=setting_properties,
|
|
||||||
index=idx)
|
index=idx)
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
if not transitive:
|
if not transitive:
|
||||||
if all_properties is None:
|
if all_properties is None:
|
||||||
all_properties = []
|
all_properties = []
|
||||||
for requires in opt.impl_getrequires():
|
for requires_ in opt.impl_getrequires():
|
||||||
for require in requires:
|
for require_ in requires_:
|
||||||
all_properties.append(require[1])
|
all_properties.append(require_[1])
|
||||||
if not set(err.proptype) - set(all_properties):
|
if not set(err.proptype) - set(all_properties):
|
||||||
continue
|
continue
|
||||||
properties = err.proptype
|
properties = err.proptype
|
||||||
|
@ -794,8 +472,228 @@ class Settings(object):
|
||||||
break
|
break
|
||||||
return calc_properties
|
return calc_properties
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# set methods
|
||||||
|
def set_context_properties(self, properties):
|
||||||
|
self.setproperties(None, None, properties)
|
||||||
|
|
||||||
|
def setproperties(self,
|
||||||
|
opt,
|
||||||
|
path,
|
||||||
|
properties):
|
||||||
|
# force=False):
|
||||||
|
"""save properties for specified path
|
||||||
|
(never save properties if same has option properties)
|
||||||
|
"""
|
||||||
|
if self._getcontext().cfgimpl_get_meta() is not None:
|
||||||
|
raise ConfigError(_('cannot change global property with metaconfig'))
|
||||||
|
#if not force:
|
||||||
|
forbidden_properties = forbidden_set_properties & properties
|
||||||
|
if forbidden_properties:
|
||||||
|
raise ConfigError(_('cannot add those properties: {0}').format(
|
||||||
|
' '.join(forbidden_properties)))
|
||||||
|
if not isinstance(properties, frozenset):
|
||||||
|
raise TypeError(_('properties must be a frozenset'))
|
||||||
|
self._p_.setproperties(path,
|
||||||
|
properties)
|
||||||
|
#values too because of slave values could have a PropertiesOptionError has value
|
||||||
|
self._getcontext().cfgimpl_reset_cache(opt=opt,
|
||||||
|
path=path)
|
||||||
|
|
||||||
|
def set_context_permissive(self, permissive):
|
||||||
|
self.setpermissive(None, None, permissive)
|
||||||
|
|
||||||
|
def setpermissive(self,
|
||||||
|
opt,
|
||||||
|
path,
|
||||||
|
permissives):
|
||||||
|
"""
|
||||||
|
enables us to put the permissives in the storage
|
||||||
|
|
||||||
|
:param path: the option's path
|
||||||
|
:param type: str
|
||||||
|
:param opt: if an option object is set, the path is extracted.
|
||||||
|
it is better (faster) to set the path parameter
|
||||||
|
instead of passing a :class:`tiramisu.option.Option()` object.
|
||||||
|
"""
|
||||||
|
if not isinstance(permissives, frozenset):
|
||||||
|
raise TypeError(_('permissive must be a frozenset'))
|
||||||
|
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=opt,
|
||||||
|
path=path)
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# reset methods
|
||||||
|
|
||||||
|
def reset(self, opt=None, _path=None, all_properties=False):
|
||||||
|
if all_properties and (_path or opt): # pragma: optional cover
|
||||||
|
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())
|
||||||
|
self._p_.delproperties(_path)
|
||||||
|
self._getcontext().cfgimpl_reset_cache(opt=opt,
|
||||||
|
path=_path)
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# validate properties
|
||||||
|
|
||||||
|
def validate_properties(self,
|
||||||
|
opt_or_descr,
|
||||||
|
is_descr,
|
||||||
|
check_frozen,
|
||||||
|
path,
|
||||||
|
value=None,
|
||||||
|
force_permissive=False,
|
||||||
|
setting_properties=undefined,
|
||||||
|
self_properties=undefined,
|
||||||
|
index=None,
|
||||||
|
debug=False):
|
||||||
|
"""
|
||||||
|
validation upon the properties related to `opt_or_descr`
|
||||||
|
|
||||||
|
:param opt_or_descr: an option or an option description object
|
||||||
|
:param force_permissive: behaves as if the permissive property
|
||||||
|
was present
|
||||||
|
:param is_descr: we have to know if we are in an option description,
|
||||||
|
just because the mandatory property
|
||||||
|
doesn't exist here
|
||||||
|
|
||||||
|
:param check_frozen: in the validation process, an option is to be modified,
|
||||||
|
the behavior can be different
|
||||||
|
(typically with the `frozen` property)
|
||||||
|
"""
|
||||||
|
# opt properties
|
||||||
|
if self_properties is not undefined:
|
||||||
|
if not isinstance(self_properties, frozenset):
|
||||||
|
raise Exception('pouet')
|
||||||
|
properties = self_properties
|
||||||
|
else:
|
||||||
|
properties = self.getproperties(opt_or_descr,
|
||||||
|
path,
|
||||||
|
setting_properties=setting_properties,
|
||||||
|
index=index)
|
||||||
|
# calc properties
|
||||||
|
properties &= setting_properties
|
||||||
|
if not is_descr:
|
||||||
|
#mandatory
|
||||||
|
if 'mandatory' in properties and \
|
||||||
|
not self._getcontext().cfgimpl_get_values().isempty(opt_or_descr,
|
||||||
|
value,
|
||||||
|
index=index):
|
||||||
|
properties.remove('mandatory')
|
||||||
|
elif 'empty' in properties and \
|
||||||
|
'empty' in setting_properties and \
|
||||||
|
self._getcontext().cfgimpl_get_values().isempty(opt_or_descr,
|
||||||
|
value,
|
||||||
|
force_allow_empty_list=True,
|
||||||
|
index=index):
|
||||||
|
properties.add('mandatory')
|
||||||
|
# should return 'frozen' only when tried to modify a value
|
||||||
|
if check_frozen and 'everything_frozen' in setting_properties:
|
||||||
|
properties.add('frozen')
|
||||||
|
elif 'frozen' in properties and not check_frozen:
|
||||||
|
properties.remove('frozen')
|
||||||
|
if 'empty' in properties:
|
||||||
|
properties.remove('empty')
|
||||||
|
|
||||||
|
# remove permissive properties
|
||||||
|
if properties != frozenset() and (force_permissive is True or
|
||||||
|
'permissive' in setting_properties):
|
||||||
|
# remove global permissive if need
|
||||||
|
properties -= self.get_context_permissive()
|
||||||
|
|
||||||
|
# at this point an option should not remain in properties
|
||||||
|
if properties != frozenset():
|
||||||
|
props = list(properties)
|
||||||
|
datas = {'opt': opt_or_descr,
|
||||||
|
'path': path,
|
||||||
|
'setting_properties': setting_properties,
|
||||||
|
'index': index,
|
||||||
|
'debug': True}
|
||||||
|
if is_descr:
|
||||||
|
opt_type = 'optiondescription'
|
||||||
|
else:
|
||||||
|
opt_type = 'option'
|
||||||
|
if 'frozen' in properties:
|
||||||
|
raise PropertiesOptionError(_('cannot change the value for '
|
||||||
|
'option "{0}" this option is'
|
||||||
|
' frozen').format(
|
||||||
|
opt_or_descr.impl_getname()),
|
||||||
|
props,
|
||||||
|
self,
|
||||||
|
datas,
|
||||||
|
opt_type)
|
||||||
|
else:
|
||||||
|
if len(props) == 1:
|
||||||
|
prop_msg = _('property')
|
||||||
|
else:
|
||||||
|
prop_msg = _('properties')
|
||||||
|
raise PropertiesOptionError(_('cannot access to {0} "{1}" '
|
||||||
|
'because has {2} {3}'
|
||||||
|
'').format(opt_type,
|
||||||
|
opt_or_descr.impl_get_display_name(),
|
||||||
|
prop_msg,
|
||||||
|
display_list(props)),
|
||||||
|
props,
|
||||||
|
self,
|
||||||
|
datas,
|
||||||
|
opt_type)
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# read only/read write
|
||||||
|
|
||||||
|
def _read(self,
|
||||||
|
remove,
|
||||||
|
append):
|
||||||
|
props = self._p_.getproperties(None,
|
||||||
|
default_properties)
|
||||||
|
modified = False
|
||||||
|
if remove & props != set([]):
|
||||||
|
props = props - remove
|
||||||
|
modified = True
|
||||||
|
if append & props != append:
|
||||||
|
props = props | append
|
||||||
|
modified = True
|
||||||
|
if modified:
|
||||||
|
self.set_context_properties(frozenset(props))
|
||||||
|
|
||||||
|
def read_only(self):
|
||||||
|
"convenience method to freeze, hide and disable"
|
||||||
|
self._read(ro_remove,
|
||||||
|
ro_append)
|
||||||
|
|
||||||
|
def read_write(self):
|
||||||
|
"convenience method to freeze, hide and disable"
|
||||||
|
self._read(rw_remove,
|
||||||
|
rw_append)
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# get modified properties/permissives
|
||||||
|
|
||||||
def get_modified_properties(self):
|
def get_modified_properties(self):
|
||||||
return self._p_.get_modified_properties()
|
return self._p_.get_modified_properties()
|
||||||
|
|
||||||
def get_modified_permissives(self):
|
def get_modified_permissives(self):
|
||||||
return self._pp_.get_modified_permissives()
|
return self._pp_.get_modified_permissives()
|
||||||
|
|
||||||
|
#____________________________________________________________
|
||||||
|
# default owner methods
|
||||||
|
|
||||||
|
def setowner(self,
|
||||||
|
owner):
|
||||||
|
":param owner: sets the default value for owner at the Config level"
|
||||||
|
if not isinstance(owner,
|
||||||
|
owners.Owner): # pragma: optional cover
|
||||||
|
raise TypeError(_("invalid generic owner {0}").format(str(owner)))
|
||||||
|
self._owner = owner
|
||||||
|
|
||||||
|
def getowner(self):
|
||||||
|
return self._owner
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Properties(Cache):
|
||||||
self._properties[path] = properties
|
self._properties[path] = properties
|
||||||
|
|
||||||
def getproperties(self, path, default_properties):
|
def getproperties(self, path, default_properties):
|
||||||
return self._properties.get(path, set(default_properties))
|
return self._properties.get(path, frozenset(default_properties))
|
||||||
|
|
||||||
def reset_all_properties(self):
|
def reset_all_properties(self):
|
||||||
self._properties.clear()
|
self._properties.clear()
|
||||||
|
|
|
@ -195,7 +195,11 @@ class Values(Cache):
|
||||||
return 0
|
return 0
|
||||||
return max(self._values[1][idx]) + 1
|
return max(self._values[1][idx]) + 1
|
||||||
|
|
||||||
def getowner(self, path, default, index=None, only_default=False,
|
def getowner(self,
|
||||||
|
path,
|
||||||
|
default,
|
||||||
|
index=None,
|
||||||
|
only_default=False,
|
||||||
with_value=False):
|
with_value=False):
|
||||||
"""get owner for a path
|
"""get owner for a path
|
||||||
return: owner object
|
return: owner object
|
||||||
|
@ -207,19 +211,28 @@ class Values(Cache):
|
||||||
else:
|
else:
|
||||||
owner = default
|
owner = default
|
||||||
else:
|
else:
|
||||||
owner = self._getvalue(path, 3, index)
|
owner = self._getvalue(path,
|
||||||
|
3,
|
||||||
|
index)
|
||||||
if owner is undefined:
|
if owner is undefined:
|
||||||
owner = default
|
owner = default
|
||||||
else:
|
else:
|
||||||
owner = self._getvalue(path, 3, index)
|
owner = self._getvalue(path,
|
||||||
|
3,
|
||||||
|
index)
|
||||||
if owner is undefined:
|
if owner is undefined:
|
||||||
owner = default
|
owner = default
|
||||||
if with_value:
|
if with_value:
|
||||||
return owner, self._getvalue(path, 2, index)
|
return owner, self._getvalue(path,
|
||||||
|
2,
|
||||||
|
index)
|
||||||
else:
|
else:
|
||||||
return owner
|
return owner
|
||||||
|
|
||||||
def _getvalue(self, path, nb, index):
|
def _getvalue(self,
|
||||||
|
path,
|
||||||
|
nb,
|
||||||
|
index):
|
||||||
"""
|
"""
|
||||||
_values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
|
_values == ((path1, path2), ((idx1_1, idx1_2), None), ((value1_1, value1_2), value2), ((owner1_1, owner1_2), owner2))
|
||||||
"""
|
"""
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue