trimming options's callbacks

This commit is contained in:
gwen 2012-10-15 15:06:41 +02:00
parent 0bd7624eea
commit b3da043190
4 changed files with 63 additions and 41 deletions

View file

@ -70,7 +70,7 @@ def test_has_callback():
descr = make_description() descr = make_description()
# here the owner is 'default' # here the owner is 'default'
config = Config(descr, bool=False) config = Config(descr, bool=False)
# because dummy has a callback # because dummy has a callback
dummy = config.unwrap_from_path('gc.dummy') dummy = config.unwrap_from_path('gc.dummy')
config.cfgimpl_freeze() config.cfgimpl_freeze()
dummy.freeze() dummy.freeze()
@ -85,8 +85,7 @@ def test_freeze_and_has_callback_with_setoption():
dummy.freeze() dummy.freeze()
raises(TypeError, "config.gc.setoption('dummy', True, 'gen_config')") raises(TypeError, "config.gc.setoption('dummy', True, 'gen_config')")
def test_cannot_override(): #def test_cannot_override():
descr = make_description() # descr = make_description()
config = Config(descr, bool=False) # config = Config(descr, bool=False)
raises(TypeError, "config.override({'gc.dummy': True})") # raises(TypeError, "config.override({'gc.dummy': True})")

View file

@ -19,8 +19,7 @@
# the whole pypy projet is under MIT licence # the whole pypy projet is under MIT licence
# ____________________________________________________________ # ____________________________________________________________
"enables us to carry out a calculation and return an option's value" "enables us to carry out a calculation and return an option's value"
from tiramisu.error import (PropertiesOptionError, ConflictConfigError, from tiramisu.error import PropertiesOptionError, ConflictConfigError
NoValueReturned)
# ____________________________________________________________ # ____________________________________________________________
# automatic Option object # automatic Option object
#def special_owner_factory(name, owner, value, #def special_owner_factory(name, owner, value,
@ -28,10 +27,12 @@ from tiramisu.error import (PropertiesOptionError, ConflictConfigError,
# # in case of an 'auto' and a 'fill' without a value, # # in case of an 'auto' and a 'fill' without a value,
# # we have to carry out a calculation # # we have to carry out a calculation
# return calc_factory(name, callback, callback_params, config) # return calc_factory(name, callback, callback_params, config)
def carry_out_calculation(name, callback, callback_params, config): def carry_out_calculation(name, option, config):
# FIXME we have to know the exact status of the config # FIXME we have to know the exact status of the config
# not to disrupt it # not to disrupt it
# config.freeze() # config.freeze()
callback=option.getcallback()
callback_params=option.getcallback_params()
if callback_params is None: if callback_params is None:
callback_params = {} callback_params = {}
tcparams = {} tcparams = {}
@ -44,7 +45,7 @@ def carry_out_calculation(name, callback, callback_params, config):
opt_value = getattr(config, path) opt_value = getattr(config, path)
opt = config.unwrap_from_path(path) opt = config.unwrap_from_path(path)
except PropertiesOptionError, e: except PropertiesOptionError, e:
if chek_disabled: if check_disabled:
continue continue
raise PropertiesOptionError(e) raise PropertiesOptionError(e)
is_multi = opt.is_multi() is_multi = opt.is_multi()
@ -87,6 +88,7 @@ def carry_out_calculation(name, callback, callback_params, config):
params.append(couple[0]) params.append(couple[0])
else: else:
tcp[key] = couple[0] tcp[key] = couple[0]
a=calculate(name, callback, params, tcp)
return calculate(name, callback, params, tcp) return calculate(name, callback, params, tcp)
def calculate(name, callback, params, tcparams): def calculate(name, callback, params, tcparams):
@ -94,8 +96,6 @@ def calculate(name, callback, params, tcparams):
# XXX not only creole... # XXX not only creole...
from creole import eosfunc from creole import eosfunc
return getattr(eosfunc, callback)(*params, **tcparams) return getattr(eosfunc, callback)(*params, **tcparams)
except NoValueReturned, err:
return ""
except AttributeError, err: except AttributeError, err:
import traceback import traceback
traceback.print_exc() traceback.print_exc()

View file

@ -23,10 +23,9 @@
from copy import copy from copy import copy
from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError, from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError,
AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound, AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound,
MandatoryError, MethodCallError) MandatoryError, MethodCallError, NoValueReturned)
from tiramisu.option import (OptionDescription, Option, SymLinkOption, from tiramisu.option import (OptionDescription, Option, SymLinkOption,
group_types, Multi, apply_requires) group_types, Multi, apply_requires)
from tiramisu.autolib import carry_out_calculation
# ______________________________________________________________________ # ______________________________________________________________________
# generic owner. 'default' is the general config owner after init time # generic owner. 'default' is the general config owner after init time
@ -226,36 +225,42 @@ class Config(object):
if opt_or_descr.has_callback(): if opt_or_descr.has_callback():
value = self._cfgimpl_values[name] value = self._cfgimpl_values[name]
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 value != None: not opt_or_descr.is_forced_on_freeze()) and \
not opt_or_descr.getowner(self) == 'default':
if opt_or_descr.is_multi(): if opt_or_descr.is_multi():
if None not in value: if None not in value:
return value return value
else: else:
return value return value
result = carry_out_calculation(name, try:
callback=opt_or_descr.getcallback(), result = opt_or_descr.getcallback_value(
callback_params=opt_or_descr.getcallback_params(), self._cfgimpl_get_toplevel())
config=self._cfgimpl_get_toplevel()) except NoValueReturned, err:
# this result **shall not** be a list pass
# 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 == []:
_result = Multi([result], value.config, value.child)
else:
_result = Multi([], value.config, value.child)
for val in value:
if val == None:
val = result
_result.append(val)
else: else:
_result = result # this result **shall not** be a list
return _result # 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 == []:
_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)
else:
_result = result
self._cfgimpl_values[name] = _result
# mandatory options # mandatory options
homeconfig = self._cfgimpl_get_toplevel() homeconfig = self._cfgimpl_get_toplevel()
@ -335,9 +340,9 @@ class Config(object):
else: else:
newowner = who newowner = who
if type(child) != SymLinkOption: if type(child) != SymLinkOption:
if child.has_callback() and who=='default': #if child.has_callback() and who=='default':
raise TypeError("trying to set a value to an option " # raise TypeError("trying to set a default value to an option "
"wich has a callback: {0}".format(name)) # "which has a callback: {0}".format(name))
child.setoption(self, value, who) child.setoption(self, value, who)
if (value is None and who != 'default' and not child.is_multi()): if (value is None and who != 'default' and not child.is_multi()):
child.setowner(self, 'default') child.setowner(self, 'default')

