multies are working now

This commit is contained in:
gwen 2012-07-23 14:30:06 +02:00
parent 7800e38585
commit 9b876f6463
2 changed files with 75 additions and 61 deletions

View File

@ -27,6 +27,7 @@ from error import (HiddenOptionError, ConfigError, NotFoundError,
from option import (OptionDescription, Option, SymLinkOption, group_types, from option import (OptionDescription, Option, SymLinkOption, group_types,
Multi, apply_requires, modes) Multi, apply_requires, modes)
from autolib import special_owners, special_owner_factory from autolib import special_owners, special_owner_factory
from copy import copy
# ______________________________________________________________________ # ______________________________________________________________________
# generic owner. 'default' is the general config owner after init time # generic owner. 'default' is the general config owner after init time
default_owner = 'user' default_owner = 'user'
@ -68,10 +69,10 @@ class Config(object):
for child in self._cfgimpl_descr._children: for child in self._cfgimpl_descr._children:
if isinstance(child, Option): if isinstance(child, Option):
if child.is_multi(): if child.is_multi():
childdef = Multi(child.getdefault(), config=self, childdef = Multi(copy(child.getdefault()), config=self,
child=child) child=child)
self._cfgimpl_values[child._name] = childdef self._cfgimpl_values[child._name] = childdef
self._cfgimpl_previous_values[child._name] = childdef self._cfgimpl_previous_values[child._name] = list(childdef)
else: else:
childdef = child.getdefault() childdef = child.getdefault()
self._cfgimpl_values[child._name] = childdef self._cfgimpl_values[child._name] = childdef
@ -100,9 +101,14 @@ class Config(object):
for child in self._cfgimpl_descr._children: for child in self._cfgimpl_descr._children:
if isinstance(child, Option): if isinstance(child, Option):
if child._name not in self._cfgimpl_values: if child._name not in self._cfgimpl_values:
self._cfgimpl_values[child._name] = child.getdefault() if child.is_multi():
# FIXME and ['default', ...] if is_multi() ? self._cfgimpl_values[child._name] = Multi(
self._cfgimpl_value_owners[child._name] = 'default' copy(child.getdefault()), config=self, child=child)
self._cfgimpl_value_owners[child._name] = ['default' \
for i in range(len(child.getdefault() ))]
else:
self._cfgimpl_values[child._name] = copy(child.getdefault())
self._cfgimpl_value_owners[child._name] = 'default'
elif isinstance(child, OptionDescription): elif isinstance(child, OptionDescription):
if child._name not in self._cfgimpl_values: if child._name not in self._cfgimpl_values:
self._cfgimpl_values[child._name] = Config(child, parent=self) self._cfgimpl_values[child._name] = Config(child, parent=self)
@ -223,7 +229,7 @@ class Config(object):
config=self._cfgimpl_get_toplevel()) config=self._cfgimpl_get_toplevel())
# this result **shall not** be a list # this result **shall not** be a list
# for example, [1, 2, 3, None] -> [1, 2, 3, result] # for example, [1, 2, 3, None] -> [1, 2, 3, result]
if type(result) == list: if isinstance(result, list):
raise ConfigError('invalid calculated value returned' raise ConfigError('invalid calculated value returned'
' for option {0} : shall not be a list'.format(name)) ' for option {0} : shall not be a list'.format(name))
if result != None and not opt_or_descr._validate(result): if result != None and not opt_or_descr._validate(result):
@ -231,9 +237,9 @@ class Config(object):
' for option {0}'.format(name)) ' for option {0}'.format(name))
if opt_or_descr.is_multi(): if opt_or_descr.is_multi():
if value == []: if value == []:
_result = [result] _result = Multi([result], value.config, value.child)
else: else:
_result = [] _result = Multi([], value.config, value.child)
for val in value: for val in value:
if val == None: if val == None:
val = result val = result
@ -250,19 +256,8 @@ class Config(object):
and opt_or_descr.getdefault() == None: and opt_or_descr.getdefault() == None:
raise MandatoryError("option: {0} is mandatory " raise MandatoryError("option: {0} is mandatory "
"and shall have a value".format(name)) "and shall have a value".format(name))
# for multi types with None in the value (ex: ["egg", None, "spam"])
# None is replaced by default_multi
if not isinstance(opt_or_descr, OptionDescription):
if opt_or_descr.is_multi() and None in self._cfgimpl_values[name]:
newvalue = []
for val in self._cfgimpl_values[name]:
if val is None:
newvalue.append(opt_or_descr.default_multi)
else:
newvalue.append(val)
return newvalue
return self._cfgimpl_values[name] return self._cfgimpl_values[name]
def __dir__(self): def __dir__(self):
#from_type = dir(type(self)) #from_type = dir(type(self))
from_dict = list(self.__dict__) from_dict = list(self.__dict__)
@ -301,6 +296,7 @@ class Config(object):
def setoption(self, name, value, who=None): def setoption(self, name, value, who=None):
#who is **not necessarily** a owner, because it cannot be a list #who is **not necessarily** a owner, because it cannot be a list
#FIXME : sortir le setoption pour les multi, ca ne devrait pas être la
child = getattr(self._cfgimpl_descr, name) child = getattr(self._cfgimpl_descr, name)
if who == None: if who == None:
if child.is_multi(): if child.is_multi():
@ -310,8 +306,11 @@ class Config(object):
else: else:
if type(child) != SymLinkOption: if type(child) != SymLinkOption:
if child.is_multi(): if child.is_multi():
if type(value) != list: if type(value) != Multi:
raise ConfigError("invalid value for option:" if type(value) == list:
value = Multi(value, self, child)
else:
raise ConfigError("invalid value for option:"
" {0} that is set to multi".format(name)) " {0} that is set to multi".format(name))
newowner = [who for i in range(len(value))] newowner = [who for i in range(len(value))]
else: else:
@ -336,10 +335,11 @@ class Config(object):
child.hide() child.hide()
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')
self._cfgimpl_values[name] = child.getdefault() self._cfgimpl_values[name] = copy(child.getdefault())
elif (value == [] and who != 'default' and child.is_multi()): elif (value == [] and who != 'default' and child.is_multi()):
child.setowner(self, ['default' for i in range(len(child.getdefault()))]) child.setowner(self, ['default' for i in range(len(child.getdefault()))])
self._cfgimpl_values[name] = child.getdefault() self._cfgimpl_values[name] = Multi(copy(child.getdefault()),
config=self, child=child)
else: else:
child.setowner(self, newowner) child.setowner(self, newowner)
else: else:
@ -444,7 +444,7 @@ class Config(object):
self.cfgimpl_unfreeze() self.cfgimpl_unfreeze()
rootconfig = self._cfgimpl_get_toplevel() rootconfig = self._cfgimpl_get_toplevel()
rootconfig._cfgimpl_hidden = True rootconfig._cfgimpl_hidden = True
rootconfig._cfgimpl_disabled = False rootconfig._cfgimpl_disabled = True
rootconfig._cfgimpl_mandatory = False rootconfig._cfgimpl_mandatory = False
# ____________________________________________________________ # ____________________________________________________________
def getkey(self): def getkey(self):

