+Sun Nov 29 23:01:28 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
+ * requires could be apply to a slave and properties could be different
+
Mon Oct 12 17:05:28 2015 +0200 Emmanuel Garette <egarette@cadoles.com>
* domainname with only one character is now allowed
from tiramisu import setting
setting.expires_time = 1
-from tiramisu.option import IntOption, OptionDescription
+from tiramisu.option import IntOption, StrOption, OptionDescription
from tiramisu.config import Config
-from tiramisu.error import ConfigError, PropertiesOptionError
+from tiramisu.error import ConfigError
+from tiramisu.setting import groups
from time import sleep, time
values = c.cfgimpl_get_values()
settings = c.cfgimpl_get_settings()
ntime = time() + 1
- settings._p_.setcache('u1', set(['inject']), ntime)
+ settings._p_.setcache('u1', set(['inject']), ntime, None)
assert 'inject' in settings[od1.u1]
- values._p_.setcache('u1', 100, ntime)
+ values._p_.setcache('u1', 100, ntime, None)
assert c.u1 == [100]
c = Config(od1)
values = c.cfgimpl_get_values()
settings = c.cfgimpl_get_settings()
- settings._p_.setcache('u1', set(['inject2']), None)
+ settings._p_.setcache('u1', set(['inject2']), None, None)
assert 'inject2' in settings[od1.u1]
- values._p_.setcache('u1', 200, None)
+ values._p_.setcache('u1', 200, None, None)
assert c.u1 == [200]
c.cfgimpl_get_settings().remove('expire')
c.cfgimpl_get_values().force_cache()
- assert c.cfgimpl_get_values()._p_.get_cached(c) == {'u1': ([], None), 'u3': ([], None), 'u2': (None, None), 'u4': (None, None)}
- assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'u4': (set(['disabled']), None), 'u1': (set([]), None), 'u3': (set([]), None), 'u2': (set([]), None)}
+ assert c.cfgimpl_get_values()._p_.get_cached(c) == {'u1': {None: ([], None)},
+ 'u2': {None: (None, None)},
+ 'u3': {None: ([], None)},
+ 'u4': {None: (None, None)}}
+ assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'u1': {None: (set([]), None)},
+ 'u2': {None: (set([]), None)},
+ 'u3': {None: (set([]), None)},
+ 'u4': {None: (set(['disabled']), None)}}
c.read_only()
c.cfgimpl_get_values().force_cache()
- assert c.cfgimpl_get_values()._p_.get_cached(c) == {'u1': ([], None), 'u3': ([], None), 'u2': (None, None)}
- assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'u4': (set(['disabled']), None), 'u1': (set([]), None), 'u3': (set([]), None), 'u2': (set([]), None)}
+ assert c.cfgimpl_get_values()._p_.get_cached(c) == {'u1': {None: ([], None)},
+ 'u2': {None: (None, None)},
+ 'u3': {None: ([], None)}}
+ assert c.cfgimpl_get_settings()._p_.get_cached(c) == {'u1': {None: (set([]), None)},
+ 'u2': {None: (set([]), None)},
+ 'u3': {None: (set([]), None)},
+ 'u4': {None: (set(['disabled']), None)}}
c.cfgimpl_get_settings().remove('cache')
raises(ConfigError, "c.cfgimpl_get_values().force_cache()")
+
+
+def test_cache_master_slave():
+ ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
+ netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
+ interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
+ interface1.impl_set_group_type(groups.master)
+ maconfig = OptionDescription('toto', '', [interface1])
+ cfg = Config(maconfig)
+ cfg.read_write()
+ assert cfg.cfgimpl_get_values()._p_.get_cached(cfg) == {}
+ assert cfg.cfgimpl_get_settings()._p_.get_cached(cfg) == {}
+ #
+ cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.2')
+ cfg.ip_admin_eth0.ip_admin_eth0
+ cfg.ip_admin_eth0.netmask_admin_eth0
+ cache = cfg.cfgimpl_get_values()._p_.get_cached(cfg)
+ assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
+ assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
+ assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2']
+ assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0])
+ assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None]
+ assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
+ cache = cfg.cfgimpl_get_settings()._p_.get_cached(cfg)
+ assert set(cache.keys()) == set(['ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
+ assert set(cache['ip_admin_eth0'].keys()) == set([None])
+ assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
+ assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0])
+ #
+ cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.1')
+ cfg.ip_admin_eth0.ip_admin_eth0
+ cfg.ip_admin_eth0.netmask_admin_eth0
+ cache = cfg.cfgimpl_get_values()._p_.get_cached(cfg)
+ assert set(cache.keys()) == set(['ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
+ assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
+ assert cache['ip_admin_eth0.ip_admin_eth0'][None][0] == ['192.168.1.2', '192.168.1.1']
+ assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0, 1])
+ assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None, None]
+ assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
+ assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None
+ cache = cfg.cfgimpl_get_settings()._p_.get_cached(cfg)
+ assert set(cache.keys()) == set(['ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
+ assert set(cache['ip_admin_eth0'].keys()) == set([None])
+ assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
+ assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([None, 0, 1])
+ #DEL, insert, ...
OptionDescription("s1", "", [
BoolOption("a", "", default=False),
BoolOption("b", "", default=False, properties=('disabled',))]),
+ OptionDescription("s2", "", [
+ BoolOption("a", "", default=False),
+ BoolOption("b", "", default=False)], properties=('disabled',)),
+ IntOption("int", "", default=42)])
+ config = Config(descr)
+ config.read_only()
+ d = config.make_dict()
+ assert d == {"s1.a": False, "int": 42}
+
+
+def test_make_dict_with_disabled_in_callback():
+ descr = OptionDescription("opt", "", [
+ OptionDescription("s1", "", [
+ BoolOption("a", "", default=False),
+ BoolOption("b", "", default=False, properties=('disabled',))]),
+ OptionDescription("s2", "", [
+ BoolOption("a", "", default=False),
+ BoolOption("b", "", default=False)], properties=('disabled',)),
IntOption("int", "", default=42)])
config = Config(descr)
config.read_only()
from py.test import raises
-from tiramisu.setting import owners
+from tiramisu.setting import owners, groups
from tiramisu.config import Config
from tiramisu.option import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription
def test_idontexist():
descr = make_description()
cfg = Config(descr)
+ cfg
raises(AttributeError, "cfg.idontexist")
def test_multi_with_requires_that_is_multi():
- s = StrOption("string", "", default=["string"], multi=True)
- intoption = IntOption('int', 'Test int option', default=[0], multi=True)
- raises(ValueError, "StrOption('str', 'Test string option', default=['abc'], requires=[{'option': intoption, 'expected': 1, 'action': 'hidden'}], multi=True)")
+ b = IntOption('int', 'Test int option', default=[0], multi=True)
+ c = StrOption('str', 'Test string option', default=['abc'], requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
+ descr = OptionDescription("opt", "", [b, c])
+ descr
+ raises(ValueError, "Config(descr)")
+
+
+def test_multi_with_requires_that_is_masterslave():
+ b = IntOption('int', 'Test int option', default=[0], multi=True)
+ c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
+ descr = OptionDescription("int", "", [b, c])
+ descr.impl_set_group_type(groups.master)
+ Config(descr)
+
+
+def test_multi_with_requires_that_is_masterslave_master():
+ b = IntOption('int', 'Test int option', multi=True)
+ c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
+ descr = OptionDescription("str", "", [c, b])
+ descr.impl_set_group_type(groups.master)
+ raises(ValueError, "Config(descr)")
+
+
+def test_multi_with_requires_that_is_masterslave2():
+ b = IntOption('int', 'Test int option', default=[0], multi=True)
+ c = StrOption('str', 'Test string option', multi=True)
+ d = StrOption('str1', 'Test string option', requires=[{'option': c, 'expected': '1', 'action': 'hidden'}], multi=True)
+ descr = OptionDescription("int", "", [b, c, d])
+ descr.impl_set_group_type(groups.master)
+ Config(descr)
+
+
+def test_multi_with_requires_that_is_not_same_masterslave():
+ b = IntOption('int', 'Test int option', default=[0], multi=True)
+ c = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
+ descr1 = OptionDescription("int", "", [b, c])
+ descr1.impl_set_group_type(groups.master)
+ d = IntOption('int1', 'Test int option', default=[0], multi=True)
+ e = StrOption('str', 'Test string option', requires=[{'option': b, 'expected': 1, 'action': 'hidden'}], multi=True)
+ descr2 = OptionDescription("int1", "", [d, e])
+ descr2.impl_set_group_type(groups.master)
+ descr3 = OptionDescription('val', '', [descr1, descr2])
+ descr3
+ raises(ValueError, "Config(descr3)")
def test_multi_with_bool():
s = BoolOption("bool", "", default=[False], multi=True)
descr = OptionDescription("options", "", [s])
config = Config(descr)
+ config
assert descr.bool.impl_is_multi() is True
raises(ValueError, "config.bool = True")
c.read_write()
setting = c.cfgimpl_get_settings()
option = c.cfgimpl_get_description().sub.b1
+ option
c._setattr('sub.b1', True, force_permissive=True)
assert str(setting[b1]) in ["['test']", "[u'test']"]
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
+ interface1
raises(ValueError, "interface1.impl_set_group_type('toto')")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
invalid_group = OptionDescription('interface1', '', [ip_admin_eth0, netmask_admin_eth0])
+ invalid_group
raises(ValueError, "invalid_group.impl_set_group_type(groups.master)")
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True)
subgroup = OptionDescription("subgroup", '', [])
invalid_group = OptionDescription('ip_admin_eth0', '', [subgroup, ip_admin_eth0, netmask_admin_eth0])
+ invalid_group
raises(ValueError, "invalid_group.impl_set_group_type(groups.master)")
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau")
group = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
+ group
raises(ValueError, "group.impl_set_group_type(groups.master)")
do_autopath()
from copy import copy
+from tiramisu.setting import groups
from tiramisu import setting
setting.expires_time = 1
from tiramisu.option import IPOption, OptionDescription, BoolOption, IntOption, StrOption
def test_requires_invalid():
a = BoolOption('activate_service', '', True)
+ a
raises(ValueError, "IPOption('ip_address_service', '', requires='string')")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False, 'action': 'disabled', 'unknown': True}])")
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': False}])")
def test_requires_different_inverse():
a = BoolOption('activate_service', '', True)
+ a
raises(ValueError, "IPOption('ip_address_service', '', requires=[{'option': a, 'expected': True, 'action': 'disabled', 'inverse': True}, {'option': a, 'expected': True, 'action': 'disabled', 'inverse': False}])")
def test_properties_conflict():
a = BoolOption('activate_service', '', True)
+ a
raises(ValueError, "IPOption('ip_address_service', '', properties=('disabled',), requires=[{'option': a, 'expected': False, 'action': 'disabled'}])")
raises(ValueError, "od1 = OptionDescription('service', '', [a], properties=('disabled',), requires=[{'option': a, 'expected': False, 'action': 'disabled'}])")
+
+
+def test_master_slave_requires():
+ ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
+ netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True,
+ requires=[{'option': ip_admin_eth0, 'expected': '192.168.1.1', 'action': 'disabled'}])
+ interface1 = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
+ interface1.impl_set_group_type(groups.master)
+ maconfig = OptionDescription('toto', '', [interface1])
+ cfg = Config(maconfig)
+ cfg.read_write()
+ assert cfg.ip_admin_eth0.netmask_admin_eth0 == []
+ assert cfg.ip_admin_eth0.ip_admin_eth0 == []
+ cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.2')
+ assert cfg.ip_admin_eth0.netmask_admin_eth0 == [None]
+ assert cfg.ip_admin_eth0.ip_admin_eth0 == ['192.168.1.2']
+ cfg.ip_admin_eth0.ip_admin_eth0.append('192.168.1.1')
+ assert cfg.ip_admin_eth0.netmask_admin_eth0[0] is None
+ raises(PropertiesOptionError, "cfg.ip_admin_eth0.netmask_admin_eth0[1]")
p = URLOption('p', '')
q = FilenameOption('q', '')
m = OptionDescription('m', '', [a, b, c, d, e, g, h, i, j, k, l, o, p, q])
- a._requires = 'a'
- b._requires = 'b'
- c._requires = 'c'
- d._requires = 'd'
- e._requires = 'e'
- g._requires = 'g'
- h._requires = 'h'
- i._requires = 'i'
- j._requires = 'j'
- k._requires = 'k'
- l._requires = 'l'
- m._requires = 'm'
- o._requires = 'o'
- p._requires = 'p'
- q._requires = 'q'
+ a._requires = (((a,),),)
+ b._requires = (((a,),),)
+ c._requires = (((a,),),)
+ d._requires = (((a,),),)
+ e._requires = (((a,),),)
+ g._requires = (((a,),),)
+ h._requires = (((a,),),)
+ i._requires = (((a,),),)
+ j._requires = (((a,),),)
+ k._requires = (((a,),),)
+ l._requires = (((a,),),)
+ m._requires = (((a,),),)
+ o._requires = (((a,),),)
+ p._requires = (((a,),),)
+ q._requires = (((a,),),)
Config(m)
raises(AttributeError, "a._requires = 'a'")
raises(AttributeError, "b._requires = 'b'")
# 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, ConfigError, ContextError, \
+from .error import PropertiesOptionError, ConfigError, ContextError, \
SlaveError
-from tiramisu.i18n import _
-from tiramisu.setting import undefined
+from .i18n import _
+from .setting import undefined
# ____________________________________________________________
else:
kwargs[key] = couple[0]
ret = calculate(callback, args, kwargs)
- if callback_params != {} and isinstance(ret, list) and index is not undefined:
- raise SlaveError(_("callback cannot return a list for a "
- "slave option ({0})").format(path))
+ try:
+ if callback_params != {} and isinstance(ret, list) and \
+ option.impl_is_master_slaves('slave'):
+ raise SlaveError(_("callback cannot return a list for a "
+ "slave option ({0})").format(path))
+ except AttributeError:
+ pass
return ret
import weakref
-from tiramisu.error import PropertiesOptionError, ConfigError, ConflictError
-from tiramisu.option import OptionDescription, Option, SymLinkOption, \
+from .error import PropertiesOptionError, ConfigError, ConflictError
+from .option import OptionDescription, Option, SymLinkOption, \
DynSymLinkOption
-from tiramisu.option.baseoption import valid_name
-from tiramisu.setting import groups, Settings, default_encoding, undefined
-from tiramisu.storage import get_storages, get_storage, set_storage, \
+from .option.baseoption import valid_name
+from .setting import groups, Settings, default_encoding, undefined
+from .storage import get_storages, get_storage, set_storage, \
_impl_getstate_setting, get_storages_validation
-from tiramisu.value import Values, Multi
-from tiramisu.i18n import _
+from .value import Values, Multi
+from .i18n import _
class SubConfig(object):
return subpath
def getattr(self, name, force_permissive=False, validate=True,
- _setting_properties=undefined):
+ _setting_properties=undefined, index=None):
"""
attribute notation mechanism for accessing the value of an option
:param name: attribute name
name, force_permissive=force_permissive)
return homeconfig.getattr(name, force_permissive=force_permissive,
validate=validate,
- _setting_properties=_setting_properties)
+ _setting_properties=_setting_properties,
+ index=index)
context = self._cfgimpl_get_context()
option = self.cfgimpl_get_description().__getattr__(name,
context=context)
subpath = self._get_subpath(name)
if isinstance(option, DynSymLinkOption):
- return self.cfgimpl_get_values()._get_cached_item(
+ return self.cfgimpl_get_values()._get_cached_value(
option, path=subpath,
validate=validate,
force_permissive=force_permissive,
- setting_properties=_setting_properties)
+ setting_properties=_setting_properties, index=index)
elif isinstance(option, SymLinkOption): # pragma: no dynoptiondescription cover
path = context.cfgimpl_get_description().impl_get_path_by_opt(
option._impl_getopt())
return context.getattr(path, validate=validate,
force_permissive=force_permissive,
- _setting_properties=_setting_properties)
+ _setting_properties=_setting_properties,
+ index=index)
elif option.impl_is_optiondescription():
self.cfgimpl_get_settings().validate_properties(
option, True, False, path=subpath,
setting_properties=_setting_properties)
return SubConfig(option, self._impl_context, subpath)
else:
- return self.cfgimpl_get_values()._get_cached_item(
+ return self.cfgimpl_get_values()._get_cached_value(
option, path=subpath,
validate=validate,
force_permissive=force_permissive,
- setting_properties=_setting_properties)
+ setting_properties=_setting_properties,
+ index=index)
def find(self, bytype=None, byname=None, byvalue=undefined, type_='option',
check_properties=True, force_permissive=False):
from types import FunctionType
import warnings
-from tiramisu.i18n import _
-from tiramisu.setting import log, undefined
-from tiramisu.autolib import carry_out_calculation
-from tiramisu.error import ConfigError, ValueWarning, PropertiesOptionError,\
+from ..i18n import _
+from ..setting import log, undefined
+from ..autolib import carry_out_calculation
+from ..error import ConfigError, ValueWarning, PropertiesOptionError,\
ContextError
-from tiramisu.storage import get_storages_option
+from ..storage import get_storages_option
StorageBase = get_storages_option('base')
if not isinstance(option, Option): # pragma: optional cover
raise ValueError(_('malformed requirements '
'must be an option in option {0}').format(name))
- if option.impl_is_multi(): # pragma: optional cover
- raise ValueError(_('malformed requirements option {0} '
- 'must not be a multi for {1}').format(
- option.impl_getname(), name))
if expected is not None:
try:
option._validate(expected)
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
# the whole pypy projet is under MIT licence
# ____________________________________________________________
-from tiramisu.i18n import _
-from tiramisu.setting import log, undefined
-from tiramisu.error import SlaveError, ConfigError
+from ..i18n import _
+from ..setting import log, undefined
+from ..error import SlaveError, ConfigError, PropertiesOptionError
from .baseoption import DynSymLinkOption, SymLinkOption, Option
else:
if child.impl_getdefault() != []:
raise ValueError(_("not allowed default value for option {0} "
- "in group {1}").format(child.impl_getname(),
- name))
+ "in group {1}").format(child.impl_getname(),
+ name))
slaves.append(child)
if self.master is None: # pragma: optional cover
raise ValueError(_('master group with wrong'
for slave in self.getslaves(opt):
if not values.is_default_owner(slave, validate_properties=False,
validate_meta=False, index=index):
- values._get_cached_item(slave, validate=False,
- validate_properties=False
- ).pop(index, force=True)
+ values._get_cached_value(slave, validate=False,
+ validate_properties=False
+ ).pop(index, force=True)
pass
def getitem(self, values, opt, path, validate, force_permissive,
force_properties, validate_properties, slave_path=undefined,
- slave_value=undefined, setting_properties=undefined, self_properties=undefined):
+ slave_value=undefined, setting_properties=undefined,
+ self_properties=undefined, index=None):
if self.is_master(opt):
return self._getmaster(values, opt, path, validate,
force_permissive, force_properties,
validate_properties, slave_path,
- slave_value, self_properties)
+ slave_value, self_properties, index)
else:
return self._getslave(values, opt, path, validate,
force_permissive, force_properties,
- validate_properties, setting_properties, self_properties)
+ validate_properties, setting_properties,
+ self_properties, index)
def _getmaster(self, values, opt, path, validate, force_permissive,
force_properties, validate_properties, c_slave_path,
- c_slave_value, self_properties):
+ c_slave_value, self_properties, index):
value = values._get_validated_value(opt, path, validate,
force_permissive,
force_properties,
validate_properties,
- self_properties=self_properties)
- if validate is True:
+ self_properties=self_properties,
+ index=index)
+ if index is None and validate is True:
masterlen = len(value)
for slave in self.getslaves(opt):
try:
slave_path = slave.impl_getpath(values._getcontext())
slavelen = values._p_.get_max_length(slave_path)
- #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,
- # self_properties=self_properties,
- # masterlen=masterlen)
- #slavelen = len(slave_value)
self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
except ConfigError: # pragma: optional cover
pass
def _getslave(self, values, opt, path, validate, force_permissive,
force_properties, validate_properties, setting_properties,
- self_properties):
+ self_properties, index):
"""
if master has length 0:
return []
masterlen = self.get_length(values, opt, validate, undefined,
undefined, force_permissive,
master=master)
- master_is_meta = values._is_meta(opt, masterp)
- #value = values._get_validated_value(opt, path, validate,
- # force_permissive,
- # force_properties,
- # validate_properties,
- # None, # not undefined
- # with_meta=master_is_meta,
- # self_properties=self_properties)
- #if slave, had values until master's one
- #path = opt.impl_getpath(context)
- #valuelen = len(value)
- #if validate:
- # self.validate_slave_length(masterlen, valuelen,
- # opt.impl_getname(), opt)
- #if valuelen < masterlen:
-
- #FIXME voir si pas de plus grande valeur !
- value = values._get_multi(opt, path)
- for index in range(0, masterlen):
- #index = valuelen + num
- value.append(values._get_validated_value(opt, path, validate,
+ master_is_meta = values._is_meta(master, masterp)
+ multi = values._get_multi(opt, path)
+ if masterlen == 0:
+ if validate_properties:
+ context.cfgimpl_get_settings().validate_properties(opt, False,
+ False,
+ value=multi,
+ path=path,
+ force_permissive=force_permissive,
+ force_properties=force_properties,
+ setting_properties=setting_properties)
+ else:
+ one_has_value = False
+ if index is None:
+ indexes = range(0, masterlen)
+ else:
+ indexes = [index]
+ for idx in indexes:
+ try:
+ value = values._get_cached_value(opt, path, validate,
force_permissive, force_properties,
validate_properties,
with_meta=master_is_meta,
- index=index,
- self_properties=self_properties,
- masterlen=masterlen),
- setitem=False,
- force=True,
- validate=validate)
- #FIXME hu?
- if validate_properties:
- context.cfgimpl_get_settings().validate_properties(opt, False,
- False,
- value=value,
- path=path,
- force_permissive=force_permissive,
- force_properties=force_properties,
- setting_properties=setting_properties)
- return value
+ index=idx,
+ # not self_properties,
+ # depends to index
+ #self_properties=self_properties,
+ masterlen=masterlen,
+ from_masterslave=True)
+ multi.append(value, setitem=False, force=True, validate=validate)
+ one_has_value = True
+ except PropertiesOptionError, err:
+ multi.append_properties_error(err)
+ if not one_has_value:
+ #raise last err
+ raise err
+ return multi
def setitem(self, values, opt, value, path):
if self.is_master(opt):
slave_path = base_path + slave.impl_getname()
slavelen = values._p_.get_max_length(slave_path)
self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
- #slave_value = values._get_validated_value(slave,
- # slave_path,
- # False,
- # False,
- # None, False,
- # None,
- # masterlen=masterlen) # not undefined
- #slavelen = len(slave_value)
- #self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
else:
self.validate_slave_length(self.get_length(values, opt,
slave_path=path), len(value),
import sys
from IPy import IP
from types import FunctionType
-from tiramisu.setting import log, undefined
+from ..setting import log, undefined
-from tiramisu.error import ConfigError, ContextError
-from tiramisu.i18n import _
+from ..error import ConfigError, ContextError
+from ..i18n import _
from .baseoption import Option, validate_callback
-from tiramisu.autolib import carry_out_calculation
+from ..autolib import carry_out_calculation
class ChoiceOption(Option):
import re
-from tiramisu.i18n import _
-from tiramisu.setting import groups, undefined # , log
+from ..i18n import _
+from ..setting import groups, undefined # , log
from .baseoption import BaseOption, SymLinkOption, allowed_character
from . import MasterSlaves
-from tiramisu.error import ConfigError, ConflictError
-from tiramisu.storage import get_storages_option
-from tiramisu.autolib import carry_out_calculation
+from ..error import ConfigError, ConflictError
+from ..storage import get_storages_option
+from ..autolib import carry_out_calculation
StorageOptionDescription = get_storages_option('optiondescription')
option._set_readonly()
if isinstance(option, OptionDescription):
option.impl_validate_options(cache_option)
+ if option.impl_getrequires() != []:
+ for requires in option.impl_getrequires():
+ for require in requires:
+ if require[0].impl_is_multi():
+ if option.impl_is_master_slaves('slave') and require[0].impl_is_master_slaves():
+ if option.impl_get_master_slaves() != require[0].impl_get_master_slaves():
+ raise ValueError(_('malformed requirements option {0} '
+ 'must be in same master/slaves for {1}').format(
+ require[0].impl_getname(), option.impl_getname()))
+ else:
+ raise ValueError(_('malformed requirements option {0} '
+ 'must not be a multi for {1}').format(
+ require[0].impl_getname(), option.impl_getname()))
if init:
if len(cache_option) != len(set(cache_option)):
for idx in xrange(1, len(cache_option) + 1):
from copy import copy
from logging import getLogger
import weakref
-from tiramisu.error import (RequirementError, PropertiesOptionError,
- ConstError, ConfigError)
-from tiramisu.i18n import _
+from .error import (RequirementError, PropertiesOptionError,
+ ConstError, ConfigError)
+from .i18n import _
"Default encoding for display a Config if raise UnicodeEncodeError"
def _getproperties(self, opt=None, path=None,
setting_properties=undefined, read_write=True,
- apply_requires=True):
+ apply_requires=True, index=None):
"""
"""
if opt is None:
ntime = int(time())
else:
ntime = None
- if 'cache' in setting_properties and self._p_.hascache(path):
- is_cached, props = self._p_.getcache(path, ntime)
+ if 'cache' in setting_properties and self._p_.hascache(path, index):
+ is_cached, props = self._p_.getcache(path, ntime, index)
if not is_cached:
props = self._p_.getproperties(path, opt.impl_getproperties())
if apply_requires:
props = copy(props)
- props |= self.apply_requires(opt, path, setting_properties)
+ props |= self.apply_requires(opt, path, setting_properties, index)
if 'cache' in setting_properties:
if 'expire' in setting_properties:
ntime = ntime + expires_time
- self._p_.setcache(path, props, ntime)
+ self._p_.setcache(path, props, ntime, index)
if read_write:
props = copy(props)
return props
properties = copy(self_properties)
else:
properties = self._getproperties(opt_or_descr, path,
- setting_properties=setting_properties)
+ setting_properties=setting_properties,
+ index=index)
# remove opt permissive
# permissive affect option's permission with or without permissive
# global property
else:
self._p_.reset_all_cache()
- def apply_requires(self, opt, path, setting_properties):
+ def apply_requires(self, opt, path, setting_properties, index):
"""carries out the jit (just in time) requirements between options
a requirement is a tuple of this form that comes from the option's
"'{1}'").format(path, reqpath))
try:
value = context.getattr(reqpath, force_permissive=True,
- _setting_properties=setting_properties)
+ _setting_properties=setting_properties,
+ index=index)
except PropertiesOptionError as err:
if not transitive:
continue
from time import time
from random import randint
import os
-from tiramisu.error import ConfigError
-from tiramisu.i18n import _
+from ..error import ConfigError
+from ..i18n import _
+
+
+MODULE_PATH = os.path.split(os.path.split(os.path.split(__file__)[0])[0])[1]
class StorageType(object):
if self.storage_type is None:
self.storage_type = self.default_storage
if self.mod is None:
- modulepath = 'tiramisu.storage.{0}'.format(self.storage_type)
+ modulepath = '{0}.storage.{1}'.format(MODULE_PATH, self.storage_type)
try:
mod = __import__(modulepath)
except ImportError:
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ____________________________________________________________
-from tiramisu.i18n import _
-from tiramisu.setting import undefined
-from tiramisu.error import ConfigError
+from ...i18n import _
+from ...setting import undefined
+from ...error import ConfigError
#____________________________________________________________
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
-from tiramisu.i18n import _
-from tiramisu.error import ConfigError
+from ...i18n import _
+from ...error import ConfigError
from ..util import SerializeObject
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
from ..util import Cache
-from tiramisu.setting import undefined
+from ...setting import undefined
class Values(Cache):
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________
-from tiramisu.setting import owners
+from ..setting import owners
class SerializeObject(object):
value = tuple(_value)
setattr(self, key, value)
- def setcache(self, path, val, time):
- self._cache[path] = (val, time)
+ def setcache(self, path, val, time, index):
+ self._cache.setdefault(path, {})[index] = (val, time)
- def getcache(self, path, exp):
- value, created = self._cache[path]
+ def getcache(self, path, exp, index):
+ value, created = self._cache[path][index]
if created is None or exp <= created:
return True, value
return False, None
- def hascache(self, path):
+ def hascache(self, path, index):
""" path is in the cache
:param path: the path's option
"""
- return path in self._cache
+ return path in self._cache and index in self._cache[path]
def reset_expired_cache(self, exp):
- for key in tuple(self._cache.keys()):
- val, created = self._cache[key]
- if created is not None and exp > created:
- del(self._cache[key])
+ for key in self._cache.keys():
+ for index in self._cache[key].keys():
+ val, created = self._cache[key][index]
+ if created is not None and exp > created:
+ del(self._cache[key][index])
+ if self._cache[key] == {}:
+ del(self._cache[key])
def reset_all_cache(self):
"empty the cache"
def get_cached(self, context):
"""return all values in a dictionary
- example: {'path1': ('value1', 'time1'), 'path2': ('value2', 'time2')}
+ example: {'path1': {'index1': ('value1', 'time1')}, 'path2': {'index2': ('value2', 'time2', )}}
"""
return self._cache
from time import time
import sys
import weakref
-from tiramisu.error import ConfigError, SlaveError, PropertiesOptionError
-from tiramisu.setting import owners, expires_time, undefined
-from tiramisu.autolib import carry_out_calculation
-from tiramisu.i18n import _
-from tiramisu.option import SymLinkOption, DynSymLinkOption, Option
+from .error import ConfigError, SlaveError, PropertiesOptionError
+from .setting import owners, expires_time, undefined
+from .autolib import carry_out_calculation
+from .i18n import _
+from .option import SymLinkOption, DynSymLinkOption, Option
class Values(object):
callback=callback,
callback_params=callback_params,
index=index)
- if isinstance(value, list) and index is not undefined:
+ if isinstance(value, list) and index is not None:
#if return a list and index is set, return value only if
#it's a submulti without submulti_index and without list of list
if opt.impl_is_submulti() and submulti_index is undefined and \
if meta is not None:
try:
value = meta.cfgimpl_get_values(
- )._get_cached_item(opt, path)
+ )._get_cached_value(opt, path, index=index, from_masterslave=True)
if isinstance(value, Multi):
- if index is not undefined:
+ if index is not None:
value = value[index]
else:
value = list(value)
pass
# now try to get default value
value = opt.impl_getdefault()
- if opt.impl_is_multi() and index is not undefined:
+ if opt.impl_is_multi() and index is not None:
if value == []:
value = opt.impl_getdefault_multi()
else:
return self._p_.getvalue(path, index)
else:
value = self._p_.getvalue(path)
- if index is not undefined:
+ if index is not None:
try:
return value[index]
except IndexError:
def getitem(self, opt, validate=True, force_permissive=False):
"""
"""
- return self._get_cached_item(opt, validate=validate,
- force_permissive=force_permissive)
-
- def _get_cached_item(self, opt, path=None, validate=True,
- force_permissive=False, force_properties=None,
- validate_properties=True,
- setting_properties=undefined, self_properties=undefined):
+ return self._get_cached_value(opt, validate=validate,
+ force_permissive=force_permissive)
+
+ def _get_cached_value(self, opt, path=None, validate=True,
+ force_permissive=False, force_properties=None,
+ validate_properties=True,
+ setting_properties=undefined, self_properties=undefined,
+ index=None, from_masterslave=False, with_meta=True,
+ masterlen=undefined):
untrusted_cached_properties = force_properties is None
context = self._getcontext()
if path is None:
)._getproperties(read_write=False)
if self_properties is undefined:
self_properties = context.cfgimpl_get_settings()._getproperties(
- opt, path, read_write=False, setting_properties=setting_properties)
- if 'cache' in setting_properties and self._p_.hascache(path):
+ opt, path, read_write=False,
+ setting_properties=setting_properties, index=index)
+ if 'cache' in setting_properties and self._p_.hascache(path, index):
if 'expire' in setting_properties:
ntime = int(time())
- is_cached, value = self._p_.getcache(path, ntime)
+ is_cached, value = self._p_.getcache(path, ntime, index)
if is_cached:
- if opt.impl_is_multi() and not isinstance(value, Multi):
+ if opt.impl_is_multi() and not isinstance(value, Multi) and index is None:
value = Multi(value, self.context, opt, path)
if not untrusted_cached_properties:
# revalidate properties (because not default properties)
force_permissive=force_permissive,
force_properties=force_properties,
setting_properties=setting_properties,
- self_properties=self_properties)
+ self_properties=self_properties,
+ index=index)
return value
- val = self._getitem(opt, path, validate, force_permissive,
- force_properties, validate_properties,
- setting_properties, self_properties=self_properties)
- if 'cache' in setting_properties and validate and validate_properties \
+ if not from_masterslave and opt.impl_is_master_slaves():
+ val = opt.impl_get_master_slaves().getitem(self, opt, path,
+ validate,
+ force_permissive,
+ force_properties,
+ validate_properties,
+ setting_properties=setting_properties,
+ index=index,
+ self_properties=self_properties)
+ else:
+ val = self._get_validated_value(opt, path, validate,
+ force_permissive,
+ force_properties,
+ validate_properties,
+ setting_properties=setting_properties,
+ self_properties=self_properties,
+ with_meta=with_meta,
+ masterlen=masterlen,
+ index=index)
+ # cache doesn't work with SubMulti yet
+ if not isinstance(val, SubMulti) and 'cache' in setting_properties and validate and validate_properties \
and force_permissive is False and force_properties is None:
if 'expire' in setting_properties:
if ntime is None:
ntime = int(time())
ntime = ntime + expires_time
- self._p_.setcache(path, val, ntime)
+ self._p_.setcache(path, val, ntime, index)
return val
- def _getitem(self, opt, path, validate, force_permissive, force_properties,
- validate_properties, setting_properties=undefined,
- self_properties=undefined):
- if opt.impl_is_master_slaves():
- return opt.impl_get_master_slaves().getitem(self, opt, path,
- validate,
- force_permissive,
- force_properties,
- validate_properties,
- setting_properties=setting_properties,
- self_properties=self_properties)
- else:
- return self._get_validated_value(opt, path, validate,
- force_permissive,
- force_properties,
- validate_properties,
- setting_properties=setting_properties,
- self_properties=self_properties)
-
def _get_validated_value(self, opt, path, validate, force_permissive,
force_properties, validate_properties,
- index=undefined, submulti_index=undefined,
+ index=None, submulti_index=undefined,
with_meta=True, setting_properties=undefined,
self_properties=undefined, masterlen=undefined):
"""same has getitem but don't touch the cache
if setting_properties is undefined:
setting_properties = setting._getproperties(read_write=False)
if self_properties is undefined:
- self_properties = setting._getproperties(opt, path, read_write=False)
+ self_properties = setting._getproperties(opt, path, read_write=False, index=index)
is_default = self._is_default_owner(opt, path,
validate_properties=False,
validate_meta=False,
if 'frozen' in self_properties and 'force_default_on_freeze' in self_properties:
return owners.default
if validate_properties:
- self._getitem(opt, path, True, force_permissive, None, True,
- self_properties=self_properties)
+ self._get_cached_value(opt, path, True, force_permissive, None, True,
+ self_properties=self_properties)
owner = self._p_.getowner(path, owners.default, only_default=only_default, index=index)
if validate_meta is undefined:
if opt.impl_is_master_slaves('slave'):
setting_properties=setting_properties)
if 'mandatory' in self_properties:
try:
- self._get_cached_item(true_opt, path=true_path,
- force_properties=frozenset(('mandatory',)),
- force_permissive=force_permissive,
- setting_properties=setting_properties,
- self_properties=self_properties,
- validate=validate)
+ self._get_cached_value(true_opt, path=true_path,
+ force_properties=frozenset(('mandatory',)),
+ force_permissive=force_permissive,
+ setting_properties=setting_properties,
+ self_properties=self_properties,
+ validate=validate)
except PropertiesOptionError as err:
if err.proptype == ['mandatory']:
yield path
setting_properties = setting._getproperties(read_write=False)
if 'validator' in setting_properties and validate:
fake_context = context._gen_fake_values()
- fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
+ fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
self.opt, path=self.path, validate=False)
fake_multi._setitem(index, value, validate=False)
self._validate(value, fake_context, index, True)
#def __repr__(self, *args, **kwargs):
# return super(Multi, self).__repr__(*args, **kwargs)
- #def __getitem__(self, y):
- # return super(Multi, self).__getitem__(y)
+ def __getitem__(self, index):
+ value = super(Multi, self).__getitem__(index)
+ if isinstance(value, PropertiesOptionError):
+ raise value
+ return value
def _get_validated_value(self, index):
values = self._getcontext().cfgimpl_get_values()
index = self.__len__()
if value is undefined:
value = self._get_validated_value(index)
- context = self._getcontext()
- setting = context.cfgimpl_get_settings()
- setting_properties = setting._getproperties(read_write=False)
- if 'validator' in setting_properties and validate and value not in [None, undefined]:
- fake_context = context._gen_fake_values()
- fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
- self.opt, path=self.path, validate=False)
- fake_multi.append(value, validate=False, force=True)
- self._validate(value, fake_context, index, True)
+ if validate and value not in [None, undefined]:
+ context = self._getcontext()
+ setting = context.cfgimpl_get_settings()
+ setting_properties = setting._getproperties(read_write=False)
+ if 'validator' in setting_properties:
+ fake_context = context._gen_fake_values()
+ fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
+ self.opt, path=self.path, validate=False)
+ fake_multi.append(value, validate=False, force=True)
+ self._validate(value, fake_context, index, True)
if not '_index' in self.__slots__ and self.opt.impl_is_submulti():
if not isinstance(value, SubMulti):
value = SubMulti(value, self.context, self.opt, self.path, index)
if setitem:
self._store(force=force)
+ def append_properties_error(self, err):
+ super(Multi, self).append(err)
+
def sort(self, cmp=None, key=None, reverse=False):
if self.opt.impl_is_master_slaves():
raise SlaveError(_("cannot sort multi option {0} if master or slave"
setting_properties = setting._getproperties(read_write=False)
if 'validator' in setting_properties and validate and value is not None:
fake_context = context._gen_fake_values()
- fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
+ fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
self.opt, path=self.path, validate=False)
fake_multi.insert(index, value, validate=False)
self._validate(value, fake_context, index, True)
setting_properties = setting._getproperties(read_write=False)
if 'validator' in setting_properties and validate:
fake_context = context._gen_fake_values()
- fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
+ fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
self.opt, path=self.path, validate=False)
fake_multi.extend(iterable, validate=False)
self._validate(iterable, fake_context, index)