View file

@ -23,6 +23,8 @@
from tiramisu.basetype import HiddenBaseType, DisabledBaseType from tiramisu.basetype import HiddenBaseType, DisabledBaseType
from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError, from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
RequiresError, RequirementRecursionError, MandatoryError) RequiresError, RequirementRecursionError, MandatoryError)
from tiramisu.autolib import carry_out_calculation
requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')] requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
available_actions = [] available_actions = []
@ -191,6 +193,11 @@ class Option(HiddenBaseType, DisabledBaseType):
else: else:
return True return True
def getcallback_value(self, config):
return carry_out_calculation(self._name,
option=self,
config=config)
def getcallback_params(self): def getcallback_params(self):
"if a callback has been defined, returns his arity" "if a callback has been defined, returns his arity"
return self.callback_params return self.callback_params
@ -213,6 +220,17 @@ class Option(HiddenBaseType, DisabledBaseType):
"config *must* be only the **parent** config (not the toplevel config)" "config *must* be only the **parent** config (not the toplevel config)"
return config._cfgimpl_value_owners[self._name] return config._cfgimpl_value_owners[self._name]
def is_default_owner(self, config):
if self.is_multi():
for owner in self.getowner(config):
if owner != 'default':
return False
return True
else:
if self.getowner(config) == 'default':
return True
return False
def setoption(self, config, value, who): def setoption(self, config, value, who):
"""changes the option's value with the value_owner's who """changes the option's value with the value_owner's who
:param config: the parent config is necessary here to store the value :param config: the parent config is necessary here to store the value