validation of the len of the multi in a group
This commit is contained in:
parent
d633574cc5
commit
4393da13ab
|
@ -85,7 +85,12 @@ def carry_out_calculation(name, option, config):
|
||||||
params.append(value)
|
params.append(value)
|
||||||
else:
|
else:
|
||||||
tcp[key] = value
|
tcp[key] = value
|
||||||
ret.append(calculate(name, callback, params, tcp))
|
calc = calculate(name, callback, params, tcp)
|
||||||
|
if isinstance(calc, list):
|
||||||
|
ret.extend(calc)
|
||||||
|
else:
|
||||||
|
ret.append(calc)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
else:
|
else:
|
||||||
tcp = {}
|
tcp = {}
|
||||||
|
|
|
@ -25,8 +25,8 @@ from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError,
|
||||||
AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound,
|
AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound,
|
||||||
MandatoryError, MethodCallError, NoValueReturned)
|
MandatoryError, MethodCallError, NoValueReturned)
|
||||||
from tiramisu.option import (OptionDescription, Option, SymLinkOption,
|
from tiramisu.option import (OptionDescription, Option, SymLinkOption,
|
||||||
group_types, Multi, apply_requires)
|
Multi, apply_requires)
|
||||||
from tiramisu.setting import settings
|
from tiramisu.setting import settings, group_types
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
class Config(object):
|
class Config(object):
|
||||||
|
@ -159,6 +159,52 @@ class Config(object):
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return self._getattr(name)
|
return self._getattr(name)
|
||||||
|
|
||||||
|
def _get_master_len(self, slave_name):
|
||||||
|
try:
|
||||||
|
parent_cfg = self._cfgimpl_parent
|
||||||
|
if parent_cfg is None:
|
||||||
|
return None
|
||||||
|
master_name = parent_cfg._cfgimpl_descr.get_master_name()
|
||||||
|
master_value = getattr(parent_cfg, master_name)
|
||||||
|
return len(master_value)
|
||||||
|
except TypeError:
|
||||||
|
# in this case we just don't care about the len
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _valid_len(self, slave_name, slave_value):
|
||||||
|
master_len = self._get_master_len(slave_name)
|
||||||
|
if master_len == None:
|
||||||
|
return True
|
||||||
|
if master_len != len(slave_value):
|
||||||
|
raise ValueError("invalid len for the group {0}"
|
||||||
|
"in the option {1} ".format(master_name, slave_name))
|
||||||
|
|
||||||
|
def fill_multi(self, name, result, default_multi=None):
|
||||||
|
"""fills a multi option with default and calculated values
|
||||||
|
"""
|
||||||
|
value = self._cfgimpl_values[name]
|
||||||
|
master_len = self._get_master_len(name)
|
||||||
|
if not isinstance(result, list):
|
||||||
|
if master_len is None:
|
||||||
|
master_len = 1
|
||||||
|
# a list is built with the same len as the master
|
||||||
|
_result = []
|
||||||
|
for i in range(master_len):
|
||||||
|
_result.append(result)
|
||||||
|
elif default_multi != None:
|
||||||
|
if master_len != None:
|
||||||
|
slave_len = len(result)
|
||||||
|
if slave_len > master_len:
|
||||||
|
raise ValueError("invalid value's len for"
|
||||||
|
"the option: {1}".format(name))
|
||||||
|
if slave_len != master_len:
|
||||||
|
delta_len = master_len - len(result)
|
||||||
|
for i in range(delta_len):
|
||||||
|
_result.append(default_multi)
|
||||||
|
else:
|
||||||
|
_result = result
|
||||||
|
return Multi(_result, value.config, value.child)
|
||||||
|
|
||||||
def _getattr(self, name, permissive=False):
|
def _getattr(self, name, permissive=False):
|
||||||
"""
|
"""
|
||||||
attribute notation mechanism for accessing the value of an option
|
attribute notation mechanism for accessing the value of an option
|
||||||
|
@ -195,6 +241,7 @@ class Config(object):
|
||||||
if (not opt_or_descr.is_frozen() or \
|
if (not opt_or_descr.is_frozen() or \
|
||||||
not opt_or_descr.is_forced_on_freeze()) and \
|
not opt_or_descr.is_forced_on_freeze()) and \
|
||||||
not opt_or_descr.is_default_owner(self):
|
not opt_or_descr.is_default_owner(self):
|
||||||
|
self._valid_len(name, value)
|
||||||
return value
|
return value
|
||||||
try:
|
try:
|
||||||
result = opt_or_descr.getcallback_value(
|
result = opt_or_descr.getcallback_value(
|
||||||
|
@ -203,9 +250,7 @@ class Config(object):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if opt_or_descr.is_multi():
|
if opt_or_descr.is_multi():
|
||||||
if not isinstance(result, list):
|
_result = self.fill_multi(name, result)
|
||||||
result = [result]
|
|
||||||
_result = Multi(result, value.config, value.child)
|
|
||||||
else:
|
else:
|
||||||
# this result **shall not** be a list
|
# this result **shall not** be a list
|
||||||
if isinstance(result, list):
|
if isinstance(result, list):
|
||||||
|
@ -218,11 +263,17 @@ class Config(object):
|
||||||
' for option {0}'.format(name))
|
' for option {0}'.format(name))
|
||||||
self._cfgimpl_values[name] = _result
|
self._cfgimpl_values[name] = _result
|
||||||
opt_or_descr.setowner(self, 'default')
|
opt_or_descr.setowner(self, 'default')
|
||||||
if not opt_or_descr.has_callback() and opt_or_descr.is_forced_on_freeze():
|
|
||||||
return opt_or_descr.getdefault()
|
|
||||||
self._test_mandatory(name, opt_or_descr)
|
|
||||||
# frozen and force default
|
# frozen and force default
|
||||||
return self._cfgimpl_values[name]
|
if not opt_or_descr.has_callback() and opt_or_descr.is_forced_on_freeze():
|
||||||
|
value = opt_or_descr.getdefault()
|
||||||
|
if opt_or_descr.is_multi():
|
||||||
|
value = self.fill_multi(name, result, opt_or_descr.getdefault_multi())
|
||||||
|
self._cfgimpl_values[name] = value
|
||||||
|
opt_or_descr.setowner(self, 'default')
|
||||||
|
self._test_mandatory(name, opt_or_descr)
|
||||||
|
value = self._cfgimpl_values[name]
|
||||||
|
self._valid_len(name, value)
|
||||||
|
return value
|
||||||
|
|
||||||
def unwrap_from_name(self, name):
|
def unwrap_from_name(self, name):
|
||||||
"""convenience method to extract and Option() object from the Config()
|
"""convenience method to extract and Option() object from the Config()
|
||||||
|
@ -375,10 +426,8 @@ class Config(object):
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"Config comparison"
|
"Config comparison"
|
||||||
if not isinstance(other, Config):
|
if not isinstance(other, OptionDescription):
|
||||||
return False
|
return False
|
||||||
print self.getkey()
|
|
||||||
print other.getkey()
|
|
||||||
return self.getkey() == other.getkey()
|
return self.getkey() == other.getkey()
|
||||||
|
|
||||||
def __ne__(self, other):
|
def __ne__(self, other):
|
||||||
|
|
|
@ -26,7 +26,7 @@ from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
|
||||||
RequiresError, RequirementRecursionError, MandatoryError,
|
RequiresError, RequirementRecursionError, MandatoryError,
|
||||||
PropertiesOptionError)
|
PropertiesOptionError)
|
||||||
from tiramisu.autolib import carry_out_calculation
|
from tiramisu.autolib import carry_out_calculation
|
||||||
from tiramisu.setting import settings
|
from tiramisu.setting import settings, group_types, groups_has_master
|
||||||
|
|
||||||
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
|
||||||
|
|
||||||
|
@ -37,15 +37,6 @@ for act1, act2 in requires_actions:
|
||||||
reverse_actions[act1] = act2
|
reverse_actions[act1] = act2
|
||||||
reverse_actions[act2] = act1
|
reverse_actions[act2] = act1
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# OptionDescription authorized group_type values
|
|
||||||
"""
|
|
||||||
Three available group_types : `default`, `family`, `group` and
|
|
||||||
`master` (for master~slave group type). Notice that for a
|
|
||||||
master~slave group, the name of the group and the name of the
|
|
||||||
master option are identical.
|
|
||||||
"""
|
|
||||||
group_types = ['default', 'family', 'group', 'master']
|
|
||||||
# ____________________________________________________________
|
|
||||||
# multi types
|
# multi types
|
||||||
|
|
||||||
class Multi(list):
|
class Multi(list):
|
||||||
|
@ -416,6 +407,9 @@ class OptionDescription(HiddenBaseType, DisabledBaseType):
|
||||||
self._requires = requires
|
self._requires = requires
|
||||||
self._build()
|
self._build()
|
||||||
self.properties = [] # 'hidden', 'disabled'...
|
self.properties = [] # 'hidden', 'disabled'...
|
||||||
|
# if this group is a master group, master is set
|
||||||
|
# to the master option name
|
||||||
|
self.master = None
|
||||||
|
|
||||||
def getdoc(self):
|
def getdoc(self):
|
||||||
return self.doc
|
return self.doc
|
||||||
|
@ -466,16 +460,33 @@ class OptionDescription(HiddenBaseType, DisabledBaseType):
|
||||||
paths.append('.'.join(currpath + [attr]))
|
paths.append('.'.join(currpath + [attr]))
|
||||||
return paths
|
return paths
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
def set_group_type(self, group_type):
|
def set_group_type(self, group_type, master=None):
|
||||||
":param group_type: string in group_types"
|
":param group_type: string in group_types"
|
||||||
if group_type in group_types:
|
if group_type in group_types:
|
||||||
self.group_type = group_type
|
self.group_type = group_type
|
||||||
|
if group_type in groups_has_master:
|
||||||
|
if master is None:
|
||||||
|
raise ConfigError('this group type ({0}) needs a master '
|
||||||
|
'for OptionDescription {1}'.format(group_type,
|
||||||
|
self._name))
|
||||||
|
else:
|
||||||
|
if master is not None:
|
||||||
|
raise ConfigError("this group type ({0}) doesn't need a "
|
||||||
|
"master for OptionDescription {1}".format(
|
||||||
|
group_type, self._name))
|
||||||
|
self.master = master
|
||||||
else:
|
else:
|
||||||
raise ConfigError('not allowed value for group_type : {0}'.format(
|
raise ConfigError('not allowed value for group_type : {0}'.format(
|
||||||
group_type))
|
group_type))
|
||||||
|
|
||||||
def get_group_type(self):
|
def get_group_type(self):
|
||||||
return self.group_type
|
return self.group_type
|
||||||
|
|
||||||
|
def get_master_name(self):
|
||||||
|
if self.master is None:
|
||||||
|
raise TypeError('get_master_name() shall not be called in case of'
|
||||||
|
'non-master OptionDescription')
|
||||||
|
return self.master
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
"actions API"
|
"actions API"
|
||||||
def hide(self):
|
def hide(self):
|
||||||
|
|
|
@ -21,6 +21,12 @@
|
||||||
# the whole pypy projet is under MIT licence
|
# the whole pypy projet is under MIT licence
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
|
|
||||||
|
# available group_type values
|
||||||
|
_group_name = ('default', 'family', 'group')
|
||||||
|
groups_has_master = ('group', )
|
||||||
|
class Group(str): pass
|
||||||
|
group_types = tuple(Group(i) for i in _group_name)
|
||||||
|
|
||||||
class Setting():
|
class Setting():
|
||||||
"``Config()``'s configuration options"
|
"``Config()``'s configuration options"
|
||||||
# properties attribute: the name of a property enables this property
|
# properties attribute: the name of a property enables this property
|
||||||
|
|
Loading…
Reference in New Issue