replace special_owner with hascallback_and_freeze
authorgwen <gremond@cadoles.com>
Tue, 14 Aug 2012 08:55:08 +0000 (10:55 +0200)
committergwen <gremond@cadoles.com>
Tue, 14 Aug 2012 08:55:08 +0000 (10:55 +0200)
test/test_option_owner.py
test/test_option_type.py
tiramisu/autolib.py
tiramisu/config.py
tiramisu/error.py
tiramisu/option.py

index 70fb845..ac40dfd 100644 (file)
@@ -3,7 +3,6 @@ import autopath
 from py.test import raises
 from tiramisu.config import *
 from tiramisu.option import *
-from tiramisu.error import SpecialOwnersError
 
 def make_description():
     gcoption = ChoiceOption('name', 'GC name', ['ref', 'framework'], 'ref')
@@ -67,65 +66,20 @@ def test_override_are_default_owner():
     config.gc.dummy = False
     assert config.gc._cfgimpl_value_owners['dummy'] == 'user'
 
-def test_change_owner():
+def test_has_callback():
     descr = make_description()
     # here the owner is 'default'
     config = Config(descr, bool=False)
-    # the default owner is 'user' (which is not 'default')
-    # Still not getting it ? read the docs
-    config.gc.dummy = True
-    assert config.gc._cfgimpl_value_owners['dummy'] == 'user'
-#    config.cfgimpl_set_owner('eggs')
-#    config.set(dummy=False)
-#    assert config.gc._cfgimpl_value_owners['dummy'] == 'eggs'
-#    config.cfgimpl_set_owner('spam')
-#    gcdummy = config.unwrap_from_path('gc.dummy')
-#    gcdummy.setowner(config.gc, 'blabla')
-#    assert config.gc._cfgimpl_value_owners['dummy'] == 'blabla'
-#    config.gc.dummy = True
-#    assert config.gc._cfgimpl_value_owners['dummy'] == 'spam'
-
+    # because dummy has a callback 
+    raises(ConflictConfigError, "config.gc.dummy = True")
 #____________________________________________________________
-# special owners
-def test_auto_owner():
+def test_has_callback_with_setoption():
     descr = make_description()
     config = Config(descr, bool=False)
-    config.gc.setoption('dummy', True, 'auto')
-    raises(PropertiesOptionError, "config.gc.dummy")
-    raises(ConflictConfigError, "config.gc.setoption('dummy', False, 'auto')")
-    # shall return an auto value...
-    #assert config.gc.dummy == 'auto_dummy_value'
+    raises(ConflictConfigError, "config.gc.setoption('dummy', True, 'gen_config')")
 
 def test_cannot_override_special_owners():
     descr = make_description()
     config = Config(descr, bool=False)
-    config.gc.setoption('dummy', True, 'auto')
-    raises(SpecialOwnersError, "config.override({'gc.dummy': True})")
-
-# FIXME have to test the fills anyway
-#def test_fill_owner():    
-#    "fill option"
-#    descr = make_description()
-#    config = Config(descr, bool=False)
-#    assert config.bool == False
-#    assert config.gc.dummy == False
-#    # 'fill' special values
-#    config.gc.setoption('dummy', True, 'fill')
-#    assert config.gc.dummy == False
-
-#def test_auto_fill_and_override():    
-#    descr = make_description()
-#    config = Config(descr, bool=False)
-#    booloption = config.unwrap_from_path('bool')
-#    booloption.callback = 'identical'
-#    booloption.setowner(config, 'auto')
-#    assert config.bool == 'identicalbool'
-#    gcdummy = config.unwrap_from_path('gc.dummy')
-#    gcdummy.callback = 'identical'
-#    gcdummy.setowner(config.gc, 'fill')
-#    raises(SpecialOwnersError, "config.override({'gc.dummy':True})")
-#    config.gc.setoption('dummy', False, 'fill')
-#    # value is returned
-#    assert config.gc.dummy == False
-
+    raises(ConflictConfigError, "config.override({'gc.dummy': True})")
 
index 3cd61c6..044451a 100644 (file)
@@ -67,7 +67,7 @@ def test_freeze_one_option():
     #freeze only one option
     conf.gc._cfgimpl_descr.dummy.freeze()
     assert conf.gc.dummy == False
-    raises(TypeError, "conf.gc.dummy = True")
+    raises(ConflictConfigError, "conf.gc.dummy = True")
 
 def test_frozen_value():
     "setattr a frozen value at the config level"
index d6c57a8..7c715fd 100644 (file)
 # 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, SpecialOwnersError
+from tiramisu.error import PropertiesOptionError, ConflictConfigError
 # ____________________________________________________________
 # automatic Option object
