# the whole pypy projet is under MIT licence
# ____________________________________________________________
from tiramisu.i18n import _
-from tiramisu.setting import log
+from tiramisu.setting import log, undefined
from tiramisu.error import SlaveError, ConfigError
-from .baseoption import SymLinkOption, Option
+from .baseoption import DynSymLinkOption, SymLinkOption, Option
class MasterSlaves(object):
__slots__ = ('master', 'slaves')
- def __init__(self, name, childs):
+ def __init__(self, name, childs, validate=True):
#if master (same name has group) is set
#for collect all slaves
self.master = None
slaves = []
for child in childs:
- if isinstance(child, SymLinkOption):
+ if isinstance(child, SymLinkOption): # pragma: optional cover
raise ValueError(_("master group {0} shall not have "
"a symlinkoption").format(name))
- if not isinstance(child, Option):
+ if not isinstance(child, Option): # pragma: optional cover
raise ValueError(_("master group {0} shall not have "
"a subgroup").format(name))
- if not child.impl_is_multi():
+ if not child.impl_is_multi(): # pragma: optional cover
raise ValueError(_("not allowed option {0} "
"in group {1}"
": this option is not a multi"
- "").format(child._name, name))
- if child._name == name:
+ "").format(child.impl_getname(), name))
+ if child.impl_getname() == name:
self.master = child
else:
slaves.append(child)
- if self.master is None:
+ if self.master is None: # pragma: optional cover
raise ValueError(_('master group with wrong'
' master name for {0}'
).format(name))
- callback, callback_params = self.master.impl_get_callback()
- if callback is not None and callback_params is not None:
- for key, callbacks in callback_params.items():
- for callbk in callbacks:
- if isinstance(callbk, tuple):
- if callbk[0] in slaves:
- raise ValueError(_("callback of master's option shall "
- "not refered a slave's ones"))
+ if validate:
+ callback, callback_params = self.master.impl_get_callback()
+ if callback is not None and callback_params != {}: # pragma: optional cover
+ for key, callbacks in callback_params.items():
+ for callbk in callbacks:
+ if isinstance(callbk, tuple):
+ if callbk[0] in slaves:
+ raise ValueError(_("callback of master's option shall "
+ "not refered a slave's ones"))
#everything is ok, store references
self.slaves = tuple(slaves)
for child in childs:
child._master_slaves = self
def is_master(self, opt):
- return opt == self.master
+ return opt == self.master or (isinstance(opt, DynSymLinkOption) and
+ opt._opt == self.master)
+
+ def getmaster(self, opt):
+ if isinstance(opt, DynSymLinkOption):
+ suffix = opt.impl_getsuffix()
+ name = self.master.impl_getname() + suffix
+ base_path = opt._dyn.split('.')[0] + '.'
+ path = base_path + name
+ master = self.master._impl_to_dyn(name, path)
+ else: # pragma: no dynoptiondescription cover
+ master = self.master
+ return master
+
+ def getslaves(self, opt):
+ if isinstance(opt, DynSymLinkOption):
+ for slave in self.slaves:
+ suffix = opt.impl_getsuffix()
+ name = slave.impl_getname() + suffix
+ base_path = opt._dyn.split('.')[0] + '.'
+ path = base_path + name
+ yield slave._impl_to_dyn(name, path)
+ else: # pragma: no dynoptiondescription cover
+ for slave in self.slaves:
+ yield slave
def in_same_group(self, opt):
- return opt == self.master or opt in self.slaves
+ if isinstance(opt, DynSymLinkOption):
+ return opt._opt == self.master or opt._opt in self.slaves
+ else: # pragma: no dynoptiondescription cover
+ return opt == self.master or opt in self.slaves
- def reset(self, values):
- for slave in self.slaves:
+ def reset(self, opt, values):
+ #FIXME pas de opt ???
+ for slave in self.getslaves(opt):
values.reset(slave)
- def pop(self, values, index):
+ def pop(self, opt, values, index):
#FIXME pas test de meta ...
- for slave in self.slaves:
+ for slave in self.getslaves(opt):
if not values.is_default_owner(slave, validate_properties=False,
validate_meta=False):
values._get_cached_item(slave, validate=False,
pass
def getitem(self, values, opt, path, validate, force_permissive,
- force_properties, validate_properties):
- if opt == self.master:
- value = values._get_validated_value(opt, path, validate,
- force_permissive,
- force_properties,
- validate_properties)
- if validate is True:
- masterlen = len(value)
- for slave in self.slaves:
- try:
- slave_path = values._get_opt_path(slave)
+ force_properties, validate_properties, slave_path=undefined,
+ slave_value=undefined):
+ if self.is_master(opt):
+ return self._getmaster(values, opt, path, validate,
+ force_permissive, force_properties,
+ validate_properties, slave_path,
+ slave_value)
+ else:
+ return self._getslave(values, opt, path, validate,
+ force_permissive, force_properties,
+ validate_properties)
+
+ def _getmaster(self, values, opt, path, validate, force_permissive,
+ force_properties, validate_properties, c_slave_path,
+ c_slave_value):
+ value = values._get_validated_value(opt, path, validate,
+ force_permissive,
+ force_properties,
+ validate_properties)
+ if validate is True:
+ masterlen = len(value)
+ for slave in self.getslaves(opt):
+ try:
+ slave_path = slave.impl_getpath(values._getcontext())
+ if c_slave_path == slave_path:
+ slave_value = c_slave_value
+ else:
slave_value = values._get_validated_value(slave,
slave_path,
False,
False,
None, False,
None) # not undefined
- slavelen = len(slave_value)
- self.validate_slave_length(masterlen, slavelen, slave._name)
- except ConfigError:
- pass
- return value
- else:
- value = values._get_validated_value(opt, path, validate,
- force_permissive,
- force_properties,
- validate_properties,
- None) # not undefined
- return self.get_slave_value(values, opt, value, validate, validate_properties)
+ slavelen = len(slave_value)
+ self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
+ except ConfigError: # pragma: optional cover
+ pass
+ return value
+
+ def _getslave(self, values, opt, path, validate, force_permissive,
+ force_properties, validate_properties):
+ value = values._get_validated_value(opt, path, validate,
+ force_permissive,
+ force_properties,
+ validate_properties,
+ None) # not undefined
+ return self.get_slave_value(values, opt, value, validate,
+ validate_properties, force_permissive)
def setitem(self, values, opt, value, path):
- if opt == self.master:
+ if self.is_master(opt):
masterlen = len(value)
- for slave in self.slaves:
- slave_path = values._get_opt_path(slave)
+ for slave in self.getslaves(opt):
+ slave_path = slave.impl_getpath(values._getcontext())
slave_value = values._get_validated_value(slave,
slave_path,
False,
None, False,
None) # not undefined
slavelen = len(slave_value)
- self.validate_slave_length(masterlen, slavelen, slave._name)
+ self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
else:
- self.validate_slave_length(self.get_length(values), len(value),
- opt._name, setitem=True)
+ self.validate_slave_length(self.get_length(values, opt,
+ slave_path=path), len(value),
+ opt.impl_getname(), opt, setitem=True)
- def get_length(self, values, validate=True):
- masterp = values._get_opt_path(self.master)
- return len(self.getitem(values, self.master, masterp, validate, False,
- None, True))
+ def get_length(self, values, opt, validate=True, slave_path=undefined,
+ slave_value=undefined, force_permissive=False):
+ """get master len with slave option"""
+ masterp = self.getmaster(opt).impl_getpath(values._getcontext())
+ if slave_value is undefined:
+ slave_path = undefined
+ return len(self.getitem(values, self.getmaster(opt), masterp, validate,
+ force_permissive, None, True, slave_path,
+ slave_value))
- def validate_slave_length(self, masterlen, valuelen, name, setitem=False):
- if valuelen > masterlen or (valuelen < masterlen and setitem):
+ def validate_slave_length(self, masterlen, valuelen, name, opt, setitem=False):
+ if valuelen > masterlen or (valuelen < masterlen and setitem): # pragma: optional cover
log.debug('validate_slave_length: masterlen: {0}, valuelen: {1}, '
'setitem: {2}'.format(masterlen, valuelen, setitem))
raise SlaveError(_("invalid len for the slave: {0}"
" which has {1} as master").format(
- name, self.master._name))
+ name, self.getmaster(opt).impl_getname()))
def get_slave_value(self, values, opt, value, validate=True,
- validate_properties=True):
+ validate_properties=True, force_permissive=False):
"""
if master has length 0:
return []
list is greater than master: raise SlaveError
"""
#if slave, had values until master's one
- masterlen = self.get_length(values, validate)
+ path = opt.impl_getpath(values._getcontext())
+ masterlen = self.get_length(values, opt, validate, path, value,
+ force_permissive)
valuelen = len(value)
if validate:
- self.validate_slave_length(masterlen, valuelen, opt._name)
- path = values._get_opt_path(opt)
+ self.validate_slave_length(masterlen, valuelen, opt.impl_getname(), opt)
if valuelen < masterlen:
for num in range(0, masterlen - valuelen):
index = valuelen + num