multies are working now
This commit is contained in:
parent
7800e38585
commit
9b876f6463
|
@ -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,8 +101,13 @@ 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(
|
||||||
|
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'
|
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:
|
||||||
|
@ -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,17 +256,6 @@ 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):
|
||||||
|
@ -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,7 +306,10 @@ 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:
|
||||||
|
if type(value) == list:
|
||||||
|
value = Multi(value, self, child)
|
||||||
|
else:
|
||||||
raise ConfigError("invalid value for option:"
|
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))]
|
||||||
|
@ -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):
|
||||||
|
|
|
@ -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:
|
else:
|
||||||
owner = self.config._cfgimpl_owner
|
value = self.child.default_multi
|
||||||
oldowner = self.child.getowner(self.config)
|
who = 'default'
|
||||||
oldowner.append(owner)
|
else:
|
||||||
self.child.setowner(self.config, oldowner)
|
who = self.config._cfgimpl_owner
|
||||||
# changer dans la config la valeur par défaut et le owner
|
if not self.child._validate(value):
|
||||||
if value != None and not self.child._validate(value):
|
|
||||||
raise ConfigError("invalid value {0} "
|
raise ConfigError("invalid value {0} "
|
||||||
"for option {1}".format(str(value), self.child._name))
|
"for option {1}".format(str(value), self.child._name))
|
||||||
super(Multi, self).append(value)
|
oldvalue = list(self)
|
||||||
|
oldowner = self.child.getowner(self.config)
|
||||||
|
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)
|
||||||
|
return ret
|
||||||
|
|
||||||
# def pop(self):
|
def pop(self, key):
|
||||||
# pass
|
oldowner = self.child.getowner(self.config)
|
||||||
|
oldowner.pop(key)
|
||||||
|
self.child.setowner(self.config, oldowner)
|
||||||
|
super(Multi, self).pop(key)
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
#
|
#
|
||||||
class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
|
class Option(HiddenBaseType, DisabledBaseType, ModeBaseType):
|
||||||
|
@ -202,6 +206,9 @@ 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))
|
||||||
|
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_previous_values[name] = config._cfgimpl_values[name]
|
||||||
config._cfgimpl_values[name] = value
|
config._cfgimpl_values[name] = 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):
|
||||||
|
if not self.open_values:
|
||||||
return value is None or value in self.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'
|
||||||
|
|
Loading…
Reference in New Issue