From b3da04319014580cef81fc3dfd8ca7178c4405fc Mon Sep 17 00:00:00 2001 From: gwen Date: Mon, 15 Oct 2012 15:06:41 +0200 Subject: [PATCH] trimming options's callbacks --- test/test_option_owner.py | 11 ++++--- tiramisu/autolib.py | 12 ++++---- tiramisu/config.py | 63 +++++++++++++++++++++------------------ tiramisu/option.py | 18 +++++++++++ 4 files changed, 63 insertions(+), 41 deletions(-) diff --git a/test/test_option_owner.py b/test/test_option_owner.py index 247bc21..c71fbb7 100644 --- a/test/test_option_owner.py +++ b/test/test_option_owner.py @@ -70,7 +70,7 @@ def test_has_callback(): descr = make_description() # here the owner is 'default' config = Config(descr, bool=False) - # because dummy has a callback + # because dummy has a callback dummy = config.unwrap_from_path('gc.dummy') config.cfgimpl_freeze() dummy.freeze() @@ -85,8 +85,7 @@ def test_freeze_and_has_callback_with_setoption(): dummy.freeze() raises(TypeError, "config.gc.setoption('dummy', True, 'gen_config')") -def test_cannot_override(): - descr = make_description() - config = Config(descr, bool=False) - raises(TypeError, "config.override({'gc.dummy': True})") - +#def test_cannot_override(): +# descr = make_description() +# config = Config(descr, bool=False) +# raises(TypeError, "config.override({'gc.dummy': True})") diff --git a/tiramisu/autolib.py b/tiramisu/autolib.py index 0002f5c..42fcf7f 100644 --- a/tiramisu/autolib.py +++ b/tiramisu/autolib.py @@ -19,8 +19,7 @@ # the whole pypy projet is under MIT licence # ____________________________________________________________ "enables us to carry out a calculation and return an option's value" -from tiramisu.error import (PropertiesOptionError, ConflictConfigError, - NoValueReturned) +from tiramisu.error import PropertiesOptionError, ConflictConfigError # ____________________________________________________________ # automatic Option object #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, # # we have to carry out a calculation # 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 # not to disrupt it # config.freeze() + callback=option.getcallback() + callback_params=option.getcallback_params() if callback_params is None: callback_params = {} tcparams = {} @@ -44,7 +45,7 @@ def carry_out_calculation(name, callback, callback_params, config): opt_value = getattr(config, path) opt = config.unwrap_from_path(path) except PropertiesOptionError, e: - if chek_disabled: + if check_disabled: continue raise PropertiesOptionError(e) is_multi = opt.is_multi() @@ -87,6 +88,7 @@ def carry_out_calculation(name, callback, callback_params, config): params.append(couple[0]) else: tcp[key] = couple[0] + a=calculate(name, callback, params, tcp) return calculate(name, callback, params, tcp) def calculate(name, callback, params, tcparams): @@ -94,8 +96,6 @@ def calculate(name, callback, params, tcparams): # XXX not only creole... from creole import eosfunc return getattr(eosfunc, callback)(*params, **tcparams) - except NoValueReturned, err: - return "" except AttributeError, err: import traceback traceback.print_exc() diff --git a/tiramisu/config.py b/tiramisu/config.py index dee5ca1..bd0b553 100644 --- a/tiramisu/config.py +++ b/tiramisu/config.py @@ -23,10 +23,9 @@ from copy import copy from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError, AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound, - MandatoryError, MethodCallError) + MandatoryError, MethodCallError, NoValueReturned) from tiramisu.option import (OptionDescription, Option, SymLinkOption, group_types, Multi, apply_requires) -from tiramisu.autolib import carry_out_calculation # ______________________________________________________________________ # generic owner. 'default' is the general config owner after init time @@ -226,36 +225,42 @@ class Config(object): if opt_or_descr.has_callback(): value = self._cfgimpl_values[name] 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 None not in value: return value else: return value - result = carry_out_calculation(name, - callback=opt_or_descr.getcallback(), - callback_params=opt_or_descr.getcallback_params(), - config=self._cfgimpl_get_toplevel()) - # 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 == []: - _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) + try: + result = opt_or_descr.getcallback_value( + self._cfgimpl_get_toplevel()) + except NoValueReturned, err: + pass else: - _result = result - return _result + # 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 == []: + _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 homeconfig = self._cfgimpl_get_toplevel() @@ -335,9 +340,9 @@ class Config(object): else: newowner = who if type(child) != SymLinkOption: - if child.has_callback() and who=='default': - raise TypeError("trying to set a value to an option " - "wich has a callback: {0}".format(name)) + #if child.has_callback() and who=='default': + # raise TypeError("trying to set a default value to an option " + # "which has a callback: {0}".format(name)) child.setoption(self, value, who) if (value is None and who != 'default' and not child.is_multi()): child.setowner(self, 'default') diff --git a/tiramisu/option.py b/tiramisu/option.py index e6d78fb..ed1cbfb 100644 --- a/tiramisu/option.py +++ b/tiramisu/option.py @@ -23,6 +23,8 @@ from tiramisu.basetype import HiddenBaseType, DisabledBaseType from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError, RequiresError, RequirementRecursionError, MandatoryError) +from tiramisu.autolib import carry_out_calculation + requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')] available_actions = [] @@ -191,6 +193,11 @@ class Option(HiddenBaseType, DisabledBaseType): else: return True + def getcallback_value(self, config): + return carry_out_calculation(self._name, + option=self, + config=config) + def getcallback_params(self): "if a callback has been defined, returns his arity" return self.callback_params @@ -213,6 +220,17 @@ 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): + 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): """changes the option's value with the value_owner's who :param config: the parent config is necessary here to store the value