View File

@ -31,49 +31,53 @@ reverse_actions = {'hide': 'show', 'show': 'hide',
# OptionDescription authorized group_type values # OptionDescription authorized group_type values
group_types = ['default', 'family', 'group', 'master'] group_types = ['default', 'family', 'group', 'master']
# multi types # multi types
class Multi(list): class Multi(list):
"container that support items for the values of list (multi) options" "container that support items for the values of list (multi) options"
def __init__(self, lst, config=None, child=None): def __init__(self, lst, config, child):
self.config = config self.config = config
self.child = child self.child = child
super(Multi, self).__init__(lst) super(Multi, self).__init__(lst)
def __getitem__(self, key):
value = super(Multi, self).__getitem__(key)
if value is None:
return self.child.default_multi
else:
return value
def __setitem__(self, key, value): def __setitem__(self, key, value):
if value is None: return self.setoption(value, key)
owner = 'default'
else:
owner = self.config._cfgimpl_owner
oldowner = self.child.getowner(self.config)
oldowner[key] = owner
self.child.setowner(self.config, oldowner)
if value != None and not self.child._validate(value):
raise ConfigError("invalid value {0} "
"for option {1}".format(str(value), self.child._name))
return super(Multi, self).__setitem__(key, value)
def append(self, value): def append(self, value):
if value is None: self.setoption(value)
owner = 'default'
def setoption(self, value, key=None):
owners = self.child.getowner(self.config)
# None is replaced by default_multi
if value == None:
defval = self.child.getdefault()
if key is not None and len(defval) > key:
value = defval[key]
else:
value = self.child.default_multi
who = 'default'
else: else:
owner = self.config._cfgimpl_owner who = self.config._cfgimpl_owner
if not self.child._validate(value):
raise ConfigError("invalid value {0} "
"for option {1}".format(str(value), self.child._name))
oldvalue = list(self)
oldowner = self.child.getowner(self.config) oldowner = self.child.getowner(self.config)
oldowner.append(owner) if key is None:
ret = super(Multi, self).append(value)
oldvalue.append(None)
oldowner.append(who)
else:
ret = super(Multi, self).__setitem__(key, value)
oldowner[key] = who
self.config._cfgimpl_previous_values[self.child._name] = oldvalue
self.child.setowner(self.config, oldowner) self.child.setowner(self.config, oldowner)
# changer dans la config la valeur par défaut et le owner return ret
if value != None and not self.child._validate(value):
raise ConfigError("invalid value {0} " def pop(self, key):
"for option {1}".format(str(value), self.child._name)) oldowner = self.child.getowner(self.config)
super(Multi, self).append(value) oldowner.pop(key)
self.child.setowner(self.config, oldowner)
# def pop(self): super(Multi, self).pop(key)
# pass
# ____________________________________________________________ # ____________________________________________________________
# #
class Option(HiddenBaseType, DisabledBaseType, ModeBaseType): class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
@ -202,7 +206,10 @@ class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
# raise ConflictConfigError("an option with requires " # raise ConflictConfigError("an option with requires "
# "has not the same length of the others " # "has not the same length of the others "
# "in the group : {0}".format(reqname)) # "in the group : {0}".format(reqname))
config._cfgimpl_previous_values[name] = config._cfgimpl_values[name] if type(config._cfgimpl_values[name]) == Multi:
config._cfgimpl_previous_values[name] = list(config._cfgimpl_values[name])
else:
config._cfgimpl_previous_values[name] = config._cfgimpl_values[name]
config._cfgimpl_values[name] = value config._cfgimpl_values[name] = value
def getkey(self, value): def getkey(self, value):
@ -224,10 +231,14 @@ class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
class ChoiceOption(Option): class ChoiceOption(Option):
opt_type = 'string' opt_type = 'string'
def __init__(self, name, doc, values, default=None, requires=None, def __init__(self, name, doc, values, open_values=False, default=None,
callback=None, callback_params=None, multi=False, requires=None, callback=None, callback_params=None,
mandatory=False): multi=False, mandatory=False):
self.values = values self.values = values
if open_values not in [True, False]:
raise ConfigError('Open_values must be a boolean for '
'{0}'.format(name))
self.open_values = open_values
super(ChoiceOption, self).__init__(name, doc, default=default, super(ChoiceOption, self).__init__(name, doc, default=default,
callback=callback, callback_params=callback_params, callback=callback, callback_params=callback_params,
requires=requires, multi=multi, mandatory=mandatory) requires=requires, multi=multi, mandatory=mandatory)
@ -237,7 +248,10 @@ class ChoiceOption(Option):
super(ChoiceOption, self).setoption(config, value, who) super(ChoiceOption, self).setoption(config, value, who)
def _validate(self, value): def _validate(self, value):
return value is None or value in self.values if not self.open_values:
return value is None or value in self.values
else:
return True
class BoolOption(Option): class BoolOption(Option):
opt_type = 'bool' opt_type = 'bool'