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')
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})")
#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"
# 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()
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
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))
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'
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)
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):
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())
else:
_result = result
return _result
- if not isinstance(opt_or_descr, OptionDescription):
+
# mandatory options
homeconfig = self._cfgimpl_get_toplevel()
mandatory = homeconfig._cfgimpl_mandatory
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())
pass
class MandatoryError(Exception):
pass
-class SpecialOwnersError(Exception):
- pass
# 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):
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
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 "
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
"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 \