-special_owners = ['auto', 'fill']
-                  
-def special_owner_factory(name, owner, value, 
-                          callback, callback_params=None, config=None):
-    # 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 calc_factory(name, callback, callback_params, config):
+#def special_owner_factory(name, owner, value, 
+#                          callback, callback_params=None, config=None):
+#    # 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):
     # FIXME we have to know the exact status of the config 
     # not to disrupt it
     # config.freeze()
@@ -54,7 +51,7 @@ def calc_factory(name, callback, callback_params, config):
                 if opt_value != None:
                     len_value = len(opt_value)
                     if len_multi != 0 and len_multi != len_value:
-                        raise SpecialOwnersError('unable to carry out a calculation, '
+                        raise ConflictConfigError('unable to carry out a calculation, '
                         'option values with multi types must have same length for: '
                          + name)
                     len_multi = len_value
@@ -89,6 +86,6 @@ def calculate(name, callback, tcparams):
     except AttributeError, err:
         import traceback
         traceback.print_exc()
-        raise SpecialOwnersError("callback: {0} return error {1} for "
+        raise ConflictConfigError("callback: {0} return error {1} for "
                        "option: {2}".format(callback, str(err), name))
 
index c4f9024..dd7c2a2 100644 (file)
 from copy import copy
 from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError, 
     AmbigousOptionError, ConflictConfigError, NoMatchingOptionFound, 
-    SpecialOwnersError, MandatoryError, MethodCallError)
+    MandatoryError, MethodCallError)
 from tiramisu.option import (OptionDescription, Option, SymLinkOption, 
     group_types, Multi, apply_requires)
-from tiramisu.autolib import special_owners, special_owner_factory
+from tiramisu.autolib import carry_out_calculation
 # ______________________________________________________________________
 # generic owner. 'default' is the general config owner after init time
 default_owner = 'user'
@@ -70,21 +70,13 @@ class Config(object):
                                      child=child)
                     self._cfgimpl_values[child._name] = childdef
                     self._cfgimpl_previous_values[child._name] = list(childdef)
+                    self._cfgimpl_value_owners[child._name] = ['default' \
+                        for i in range(len(child.getdefault() ))]
                 else:
                     childdef = child.getdefault()
                     self._cfgimpl_values[child._name] = childdef
                     self._cfgimpl_previous_values[child._name] = childdef 
-                if child.getcallback() is not None:
-                    if child._is_hidden():
-                        self._cfgimpl_value_owners[child._name] = 'auto'
-                    else:
-                        self._cfgimpl_value_owners[child._name] = 'fill'
-                else:
-                    if child.is_multi():
-                        self._cfgimpl_value_owners[child._name] = ['default' \
-                            for i in range(len(child.getdefault() ))]
-                    else:
-                        self._cfgimpl_value_owners[child._name] = 'default'
+                    self._cfgimpl_value_owners[child._name] = 'default'
             elif isinstance(child, OptionDescription):
                 self._validate_duplicates(child._children)
                 self._cfgimpl_values[child._name] = Config(child, parent=self)
@@ -113,10 +105,6 @@ class Config(object):
     def override(self, overrides):
         for name, value in overrides.iteritems():
             homeconfig, name = self._cfgimpl_get_home_by_path(name)
-            #  if there are special_owners, impossible to override
-            if homeconfig._cfgimpl_value_owners[name] in special_owners:
-                raise SpecialOwnersError("cannot override option: {0} because "
-                                            "of its special owner".format(name))
             homeconfig.setoption(name, value, 'default')
 
     def cfgimpl_set_owner(self, owner):
@@ -209,19 +197,17 @@ class Config(object):
         if name not in self._cfgimpl_values:
             raise AttributeError("%s object has no attribute %s" %
                                  (self.__class__, name))
-        if name in self._cfgimpl_value_owners:
-            owner = self._cfgimpl_value_owners[name]
-            if owner in special_owners:
+        if not isinstance(opt_or_descr, OptionDescription):
+            # options with callbacks (fill or auto) 
+            if opt_or_descr.has_callback():
                 value = self._cfgimpl_values[name]
                 if value != None:
                     if opt_or_descr.is_multi():
-                        if owner == 'fill' and None not in value:
+                        if None not in value:
                             return value
                     else:
