multi options

This commit is contained in:
gwen 2012-10-17 11:14:17 +02:00
parent a36ae7df85
commit ec2a65bd37
3 changed files with 103 additions and 64 deletions

View File

@ -38,58 +38,65 @@ def carry_out_calculation(name, option, config):
tcparams = {}
one_is_multi = False
len_multi = 0
for key, value in callback_params.items():
if type(value) == tuple:
path, check_disabled = value
try:
#opt_value = getattr(config, path)
opt_value = config._getattr(path, permissive=True)
opt = config.unwrap_from_path(path)
except PropertiesOptionError, err:
if check_disabled:
continue
raise PropertiesOptionError(err, err.proptype)
is_multi = opt.is_multi()
if is_multi:
if opt_value != None:
len_value = len(opt_value)
if len_multi != 0 and len_multi != len_value:
raise ConflictConfigError('unable to carry out a calculation, '
'option values with multi types must have same length for: '
+ name)
len_multi = len_value
one_is_multi = True
tcparams[key] = (opt_value, is_multi)
else:
tcparams[key] = (value, False)
for key, values in callback_params.items():
for value in values:
if type(value) == tuple:
path, check_disabled = value
try:
opt_value = config._getattr(path, permissive=True)
opt = config.unwrap_from_path(path)
except PropertiesOptionError, err:
if check_disabled:
continue
raise PropertiesOptionError(err, err.proptype)
is_multi = opt.is_multi()
if is_multi:
if opt_value != None:
len_value = len(opt_value)
if len_multi != 0 and len_multi != len_value:
raise ConflictConfigError('unable to carry out a calculation, '
'option values with multi types must have same length for: '
+ name)
len_multi = len_value
one_is_multi = True
tcparams.setdefault(key, []).append((opt_value, is_multi))
else:
tcparams.setdefault(key, []).append((value, False))
if one_is_multi:
ret = []
for incr in range(len_multi):
tcp = {}
for key, couple in tcparams.items():
value, ismulti = couple
if ismulti and value != None:
if key == '':
params.append(value[incr])
params = []
for key, couples in tcparams.items():
for couple in couples:
value, ismulti = couple
if ismulti and value != None:
if key == '':
params.append(value[incr])
else:
if len(value) > incr:
tcp[key] = value[incr]
else:
tcp[key] = ''
else:
tcp[key] = value[incr]
else:
if key == '':
params.append(value)
else:
tcp[key] = value
ret.append(calculate(name, callback, tcp))
if key == '':
params.append(value)
else:
tcp[key] = value
ret.append(calculate(name, callback, params, tcp))
return ret
else:
tcp = {}
params = []
for key, couple in tcparams.items():
if key == '':
params.append(couple[0])
else:
tcp[key] = couple[0]
a=calculate(name, callback, params, tcp)
for key, couples in tcparams.items():
for couple in couples:
if key == '':
value = couple[0]
params.append(value)
else:
tcp[key] = couple[0]
return calculate(name, callback, params, tcp)
def calculate(name, callback, params, tcparams):

View File

@ -239,7 +239,8 @@ class Config(object):
value = self._cfgimpl_values[name]
if (not opt_or_descr.is_frozen() or \
not opt_or_descr.is_forced_on_freeze()) and \
not opt_or_descr.getowner(self) == 'default':
not opt_or_descr.is_default_owner(self, all_default=False):
#not opt_or_descr.getowner(self) == 'default':
if opt_or_descr.is_multi():
if None not in value:
return value
@ -251,28 +252,52 @@ class Config(object):
except NoValueReturned, err:
pass
else:
# this result **shall not** be a list
# for example, [1, 2, 3, None] -> [1, 2, 3, result]
if isinstance(result, list):
raise ConfigError('invalid calculated value returned'
' for option {0} : shall not be a list'.format(name))
if result != None and not opt_or_descr._validate(result):
raise ConfigError('invalid calculated value returned'
' for option {0}'.format(name))
if opt_or_descr.is_multi():
if value == []:
owners = copy(self._cfgimpl_value_owners[name])
self._cfgimpl_value_owners[name] = []
if not isinstance(result, list):
# for example, [1, 2, 3, None] -> [1, 2, 3, result]
_result = Multi([result], value.config, value.child)
else:
_result = Multi([], value.config, value.child)
#for val in value:
owners = opt_or_descr.getowner(self)
for cpt in range(len(value)):
val = value[cpt]
if owners[cpt] == 'default':
val = result
_result.append(val)
if len(owners) > cpt:
if owners[cpt] == 'default':
_result.append(result)
self._cfgimpl_value_owners[name][cpt] = 'default'
else:
_result.append(val)
else:
_result.append(val)
self._cfgimpl_value_owners[name][cpt] = 'default'
else:
# for example, [1, None, 2, None] + [a, b, c, d]
# = [1, b, 2, d]
_result = Multi([], value.config, value.child)
for cpt in range(max(len(value), len(result))):
if len(value) > cpt:
val = value[cpt]
else:
val = ''
if len(result) > cpt:
rval = result[cpt]
if len(owners) > cpt:
if owners[cpt] == 'default':
_result.append(rval)
self._cfgimpl_value_owners[name][cpt] = 'default'
else:
_result.append(val)
else:
_result.append(rval)
self._cfgimpl_value_owners[name][cpt] = 'default'
else:
# this result **shall not** be a list
if isinstance(result, list):
raise ConfigError('invalid calculated value returned'
' for option {0} : shall not be a list'.format(name))
_result = result
if _result != None and not opt_or_descr.validate(_result):
raise ConfigError('invalid calculated value returned'
' for option {0}'.format(name))
self._cfgimpl_values[name] = _result
# mandatory options
@ -286,6 +311,7 @@ class Config(object):
# frozen and force default
if not opt_or_descr.has_callback() and opt_or_descr.is_forced_on_freeze():
return opt_or_descr.getdefault()
return self._cfgimpl_values[name]
def unwrap_from_name(self, name):

View File

@ -59,7 +59,7 @@ class Multi(list):
self.setoption(value)
def setoption(self, value, key=None):
owners = self.child.getowner(self.config)
#owners = self.child.getowner(self.config)
# None is replaced by default_multi
if value == None:
defval = self.child.getdefault()
@ -220,12 +220,18 @@ class Option(HiddenBaseType, DisabledBaseType):
"config *must* be only the **parent** config (not the toplevel config)"
return config._cfgimpl_value_owners[self._name]
def is_default_owner(self, config):
def is_default_owner(self, config, all_default=True):
if self.is_multi():
for owner in self.getowner(config):
if owner != 'default':
owners = self.getowner(config)
for owner in owners:
if all_default and owner != 'default':
return False
return True
if not all_default and owner == 'default':
return True
if all_default or owners == []:
return True
else:
return False
else:
if self.getowner(config) == 'default':
return True