-                        if owner == 'fill' and value != None:
-                            return value
-                result = special_owner_factory(name, owner, 
-                            value=value,
+                        return value
+                result = carry_out_calculation(name, 
                             callback=opt_or_descr.getcallback(),
                             callback_params=opt_or_descr.getcallback_params(),
                             config=self._cfgimpl_get_toplevel())
@@ -245,7 +231,7 @@ class Config(object):
                 else:
                     _result = result
                 return _result
-        if not isinstance(opt_or_descr, OptionDescription):
+
             # mandatory options
             homeconfig = self._cfgimpl_get_toplevel()
             mandatory = homeconfig._cfgimpl_mandatory
@@ -318,23 +304,19 @@ class Config(object):
                 else:
                     newowner = who 
         if type(child) != SymLinkOption:
+            if child.is_mandatory() and value is None:
+                raise MandatoryError('cannot override value to %s for '
+                  'option %s' % (value, name))
             if name not in self._cfgimpl_values:
                 raise AttributeError('unknown option %s' % (name,))
-            # special owners, a value with a owner *auto* cannot be changed
-            oldowner = self._cfgimpl_value_owners[child._name]
-            if oldowner == 'auto':
-                if who == 'auto':
-                    raise ConflictConfigError('cannot override value to %s for '
-                                          'option %s' % (value, name))
-            if oldowner == who:
-                oldvalue = getattr(self, name)
-                if oldvalue == value: #or who in ("default",):
-                    return
+            if child.has_callback() or child.isfrozen():
+                raise ConflictConfigError('cannot override value to %s for '
+                  'option %s' % (value, name))
+#            if oldowner == who:
+#                oldvalue = getattr(self, name)
+#                if oldvalue == value: 
+#                    return
             child.setoption(self, value, who)
-            # if the value owner is 'auto', set the option to hidden 
-            if who == 'auto':
-                if not child._is_hidden():
-                    child.hide()
             if (value is None and who != 'default' and not child.is_multi()):
                 child.setowner(self, 'default')
                 self._cfgimpl_values[name] = copy(child.getdefault())
index 82dd86f..061099b 100644 (file)
@@ -18,6 +18,4 @@ class RequirementRecursionError(RequiresError):
     pass
 class MandatoryError(Exception):
     pass 
-class SpecialOwnersError(Exception):
-    pass 
     
index 4cd8700..23ddc63 100644 (file)
 # the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
 # the whole pypy projet is under MIT licence
 # ____________________________________________________________
-from tiramisu.autolib import special_owners
 from tiramisu.basetype import HiddenBaseType, DisabledBaseType
 from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError, 
-    SpecialOwnersError, RequiresError, RequirementRecursionError)
+    RequiresError, RequirementRecursionError)
 available_actions = ['hide', 'show', 'enable', 'disable'] 
 reverse_actions = {'hide': 'show', 'show': 'hide', 
                    'disable':'enable', 'enable': 'disable'}
 # ____________________________________________________________
 # OptionDescription authorized group_type values
 group_types = ['default', 'family', 'group', 'master']
+# ____________________________________________________________
 # multi types 
-
 class Multi(list):
     "container that support items for the values of list (multi) options" 
     def __init__(self, lst, config, child):
@@ -145,11 +144,11 @@ class Option(HiddenBaseType, DisabledBaseType):
     def force_default(self):
         self._force_default_on_freeze = True
 
+    def hascallback_and_isfrozen():
+        return self._frozen and self.has_callback()
+
     def is_forced_on_freeze(self):
-        if self._frozen and self._force_default_on_freeze:
-            return True
-        else: 
-            return False
+        return self._frozen and self._force_default_on_freeze
 
     def getdoc(self):
         return self.doc
@@ -172,10 +171,6 @@ class Option(HiddenBaseType, DisabledBaseType):
         name = self._name
         if self._frozen:
             raise TypeError("trying to change a frozen option's owner: %s" % name)
-        if owner in special_owners:
-            if self.callback == None:
-                raise SpecialOwnersError("no callback specified for" 
-                                                      "option {0}".format(name))
         if self.is_multi():
             if not type(owner) == list:
                 raise ConfigError("invalid owner for multi "
@@ -228,13 +223,16 @@ class Option(HiddenBaseType, DisabledBaseType):
 
     def getkey(self, value):
         return value
-
+    # ____________________________________________________________
     def freeze(self):
         self._frozen = True
         return True
 
     def unfreeze(self):
         self._frozen = False
+
+    def isfrozen(self):
+        return self._frozen
     # ____________________________________________________________
     def is_multi(self):
         return self.multi
@@ -513,8 +511,6 @@ def apply_requires(opt, config):
                           "detected for option: '{0}' with requirement on: '{1}'".format(path, name))
                 homeconfig, shortname = \
                                       rootconfig._cfgimpl_get_home_by_path(name)
-                # FIXME: doesn't work with 'auto' or 'fill' yet 
-                # (copy the code from the __getattr__
                 if shortname in homeconfig._cfgimpl_values:
                     value = homeconfig._cfgimpl_values[shortname]
                     if (not inverted and value == expected) or \