Compare commits

...

13 Commits

36 changed files with 1204 additions and 423 deletions

View File

@ -1,3 +1,12 @@
Tue Mar 5 08:22:12 2018 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc2
* simplifying netmaskoption
* multiple option call (fixes #1)
* doesn't check follower requirement with an other follower or a leader if idx is None (fixes #3)
Mon Feb 25 10:12:35 2018 +0200 Emmanuel Garette <egarette@cadoles.com>
* version 3.0 rc1
Sat Sep 8 22:54:12 2018 +0200 Emmanuel Garette <egarette@cadoles.com>
* propose a new API to access to Tiramisu Option
This new API is totally incompatible with older's one

View File

@ -83,30 +83,34 @@ def _autocheck_default_value(cfg, path, conf, **kwargs):
# test default value (should be empty)
# cannot test for follower (we cannot get all values for a follower)
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
with warnings.catch_warnings(record=True) as w:
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(path).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path).value.get() == empty_value
assert cfg_.option(path).value.get() == empty_value
assert cfg_.forcepermissive.option(path).value.get() == empty_value
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(path).value.get()")
assert cfg.config(conf).forcepermissive.option(path).value.get() == empty_value
raises(PropertiesOptionError, "cfg_.option(path).value.get()")
assert cfg_.forcepermissive.option(path).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(path).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(path).value.get()")
raises(PropertiesOptionError, "cfg_.option(path).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(path).value.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(path, 0).value.get() == empty_value
assert cfg.config(conf).option(path, 1).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path, 1).value.get() == empty_value
assert cfg_.option(path, 0).value.get() == empty_value
assert cfg_.option(path, 1).value.get() == empty_value
assert cfg_.forcepermissive.option(path, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(path, 1).value.get() == empty_value
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(path, 0).value.get()")
assert cfg.config(conf).forcepermissive.option(path, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(path, 1).value.get() == empty_value
raises(PropertiesOptionError, "cfg_.option(path, 0).value.get()")
assert cfg_.forcepermissive.option(path, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(path, 1).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(path, 0).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(path, 0).value.get()")
raises(PropertiesOptionError, "cfg_.option(path, 0).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(path, 0).value.get()")
def _set_value(cfg, pathwrite, conf, **kwargs):
@ -131,52 +135,56 @@ def _set_value(cfg, pathwrite, conf, **kwargs):
# for follower should have an index and good length
# for leader must append, not set
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
with warnings.catch_warnings(record=True) as w:
if isleader:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
raises(APIError, "cfg.config(conf).option(pathwrite, 0).value.set(first_value[0])")
raises(APIError, "cfg_.option(pathwrite, 0).value.set(first_value[0])")
if not set_permissive:
cfg.config(conf).option(pathwrite).value.set([first_value[0]])
cfg_.option(pathwrite).value.set([first_value[0]])
else:
cfg.config(conf).forcepermissive.option(pathwrite).value.set([first_value[0]])
cfg_.forcepermissive.option(pathwrite).value.set([first_value[0]])
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set([first_value[0]])")
if set_permissive:
cfg.config(conf).forcepermissive.option(pathwrite).value.set([first_value[0]])
cfg_.forcepermissive.option(pathwrite).value.set([first_value[0]])
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set([first_value[0]])")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathwrite).value.set([first_value[0]])")
if len(first_value) > 1:
raises(APIError, "cfg.config(conf).unrestraint.option(pathwrite).value.set(first_value[1])")
raises(APIError, "cfg_.unrestraint.option(pathwrite).value.set(first_value[1])")
elif isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if not set_permissive:
cfg.config(conf).option(pathwrite, 1).value.set(second_value)
cfg_.option(pathwrite, 1).value.set(second_value)
else:
cfg.config(conf).forcepermissive.option(pathwrite, 1).value.set(second_value)
cfg_.forcepermissive.option(pathwrite, 1).value.set(second_value)
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite, 1).value.set(second_value)")
raises(PropertiesOptionError, "cfg_.option(pathwrite, 1).value.set(second_value)")
if set_permissive:
cfg.config(conf).forcepermissive.option(pathwrite, 1).value.set(second_value)
cfg_.forcepermissive.option(pathwrite, 1).value.set(second_value)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite, 1).value.set(second_value)")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathwrite, 1).value.set(second_value)")
raises(APIError, "cfg.config(conf).unrestraint.option(pathwrite).value.set([second_value, second_value])")
raises(PropertiesOptionError, "cfg_.option(pathwrite, 1).value.set(second_value)")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathwrite, 1).value.set(second_value)")
raises(APIError, "cfg_.unrestraint.option(pathwrite).value.set([second_value, second_value])")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if not set_permissive:
cfg.config(conf).option(pathwrite).value.set(first_value)
cfg_.option(pathwrite).value.set(first_value)
else:
cfg.config(conf).forcepermissive.option(pathwrite).value.set(first_value)
cfg_.forcepermissive.option(pathwrite).value.set(first_value)
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set(first_value)")
if set_permissive:
cfg.config(conf).forcepermissive.option(pathwrite).value.set(first_value)
cfg_.forcepermissive.option(pathwrite).value.set(first_value)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathwrite).value.set(first_value)")
#FIXME raises(APIError, "cfg.config(conf).unrestraint.option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg_.option(pathwrite).value.set(first_value)")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathwrite).value.set(first_value)")
#FIXME raises(APIError, "cfg_.unrestraint.option(pathwrite).value.set(first_value)")
def _getproperties(multi, isfollower, kwargs):
@ -195,37 +203,41 @@ def _getproperties(multi, isfollower, kwargs):
def _check_properties(cfg, mcfg, pathread, conf, kwargs, props_permissive, props):
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not cfg.unrestraint.option(pathread).option.isfollower():
if not kwargs.get('permissive_od', False):
assert set(cfg.config(conf).option(pathread).property.get()) == set(props_permissive)
assert set(cfg.config(conf).option(pathread).property.get()) == set(props)
assert set(cfg_.option(pathread).property.get()) == set(props_permissive)
assert set(cfg_.option(pathread).property.get()) == set(props)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).property.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).property.get()")
assert set(cfg.config(conf).forcepermissive.option(pathread).property.get()) == set(props_permissive)
assert set(cfg.config(conf).forcepermissive.option(pathread).property.get()) == set(props)
assert set(cfg.config(conf).unrestraint.option(pathread).property.get()) == set(props_permissive)
assert set(cfg.config(conf).unrestraint.option(pathread).property.get()) == set(props)
raises(PropertiesOptionError, "cfg_.option(pathread).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).property.get()")
assert set(cfg_.forcepermissive.option(pathread).property.get()) == set(props_permissive)
assert set(cfg_.forcepermissive.option(pathread).property.get()) == set(props)
assert set(cfg_.unrestraint.option(pathread).property.get()) == set(props_permissive)
assert set(cfg_.unrestraint.option(pathread).property.get()) == set(props)
else:
if not kwargs.get('permissive_od', False):
assert set(cfg.config(conf).option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg.config(conf).option(pathread, 0).property.get()) == set(props)
assert set(cfg_.option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg_.option(pathread, 0).property.get()) == set(props)
#
assert set(cfg.config(conf).option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg.config(conf).option(pathread, 1).property.get()) == set(props)
assert set(cfg_.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg_.option(pathread, 1).property.get()) == set(props)
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).property.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).property.get()")
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 1).property.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 1).property.get()")
assert set(cfg.config(conf).forcepermissive.option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg.config(conf).forcepermissive.option(pathread, 0).property.get()) == set(props)
raises(PropertiesOptionError, "cfg_.option(pathread, 1).property.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 1).property.get()")
assert set(cfg_.forcepermissive.option(pathread, 0).property.get()) == set(props_permissive)
assert set(cfg_.forcepermissive.option(pathread, 0).property.get()) == set(props)
#
assert set(cfg.config(conf).forcepermissive.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg.config(conf).forcepermissive.option(pathread, 1).property.get()) == set(props)
assert set(cfg.config(conf).unrestraint.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg.config(conf).unrestraint.option(pathread, 1).property.get()) == set(props)
assert set(cfg_.forcepermissive.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg_.forcepermissive.option(pathread, 1).property.get()) == set(props)
assert set(cfg_.unrestraint.option(pathread, 1).property.get()) == set(props_permissive)
assert set(cfg_.unrestraint.option(pathread, 1).property.get()) == set(props)
def _property_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs):
@ -253,12 +265,16 @@ def _property_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
# set properties with permissive
for prop in properties:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confread).option(pathwrite).property.add(prop)
elif not kwargs.get('propertyerror', False):
cfg.config(confread).forcepermissive.option(pathwrite).property.add(prop)
if confread is not None:
cfg_ = cfg.config(confread)
else:
cfg.config(confread).unrestraint.option(pathwrite).property.add(prop)
cfg_ = cfg
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg_.option(pathwrite).property.add(prop)
elif not kwargs.get('propertyerror', False):
cfg_.forcepermissive.option(pathwrite).property.add(prop)
else:
cfg_.unrestraint.option(pathwrite).property.add(prop)
if confwrite == confread:
_check_properties(cfg, mcfg, pathread, confwrite, kwargs, properties, properties)
else:
@ -286,64 +302,72 @@ def _autocheck_get_value(cfg, pathread, conf, **kwargs):
second_value = SUBLIST_SECOND_VALUE[1]
# get value after set value without permissive
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
with warnings.catch_warnings(record=True) as w:
if isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).option(pathread, 1).value.get() == second_value
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == second_value
assert cfg_.option(pathread, 0).value.get() == empty_value
assert cfg_.option(pathread, 1).value.get() == second_value
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == second_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
raises(PropertiesOptionError, "cfg_.option(pathread, 0).value.get()")
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
if set_permissive:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == second_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == second_value
else:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).value.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).value.get() == first_value
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
assert cfg_.option(pathread).value.get() == first_value
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
if set_permissive:
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
else:
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread).value.get() == empty_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).value.get()")
def _check_owner(cfg, pathread, conf, kwargs, owner, permissive_owner):
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).owner.get() == owner
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == owner
assert cfg_.option(pathread).owner.get() == owner
assert cfg_.forcepermissive.option(pathread).owner.get() == owner
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == permissive_owner
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
assert cfg_.forcepermissive.option(pathread).owner.get() == permissive_owner
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).owner.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).option(pathread, 1).owner.get() == owner
assert cfg.config(conf).forcepermissive.option(pathread, 1).owner.get() == owner
assert cfg_.option(pathread, 0).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg_.option(pathread, 1).owner.get() == owner
assert cfg_.forcepermissive.option(pathread, 1).owner.get() == owner
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 1).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread, 1).owner.get() == permissive_owner
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 1).owner.get()")
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread, 1).owner.get() == permissive_owner
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).owner.get()")
@autocheck
@ -373,49 +397,53 @@ def autocheck_default_owner(cfg, mcfg, pathread, pathwrite, confread, confwrite,
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
# check if owner is a string "default" and 'isdefault'
def do(conf):
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == 'default'
assert cfg_.option(pathread).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread).owner.get() == 'default'
#
assert cfg.config(conf).option(pathread).owner.isdefault()
assert cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()
assert cfg_.option(pathread).owner.isdefault()
assert cfg_.forcepermissive.option(pathread).owner.isdefault()
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread).owner.get() == 'default'
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
assert cfg_.forcepermissive.option(pathread).owner.get() == 'default'
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.isdefault()")
assert cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()
raises(PropertiesOptionError, "cfg_.option(pathread).owner.isdefault()")
assert cfg_.forcepermissive.option(pathread).owner.isdefault()
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).owner.get()")
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).owner.isdefault()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()")
raises(PropertiesOptionError, "cfg_.option(pathread).owner.isdefault()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).owner.isdefault()")
#
assert cfg.config(conf).unrestraint.option(pathread).owner.get() == 'default'
assert cfg.config(conf).unrestraint.option(pathread).owner.isdefault()
assert cfg_.unrestraint.option(pathread).owner.get() == 'default'
assert cfg_.unrestraint.option(pathread).owner.isdefault()
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
assert cfg_.option(pathread, 0).owner.get() == 'default'
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
#
assert cfg.config(conf).option(pathread, 0).owner.isdefault()
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault()
assert cfg_.option(pathread, 0).owner.isdefault()
assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault()
elif not kwargs.get('propertyerror', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.get() == 'default'
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
assert cfg_.forcepermissive.option(pathread, 0).owner.get() == 'default'
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.isdefault()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault()
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.isdefault()")
assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault()
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).owner.get()")
#
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).owner.isdefault()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault()")
assert cfg.config(conf).unrestraint.option(pathread, 0).owner.get() == 'default'
assert cfg.config(conf).unrestraint.option(pathread, 0).owner.isdefault()
raises(PropertiesOptionError, "cfg_.option(pathread, 0).owner.isdefault()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread, 0).owner.isdefault()")
assert cfg_.unrestraint.option(pathread, 0).owner.get() == 'default'
assert cfg_.unrestraint.option(pathread, 0).owner.isdefault()
do(confread)
if confread != confwrite:
do(confwrite)
@ -450,40 +478,44 @@ def autocheck_get_value_permissive(cfg, mcfg, pathread, pathwrite, confread, con
def do(conf):
# get value after set value without permissive
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg_.option(pathread, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
if submulti_:
assert cfg.config(conf).option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg_.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
else:
assert cfg.config(conf).option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg_.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 1).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
raises(PropertiesOptionError, "assert cfg_.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg_.option(pathread, 1).value.get()")
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
if submulti_:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == SUBLIST_SECOND_VALUE[1]
else:
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
assert cfg_.forcepermissive.option(pathread, 1).value.get() == LIST_SECOND_VALUE[1]
else:
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).option(pathread, 1).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get()")
raises(PropertiesOptionError, "assert cfg_.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg_.option(pathread, 1).value.get()")
raises(PropertiesOptionError, "assert cfg_.forcepermissive.option(pathread, 0).value.get()")
raises(PropertiesOptionError, "assert cfg_.forcepermissive.option(pathread, 1).value.get()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
with warnings.catch_warnings(record=True) as w:
assert cfg.config(conf).option(pathread).value.get() == first_value
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
assert cfg_.option(pathread).value.get() == first_value
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
else:
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
raises(PropertiesOptionError, "cfg_.forcepermissive.option(pathread).value.get()")
with warnings.catch_warnings(record=True) as w:
do(confread)
if confread != confwrite:
@ -515,8 +547,12 @@ def autocheck_value_follower(cfg, mcfg, pathread, pathwrite, confread, confwrite
empty_value = kwargs['default']
def do(conf):
length = cfg.config(conf).option(pathread).value.len()
assert cfg.config(conf).forcepermissive.option(pathread).value.len() == length
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
length = cfg_.option(pathread).value.len()
assert cfg_.forcepermissive.option(pathread).value.len() == length
assert length == 2
do(confread)
if confread != confwrite:
@ -567,33 +603,41 @@ def autocheck_reset_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, *
# reset value without permissive
with warnings.catch_warnings(record=True) as w:
if confwrite is not None:
cfg_ = cfg.config(confwrite)
else:
cfg_ = cfg
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confwrite).option(pathwrite).value.reset()
cfg_.option(pathwrite).value.reset()
#else:
#FIXME raises(PropertiesOptionError, "cfg.config(confwrite).option(pathwrite).value.reset()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confwrite).option(pathwrite, 0).value.reset()
cfg_.option(pathwrite, 0).value.reset()
#else:
#FIXME raises(PropertiesOptionError, "cfg.config(confwrite).option(pathwrite, 0).value.reset()")
# get value after reset value without permissive
def do(conf):
if confwrite is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).option(pathread, 1).value.get() == second_value[1]
assert cfg_.option(pathread, 0).value.get() == empty_value
assert cfg_.option(pathread, 1).value.get() == second_value[1]
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread, 0).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg.config(conf).forcepermissive.option(pathread, 1).value.get() == second_value[1]
raises(PropertiesOptionError, "cfg_.option(pathread, 0).value.get()")
assert cfg_.forcepermissive.option(pathread, 0).value.get() == empty_value
assert cfg_.forcepermissive.option(pathread, 1).value.get() == second_value[1]
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(conf).option(pathread).value.get() == empty_value
assert cfg_.option(pathread).value.get() == empty_value
elif kwargs.get('permissive', False):
raises(PropertiesOptionError, "cfg.config(conf).option(pathread).value.get()")
assert cfg.config(conf).forcepermissive.option(pathread).value.get() == first_value
raises(PropertiesOptionError, "cfg_.option(pathread).value.get()")
assert cfg_.forcepermissive.option(pathread).value.get() == first_value
with warnings.catch_warnings(record=True) as w:
do(confread)
if confread != confwrite:
@ -606,16 +650,24 @@ def autocheck_append_value(cfg, mcfg, pathread, pathwrite, confread, confwrite,
submulti_ = cfg.unrestraint.option(pathread).option.issubmulti()
if not isleader:
return
if confread is not None:
cfg_ = cfg.config(confread)
else:
cfg_ = cfg
if confwrite is not None:
cfg2_ = cfg.config(confwrite)
else:
cfg2_ = cfg
with warnings.catch_warnings(record=True) as w:
if not kwargs.get('propertyerror', False):
leader_value = cfg.config(confread).forcepermissive.option(pathread).value.get()
leader_value = cfg_.forcepermissive.option(pathread).value.get()
len_value = len(leader_value)
leader_value.append(undefined)
assert len(cfg.config(confread).forcepermissive.option(pathread).value.get()) == len_value
assert len(cfg_.forcepermissive.option(pathread).value.get()) == len_value
with warnings.catch_warnings(record=True) as w:
cfg.forcepermissive.config(confwrite).option(pathread).value.set(leader_value)
new_leader_value = cfg.config(confread).forcepermissive.option(pathread).value.get()
cfg2_.forcepermissive.option(pathread).value.set(leader_value)
new_leader_value = cfg_.forcepermissive.option(pathread).value.get()
len_new = len(new_leader_value)
assert len_value + 1 == len_new
assert new_leader_value[-1] == kwargs['default_multi']
@ -625,16 +677,16 @@ def autocheck_append_value(cfg, mcfg, pathread, pathwrite, confread, confwrite,
else:
follower_path += '.third'
for idx in range(len_new):
assert cfg.config(confread).forcepermissive.option(follower_path, idx).value.get() == kwargs['default_multi']
assert cfg_.forcepermissive.option(follower_path, idx).value.get() == kwargs['default_multi']
#
if not submulti_:
value = 'value'
else:
value = ['value']
leader_value.append(value)
assert len(cfg.config(confread).forcepermissive.option(pathread).value.get()) == len(new_leader_value)
cfg.forcepermissive.config(confwrite).option(pathread).value.set(leader_value)
assert cfg.config(confread).forcepermissive.option(pathread).value.get()[-1] == value
assert len(cfg_.forcepermissive.option(pathread).value.get()) == len(new_leader_value)
cfg2_.forcepermissive.option(pathread).value.set(leader_value)
assert cfg_.forcepermissive.option(pathread).value.get()[-1] == value
@autocheck
@ -644,6 +696,14 @@ def autocheck_pop_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, **k
if not isleader:
return
if confwrite is not None:
cfg_ = cfg.config(confwrite)
else:
cfg_ = cfg
if confread is not None:
cfg2_ = cfg.config(confread)
else:
cfg2_ = cfg
if not kwargs.get('propertyerror', False):
if not submulti_:
values = ['value1', 'value2', 'value3', 'value4']
@ -658,34 +718,34 @@ def autocheck_pop_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, **k
else:
a_follower += '.third'
with warnings.catch_warnings(record=True) as w:
cfg.forcepermissive.config(confwrite).option(pathread).value.set(values)
cfg.forcepermissive.config(confwrite).option(a_follower, 1).value.set(follower_value)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg.config(confread).forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg.config(confread).forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg.config(confread).forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 2).owner.isdefault() is True
cfg.config(confread).forcepermissive.option(a_follower, 3).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 3).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.set(values)
cfg_.forcepermissive.option(a_follower, 1).value.set(follower_value)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg2_.forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg2_.forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg2_.forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 2).owner.isdefault() is True
cfg2_.forcepermissive.option(a_follower, 3).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 3).owner.isdefault() is True
#
cfg.forcepermissive.config(confwrite).option(pathread).value.pop(3)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg.config(confread).forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg.config(confread).forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg.config(confread).forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 2).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.pop(3)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg2_.forcepermissive.option(a_follower, 1).value.get() == follower_value
assert cfg2_.forcepermissive.option(a_follower, 1).owner.isdefault() is False
cfg2_.forcepermissive.option(a_follower, 2).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 2).owner.isdefault() is True
#
cfg.forcepermissive.config(confwrite).option(pathread).value.pop(0)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == follower_value
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is False
cfg.config(confread).forcepermissive.option(a_follower, 1).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 1).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.pop(0)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == follower_value
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is False
cfg2_.forcepermissive.option(a_follower, 1).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 1).owner.isdefault() is True
#
cfg.forcepermissive.config(confwrite).option(pathread).value.pop(0)
cfg.config(confread).forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg.config(confread).forcepermissive.option(a_follower, 0).owner.isdefault() is True
cfg_.forcepermissive.option(pathread).value.pop(0)
cfg2_.forcepermissive.option(a_follower, 0).value.get() == kwargs['default_multi']
assert cfg2_.forcepermissive.option(a_follower, 0).owner.isdefault() is True
@autocheck
@ -697,12 +757,20 @@ def autocheck_reset_value_permissive(cfg, mcfg, pathread, pathwrite, confread, c
with warnings.catch_warnings(record=True) as w:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
if not isfollower:
cfg.forcepermissive.config(confwrite).option(pathwrite).value.reset()
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
cfg_.option(pathwrite).value.reset()
else:
cfg.forcepermissive.option(pathwrite, 1).value.reset()
elif kwargs.get('permissive', False):
if not isfollower:
cfg.forcepermissive.config(confwrite).option(pathwrite).value.reset()
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
cfg_.option(pathwrite).value.reset()
else:
cfg.forcepermissive.option(pathwrite, 1).value.reset()
#FIXME else:
@ -723,13 +791,21 @@ def autocheck_display(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwa
return
make_dict = kwargs['make_dict']
make_dict_value = kwargs['make_dict_value']
assert cfg.config(confread).value.dict() == make_dict
if confread is not None:
cfg_ = cfg.config(confread)
else:
cfg_ = cfg
if confwrite is not None:
cfg2_ = cfg.config(confwrite)
else:
cfg2_ = cfg
assert cfg_.value.dict() == make_dict
if confread != confwrite:
assert(cfg.config(confwrite).value.dict()) == make_dict
assert(cfg2_.value.dict()) == make_dict
_set_value(cfg, pathwrite, confwrite, **kwargs)
assert cfg.config(confread).value.dict() == make_dict_value
assert cfg_.value.dict() == make_dict_value
if confread != confwrite:
assert(cfg.config(confwrite).value.dict()) == make_dict_value
assert(cfg2_.value.dict()) == make_dict_value
@autocheck
@ -749,7 +825,11 @@ def autocheck_property(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kw
# set properties without permissive
for prop in properties:
cfg.unrestraint.config(confwrite).option(pathwrite).property.add(prop)
if confwrite is not None:
cfg_ = cfg.unrestraint.config(confwrite)
else:
cfg_ = cfg.unrestraint
cfg_.option(pathwrite).property.add(prop)
if confread == confwrite:
_check_properties(cfg, mcfg, pathread, confread, kwargs, properties, properties)
else:
@ -774,7 +854,11 @@ def autocheck_reset_property(cfg, mcfg, pathread, pathwrite, confread, confwrite
_property_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs)
# reset properties without permissive
cfg.unrestraint.config(confwrite).option(pathwrite).property.reset()
if confwrite is not None:
cfg_ = cfg.unrestraint.config(confwrite)
else:
cfg_ = cfg.unrestraint
cfg_.option(pathwrite).property.reset()
if confread == confwrite:
_check_properties(cfg, mcfg, pathread, confread, kwargs, default_props, default_props)
@ -819,22 +903,28 @@ def autocheck_default_owner_with_value(cfg, mcfg, pathread, pathwrite, confread,
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
_set_value(cfg, pathwrite, confwrite, **kwargs)
if confwrite is not None:
cfg_ = cfg.config(confread)
cfg2_ = cfg.config(confwrite)
else:
cfg_ = cfg
cfg2_ = cfg
# test if is default owner without permissive
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(confwrite).option(pathread).owner.isdefault() is False
assert cfg_.option(pathread).owner.isdefault() is False
if confwrite != confread:
assert cfg.config(confread).option(pathread).owner.isdefault() is False
assert cfg2_.option(pathread).owner.isdefault() is False
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(confwrite).option(pathread).owner.isdefault()")
# raises(PropertiesOptionError, "cfg.config(confread).option(pathread).owner.isdefault()")
else:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert cfg.config(confwrite).option(pathread, 0).owner.isdefault() is True
assert cfg.config(confwrite).option(pathread, 1).owner.isdefault() is False
assert cfg2_.option(pathread, 0).owner.isdefault() is True
assert cfg2_.option(pathread, 1).owner.isdefault() is False
if confwrite != confread:
assert cfg.config(confread).option(pathread, 0).owner.isdefault() is True
assert cfg.config(confread).option(pathread, 1).owner.isdefault() is False
assert cfg_.option(pathread, 0).owner.isdefault() is True
assert cfg_.option(pathread, 1).owner.isdefault() is False
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(confwrite).option(pathread, 0).owner.isdefault()")
# raises(PropertiesOptionError, "cfg.config(confread).option(pathread, 0).owner.isdefault()")
@ -849,12 +939,16 @@ def autocheck_default_owner_with_value_permissive(cfg, mcfg, pathread, pathwrite
def do(conf):
# test if is default owner with permissive
if conf is not None:
cfg_ = cfg.config(conf)
else:
cfg_ = cfg
if not kwargs.get('propertyerror', False):
if not isfollower:
assert cfg.config(conf).forcepermissive.option(pathread).owner.isdefault() is False
assert cfg_.forcepermissive.option(pathread).owner.isdefault() is False
else:
assert cfg.config(conf).forcepermissive.option(pathread, 0).owner.isdefault() is True
assert cfg.config(conf).forcepermissive.option(pathread, 1).owner.isdefault() is False
assert cfg_.forcepermissive.option(pathread, 0).owner.isdefault() is True
assert cfg_.forcepermissive.option(pathread, 1).owner.isdefault() is False
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(conf).forcepermissive.option(pathread).owner.isdefault()")
do(confwrite)
@ -865,11 +959,15 @@ def autocheck_default_owner_with_value_permissive(cfg, mcfg, pathread, pathwrite
@autocheck
def autocheck_set_owner_no_value(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs):
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
if not kwargs.get('propertyerror', False):
if not isfollower:
raises(ConfigError, "cfg.forcepermissive.config(confwrite).option(pathwrite).owner.set('new_user')")
raises(ConfigError, "cfg_.option(pathwrite).owner.set('new_user')")
else:
raises(ConfigError, "cfg.forcepermissive.option(pathwrite, 1).owner.set('new_user')")
raises(ConfigError, "cfg_.option(pathwrite, 1).owner.set('new_user')")
@autocheck
@ -878,13 +976,17 @@ def autocheck_set_owner(cfg, mcfg, pathread, pathwrite, confread, confwrite, **k
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
_set_value(cfg, pathwrite, confwrite, **kwargs)
if confwrite is not None:
cfg_ = cfg.config(confwrite)
else:
cfg_ = cfg
# set owner without permissive
if not isfollower:
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
cfg.config(confwrite).option(pathwrite).owner.set('new_user')
raises(ValueError, "cfg.config(confwrite).option(pathwrite).owner.set('default')")
raises(ValueError, "cfg.config(confwrite).option(pathwrite).owner.set('forced')")
cfg_.option(pathwrite).owner.set('new_user')
raises(ValueError, "cfg_.option(pathwrite).owner.set('default')")
raises(ValueError, "cfg_.option(pathwrite).owner.set('forced')")
#FIXME else:
# raises(PropertiesOptionError, "cfg.config(confwrite).option(pathwrite).owner.set('new_user')")
else:
@ -903,11 +1005,15 @@ def autocheck_set_owner_permissive(cfg, mcfg, pathread, pathwrite, confread, con
isfollower = cfg.unrestraint.option(pathread).option.isfollower()
_set_value(cfg, pathwrite, confwrite, **kwargs)
if confwrite is not None:
cfg_ = cfg.forcepermissive.config(confwrite)
else:
cfg_ = cfg.forcepermissive
# set owner with permissive
if not kwargs.get('propertyerror', False):
if not isfollower:
cfg.forcepermissive.config(confwrite).option(pathwrite).owner.set('new_user1')
cfg_.option(pathwrite).owner.set('new_user1')
else:
cfg.forcepermissive.option(pathwrite, 1).owner.set('new_user1')
#FIXME else:
@ -961,9 +1067,17 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
"""test permissive for hidden and disabled value
"""
# no permissive before
assert cfg.unrestraint.config(confwrite).option(pathread).permissive.get() == frozenset()
if confwrite is not None:
cfg_ = cfg.unrestraint.config(confwrite)
else:
cfg_ = cfg.unrestraint
if confread is not None:
cfg2_ = cfg.config(confread).unrestraint
else:
cfg2_ = cfg.unrestraint
assert cfg_.option(pathread).permissive.get() == frozenset()
if kwargs.get('permissive_od', False):
assert cfg.unrestraint.config(confwrite).option(pathread.rsplit('.', 1)[0]).permissive.get() == frozenset()
assert cfg_.option(pathread.rsplit('.', 1)[0]).permissive.get() == frozenset()
# cannot access to hidden value without forcepermissive
# and to disabled value (with forcepermissive too)
@ -972,17 +1086,17 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
_autocheck_default_value(cfg, pathread, confread, **kwargs)
# set permissive
cfg.unrestraint.config(confwrite).option(pathwrite).permissive.set(frozenset(['disabled']))
cfg_.option(pathwrite).permissive.set(frozenset(['disabled']))
callback = kwargs['callback']
if callback:
if pathread.endswith('val1') or pathread.endswith('val2'):
call_path = pathread[:-4] + 'call' + pathread[-4:]
else:
call_path = pathread + 'call'
cfg.unrestraint.config(confwrite).option(call_path).permissive.set(frozenset(['disabled']))
cfg_.option(call_path).permissive.set(frozenset(['disabled']))
# have permissive?
assert cfg.unrestraint.config(confwrite).option(pathread).permissive.get() == frozenset(['disabled'])
assert cfg_.option(pathread).permissive.get() == frozenset(['disabled'])
#if confwrite != confread:
# assert cfg.config(confread).unrestraint.option(pathread).permissive.get() == frozenset(['disabled'])
@ -991,9 +1105,9 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
ckwargs['propertyerror'] = False
_autocheck_default_value(cfg, pathread, confwrite, **ckwargs)
cfg.config(confread).unrestraint.option(pathwrite).permissive.set(frozenset(['disabled', 'hidden']))
cfg2_.option(pathwrite).permissive.set(frozenset(['disabled', 'hidden']))
if kwargs['callback']:
cfg.config(confread).unrestraint.option(call_path).permissive.set(frozenset(['disabled', 'hidden']))
cfg2_.option(call_path).permissive.set(frozenset(['disabled', 'hidden']))
# can access to all value except when optiondescript have hidden
if not ckwargs.get('permissive_od', False):
@ -1002,7 +1116,7 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
if ckwargs.get('permissive_od', False):
# set permissive to OptionDescription
cfg.config(confread).unrestraint.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['disabled',
cfg2_.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['disabled',
'hidden']))
ckwargs['permissive'] = False
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
@ -1010,23 +1124,23 @@ def autocheck_permissive(cfg, mcfg, pathread, pathwrite, confread, confwrite, **
# _autocheck_default_value(cfg, pathread, confwrite, **ckwargs)
# only hidden
cfg.config(confread).unrestraint.option(pathwrite).permissive.set(frozenset(['hidden']))
cfg2_.option(pathwrite).permissive.set(frozenset(['hidden']))
if callback:
cfg.config(confread).unrestraint.option(call_path).permissive.set(frozenset(['hidden']))
cfg2_.option(call_path).permissive.set(frozenset(['hidden']))
if ckwargs.get('permissive_od', False):
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
cfg.config(confread).unrestraint.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['hidden']))
cfg2_.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset(['hidden']))
ckwargs = copy(kwargs)
ckwargs['permissive'] = False
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
# no permissive
cfg.config(confread).unrestraint.option(pathwrite).permissive.set(frozenset())
cfg2_.option(pathwrite).permissive.set(frozenset())
if callback:
cfg.config(confread).unrestraint.option(call_path).permissive.set(frozenset())
cfg2_.option(call_path).permissive.set(frozenset())
if ckwargs.get('permissive_od', False):
_autocheck_default_value(cfg, pathread, confread, **ckwargs)
cfg.config(confread).unrestraint.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset())
cfg2_.option(pathwrite.rsplit('.', 1)[0]).permissive.set(frozenset())
_autocheck_default_value(cfg, pathread, confread, **kwargs)
@ -1060,17 +1174,21 @@ def autocheck_find(cfg, mcfg, pathread, pathwrite, confread, confwrite, **kwargs
option = _getoption(cfg.unrestraint.option(pathread))
def do(conf):
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert option == _getoption(cfg.config(conf).option.find(name, first=True))
assert option == _getoption(cfg.config(conf).forcepermissive.option.find(name, first=True))
elif kwargs.get('permissive', False):
raises(AttributeError, "cfg.config(conf).option.find(name, first=True)")
assert option == _getoption(cfg.config(conf).forcepermissive.option.find(name, first=True))
if conf is not None:
cfg_ = cfg.config(conf)
else:
raises(AttributeError, "cfg.config(conf).option.find(name, first=True)")
raises(AttributeError, "cfg.config(conf).forcepermissive.option.find(name, first=True)")
assert option == _getoption(cfg.config(conf).unrestraint.option.find(name, first=True))
assert [option] == _getoptions(cfg.config(conf).unrestraint.option.find(name))
cfg_ = cfg
if not kwargs.get('permissive', False) and not kwargs.get('propertyerror', False):
assert option == _getoption(cfg_.option.find(name, first=True))
assert option == _getoption(cfg_.forcepermissive.option.find(name, first=True))
elif kwargs.get('permissive', False):
raises(AttributeError, "cfg_.option.find(name, first=True)")
assert option == _getoption(cfg_.forcepermissive.option.find(name, first=True))
else:
raises(AttributeError, "cfg_.option.find(name, first=True)")
raises(AttributeError, "cfg_.forcepermissive.option.find(name, first=True)")
assert option == _getoption(cfg_.unrestraint.option.find(name, first=True))
assert [option] == _getoptions(cfg_.unrestraint.option.find(name))
do(confread)
if confread != confwrite:
do(confwrite)

View File

@ -264,6 +264,23 @@ def test_config_multi():
assert config.option('test3').value.get() == [2, 1]
def test_prefix_error():
i1 = IntOption('test1', '')
od = OptionDescription('test', '', [i1])
config = Config(od)
config.property.read_write()
config.option('test1').value.set(1)
try:
config.option('test1').value.set('yes')
except Exception as err:
assert str(err) == '"yes" is an invalid integer for "test1"'
try:
config.option('test1').value.set('yes')
except Exception as err:
err.prefix = ''
assert str(err) == 'invalid value'
def test_no_validation():
i1 = IntOption('test1', '')
od = OptionDescription('test', '', [i1])

View File

@ -4,8 +4,7 @@ do_autopath()
import warnings, sys
from py.test import raises
from tiramisu import Config
from tiramisu.option import DomainnameOption, EmailOption, URLOption, OptionDescription
from tiramisu import Config, DomainnameOption, EmailOption, URLOption, OptionDescription
from tiramisu.error import ValueWarning
from tiramisu.i18n import _
from tiramisu.storage import list_sessions
@ -19,9 +18,11 @@ def test_domainname():
d = DomainnameOption('d', '')
f = DomainnameOption('f', '', allow_without_dot=True)
g = DomainnameOption('g', '', allow_ip=True)
od = OptionDescription('a', '', [d, f, g])
h = DomainnameOption('h', '', allow_ip=True, cidr=True)
od = OptionDescription('a', '', [d, f, g, h])
cfg = Config(od)
cfg.property.read_write()
#
cfg.option('d').value.set('toto.com')
raises(ValueError, "cfg.option('d').value.set('toto')")
cfg.option('d').value.set('toto3.com')
@ -40,9 +41,17 @@ def test_domainname():
cfg.option('f').value.set('d.t')
#
raises(ValueError, "cfg.option('f').value.set('192.168.1.1')")
raises(ValueError, "cfg.option('f').value.set('192.168.1.0/24')")
#
cfg.option('g').value.set('toto.com')
cfg.option('g').value.set('192.168.1.0')
cfg.option('g').value.set('192.168.1.29')
raises(ValueError, "cfg.option('g').value.set('192.168.1.0/24')")
#
cfg.option('h').value.set('toto.com')
raises(ValueError, "cfg.option('h').value.set('192.168.1.0')")
raises(ValueError, "cfg.option('h').value.set('192.168.1.29')")
cfg.option('h').value.set('192.168.1.0/24')
def test_domainname_upper():

View File

@ -417,6 +417,7 @@ def test_mandatory_leader():
api = Config(descr)
api.property.read_only()
raises(PropertiesOptionError, "api.option('ip_admin_eth0.ip_admin_eth0').value.get()")
raises(PropertiesOptionError, "api.value.dict()")
def test_mandatory_warnings_leader():

View File

@ -63,6 +63,12 @@ def test_unknown_config():
raises(ConfigError, "meta.config('unknown')")
def test_error_metaconfig():
od2 = make_description()
conf1 = Config(od2, session_id='conf1')
raises(TypeError, "MetaConfig([GroupConfig([conf1])], session_id='meta')")
def test_path():
meta = make_metaconfig()
assert meta.config.path() == 'meta'

View File

@ -98,6 +98,16 @@ def test_option_isoptiondescription():
assert not cfg.option('od.test').option.isoptiondescription()
def test_option_double():
i = IntOption('test', '')
od = OptionDescription('od1', '', [i])
od = OptionDescription('od2', '', [od])
od = OptionDescription('od3', '', [od])
cfg = Config(od)
assert cfg.option('od2.od1.test').value.get() is None
assert cfg.option('od2').option('od1').option('test').value.get() is None
def test_option_multi():
IntOption('test', '', multi=True)
IntOption('test', '', multi=True, default_multi=1)
@ -227,3 +237,8 @@ def test_intoption():
def test_get_display_type():
i1 = IntOption('test1', 'description', min_number=3)
assert i1.get_display_type() == 'integer'
def test_option_not_in_config():
i1 = IntOption('test1', 'description', min_number=3)
raises(AttributeError, "i1.impl_getpath()")

View File

@ -8,7 +8,7 @@ from tiramisu.config import KernelConfig
from tiramisu.setting import groups, owners
from tiramisu import ChoiceOption, BoolOption, IntOption, FloatOption, \
StrOption, OptionDescription, SymLinkOption, IPOption, NetmaskOption, Leadership, \
undefined, Params, ParamOption, ParamValue, ParamContext
undefined, Params, ParamOption, ParamValue, ParamContext, calc_value
from tiramisu.api import TIRAMISU_VERSION
from tiramisu.error import PropertiesOptionError, ConflictError, LeadershipError, ConfigError
from tiramisu.i18n import _
@ -1194,3 +1194,100 @@ def test_callback_raise():
api.option('od2.opt2').value.get()
except ConfigError as err:
assert '"Option 2"' in str(err)
def test_calc_value_simple():
val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1)))
od = OptionDescription('root', '', [val1, val2])
cfg = Config(od)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'}
def test_calc_value_multi():
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True)))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
def test_calc_value_disabled():
val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True), default=ParamValue('default_value')))
od = OptionDescription('root', '', [val1, val2])
cfg = Config(od)
cfg.property.read_write()
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1'}
cfg.option('val1').property.add('disabled')
assert cfg.value.dict() == {'val2': 'default_value'}
def test_calc_value_condition():
boolean = BoolOption('boolean', '', True)
val1 = StrOption('val1', '', 'val1')
val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True),
default=ParamValue('default_value'),
condition=ParamOption(boolean),
expected=ParamValue(True)))
od = OptionDescription('root', '', [boolean, val1, val2])
cfg = Config(od)
cfg.property.read_write()
assert cfg.value.dict() == {'boolean': True, 'val1': 'val1', 'val2': 'val1'}
cfg.option('boolean').value.set(False)
assert cfg.value.dict() == {'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
def test_calc_value_allow_none():
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "")
val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), allow_none=ParamValue(True)))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
assert cfg.value.dict() == {'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
def test_calc_value_remove_duplicate():
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val1')
val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), remove_duplicate_value=ParamValue(True)))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
def test_calc_value_join():
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), join=ParamValue('.')))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
def test_calc_value_min():
from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
val1 = StrOption('val1', "", 'val1')
val2 = StrOption('val2', "", 'val2')
val3 = StrOption('val3', "", 'val3')
val4 = StrOption('val4', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2), ParamOption(val3, True)), join=ParamValue('.'), min_args_len=ParamValue(3)))
od = OptionDescription('root', '', [val1, val2, val3, val4])
cfg = Config(od)
cfg.property.read_write()
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val3': 'val3', 'val4': 'val1.val2.val3'}
cfg.option('val3').property.add('disabled')
assert cfg.value.dict() == {'val1': 'val1', 'val2': 'val2', 'val4': ''}
def test_calc_value_add():
from tiramisu import calc_value, IntOption, OptionDescription, Config, Params, ParamOption, ParamValue
val1 = IntOption('val1', "", 1)
val2 = IntOption('val2', "", 2)
val3 = IntOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), operator=ParamValue('add')))
od = OptionDescription('root', '', [val1, val2, val3])
cfg = Config(od)
assert cfg.value.dict() == {'val1': 1, 'val2': 2, 'val3': 3}

View File

@ -88,6 +88,24 @@ def test_consistency_warnings_only_more_option():
assert len(w) == 1
def test_consistency_error_prefix():
a = IntOption('a', '')
b = IntOption('b', '')
od = OptionDescription('od', '', [a, b])
a.impl_add_consistency('not_equal', b)
api = Config(od)
api.option('a').value.set(1)
try:
api.option('b').value.set(1)
except Exception as err:
assert str(err) == '"1" is an invalid integer for "b", must be different from the value of "a"'
try:
api.option('b').value.set(1)
except Exception as err:
err.prefix = ''
assert str(err) == 'must be different from the value of "a"'
def test_consistency_warnings_only_option():
a = IntOption('a', '')
b = IntOption('b', '', warnings_only=True)

View File

@ -1123,3 +1123,205 @@ def test_leadership_requires_no_leader():
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 0).value.get()")
raises(PropertiesOptionError, "api.option('ip_admin_eth0.netmask_admin_eth0', 1).value.get()")
assert api.value.dict() == {'ip_admin_eth0.ip_admin_eth0': ['192.168.1.2', '192.168.1.1'], 'activate': False}
def test_leadership_requires_complet():
optiontoto = StrOption('unicodetoto', "Unicode leader")
option = StrOption('unicode', "Unicode leader", multi=True)
option1 = StrOption('unicode1', "Unicode follower 1", multi=True)
option2 = StrOption('unicode2', "Values 'test' must show 'Unicode follower 3'", multi=True)
option3 = StrOption('unicode3', "Unicode follower 3", requires=[{'option': option,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option4 = StrOption('unicode4', "Unicode follower 4", requires=[{'option': option2,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option5 = StrOption('unicode5', "Unicode follower 5", requires=[{'option': optiontoto,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option6 = StrOption('unicode6', "Unicode follower 6", requires=[{'option': optiontoto,
'expected': u'test',
'action': 'hidden',
'inverse': True},
{'option': option2,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
option7 = StrOption('unicode7', "Unicode follower 7", requires=[{'option': option2,
'expected': u'test',
'action': 'hidden',
'inverse': True},
{'option': optiontoto,
'expected': u'test',
'action': 'hidden',
'inverse': True}],
multi=True)
descr1 = Leadership("unicode", "Common configuration 1",
[option, option1, option2, option3, option4, option5, option6, option7])
descr = OptionDescription("options", "Common configuration 2", [descr1, optiontoto])
descr = OptionDescription("unicode1_leadership_requires", "Leader followers with Unicode follower 3 hidden when Unicode follower 2 is test", [descr])
config = Config(descr)
config.property.read_write()
config.option('options.unicode.unicode').value.set(['test', 'trah'])
config.option('options.unicode.unicode2', 0).value.set('test')
dico = config.value.dict()
assert dico.keys() == set(['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto'])
assert dico['options.unicode.unicode'] == ['test', 'trah']
assert dico['options.unicode.unicode1'] == [None, None]
assert dico['options.unicode.unicode2'] == ['test', None]
assert dico['options.unicode.unicode3'][0] is None
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert dico['options.unicode.unicode4'][0] is None
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert dico['options.unicodetoto'] is None
del dico['options.unicode.unicode3'][1]
del dico['options.unicode.unicode3']
del dico['options.unicode.unicode4'][1]
del dico['options.unicode.unicode4']
#
config.option('options.unicodetoto').value.set('test')
dico = config.value.dict()
assert dico.keys() == set(['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicode.unicode5', 'options.unicode.unicode6', 'options.unicode.unicode7', 'options.unicodetoto'])
assert dico['options.unicode.unicode'] == ['test', 'trah']
assert dico['options.unicode.unicode1'] == [None, None]
assert dico['options.unicode.unicode2'] == ['test', None]
assert dico['options.unicode.unicode3'][0] is None
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert dico['options.unicode.unicode4'][0] is None
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert dico['options.unicode.unicode5'] == [None, None]
assert dico['options.unicode.unicode6'][0] is None
assert isinstance(dico['options.unicode.unicode6'][1], PropertiesOptionError)
assert dico['options.unicode.unicode7'][0] is None
assert isinstance(dico['options.unicode.unicode7'][1], PropertiesOptionError)
assert dico['options.unicodetoto'] == 'test'
del dico['options.unicode.unicode3'][1]
del dico['options.unicode.unicode3']
del dico['options.unicode.unicode4'][1]
del dico['options.unicode.unicode4']
del dico['options.unicode.unicode6'][1]
del dico['options.unicode.unicode6']
del dico['options.unicode.unicode7'][1]
del dico['options.unicode.unicode7']
def test_leadership_requires_transitive():
optiontoto = StrOption('unicodetoto', "Unicode leader")
option = StrOption('unicode', "Unicode leader", multi=True)
option1 = StrOption('unicode1', "Unicode follower 1", multi=True)
option2 = StrOption('unicode2', "Unicode follower 2", requires=[{'option': optiontoto,
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
option3 = StrOption('unicode3', "Unicode follower 3", requires=[{'option': option2,
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
option4 = StrOption('unicode4', "Unicode follower 4", requires=[{'option': option3,
'expected': u'test',
'action': 'disabled',
'transitive': True,
'inverse': True}],
multi=True)
descr1 = Leadership("unicode", "Common configuration 1",
[option, option1, option2, option3, option4])
descr = OptionDescription("options", "Common configuration 2", [descr1, optiontoto])
descr = OptionDescription("unicode1", "", [descr])
config = Config(descr)
config.property.read_write()
assert config.value.dict() == {'options.unicode.unicode': [], 'options.unicode.unicode1': [], 'options.unicode.unicode3': [], 'options.unicode.unicode4': [], 'options.unicodetoto': None}
#
config.option('options.unicodetoto').value.set('test')
assert config.value.dict() == {'options.unicode.unicode': [], 'options.unicode.unicode1': [], 'options.unicode.unicode2': [], 'options.unicode.unicode3': [], 'options.unicode.unicode4': [], 'options.unicodetoto': 'test'}
#
config.option('options.unicode.unicode').value.set(['a', 'b', 'c'])
dico = config.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'test'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert dico['options.unicode.unicode2'] == [None, None, None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])
#
config.option('options.unicode.unicode2', 1).value.set('test')
config.option('options.unicode.unicode3', 1).value.set('test')
dico = config.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'test'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert dico['options.unicode.unicode2'] == [None, 'test', None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert dico['options.unicode.unicode3'][1] == 'test'
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert dico['options.unicode.unicode4'][1] == None
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])
#
config.option('options.unicode.unicode2', 1).value.set('rah')
dico = config.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode2', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'test'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert dico['options.unicode.unicode2'] == [None, 'rah', None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])
#
config.option('options.unicode.unicode2', 1).value.set('test')
config.option('options.unicodetoto').value.set('rah')
dico = config.value.dict()
assert list(dico.keys()) == ['options.unicode.unicode', 'options.unicode.unicode1', 'options.unicode.unicode3', 'options.unicode.unicode4', 'options.unicodetoto']
assert dico['options.unicodetoto'] == 'rah'
assert dico['options.unicode.unicode'] == ['a', 'b', 'c']
assert dico['options.unicode.unicode1'] == [None, None, None]
assert isinstance(dico['options.unicode.unicode3'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode3'][2], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][0], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][1], PropertiesOptionError)
assert isinstance(dico['options.unicode.unicode4'][2], PropertiesOptionError)
del (dico['options.unicode.unicode3'][2])
del (dico['options.unicode.unicode3'][1])
del (dico['options.unicode.unicode3'][0])
del (dico['options.unicode.unicode4'][2])
del (dico['options.unicode.unicode4'][1])
del (dico['options.unicode.unicode4'][0])

View File

@ -13,7 +13,7 @@
# 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 .function import Params, ParamOption, ParamValue, ParamContext, \
tiramisu_copy
tiramisu_copy, calc_value
from .option import *
from .error import APIError
from .api import Config, MetaConfig, GroupConfig, MixConfig
@ -37,7 +37,8 @@ allfuncs = ['Params',
'Storage',
'list_sessions',
'delete_session',
'tiramisu_copy']
'tiramisu_copy',
'calc_value']
allfuncs.extend(all_options)
del(all_options)
__all__ = tuple(allfuncs)

View File

@ -148,7 +148,7 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
return self._option_bag.option
def type(self):
return self._option_bag.option.get_display_type()
return self._option_bag.option.get_type()
def isleadership(self):
"""Test if option is a leader or a follower"""
@ -203,6 +203,20 @@ class _TiramisuOptionOptionDescription(CommonTiramisuOption):
settings.get_context_properties(),
settings.get_context_properties())
def __call__(self,
path: str,
index: Optional[int]=None) -> 'TiramisuOption':
"""Select an option by path"""
subpath = self._option_bag.option.impl_getname() + '.' + path
subconfig, name = self._subconfig.cfgimpl_get_home_by_path(subpath,
self._option_bag.config_bag)
path = self._option_bag.path + '.' + path
return TiramisuOption(name,
path,
index,
subconfig,
self._option_bag.config_bag)
class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
"""Manage option"""
@ -738,17 +752,9 @@ class TiramisuOption(CommonTiramisuOption):
subconfig=subconfig,
config_bag=config_bag)
#__________________________________________________________________________________________________
#
# First part of API:
# - contexts informations:
# - context owner
# - context information
# - context property
# - context permissive
# - forcepermissive
# - unrestraint
# - manage MetaConfig or GroupConfig
class TiramisuContext(TiramisuHelp):

View File

@ -1198,12 +1198,13 @@ class KernelMetaConfig(KernelMixConfig):
if not isinstance(child, _CommonConfig):
try:
child = child._config
except:
except Exception:
raise TypeError(_("{}config's children "
"should be config, not {}"
).format(self.impl_type,
type(child)))
if not isinstance(child, (KernelConfig, KernelMetaConfig)):
if __debug__ and not isinstance(child, (KernelConfig,
KernelMetaConfig)):
raise TypeError(_("child must be a Config or MetaConfig"))
if descr is None:
descr = child.cfgimpl_get_description()

View File

@ -12,6 +12,9 @@
#
# 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 typing import Any, List, Optional
from operator import add, mul, sub, truediv
from .setting import undefined
from .i18n import _
@ -79,3 +82,235 @@ class ParamIndex(Param):
def tiramisu_copy(val): # pragma: no cover
return val
def calc_value(*args: List[Any],
multi: bool=False,
default: Any=undefined,
condition: Any=undefined,
expected: Any=undefined,
condition_operator: str='AND',
allow_none: bool=False,
remove_duplicate_value: bool=False,
join: Optional[str]=None,
min_args_len: Optional[int]=None,
operator: Optional[str]=None,
**kwargs) -> Any:
"""calculate value
:param multi: value returns must be a list of value
:param default: default value if condition is not matched or if args is empty
if there is more than one default value, set default_0, default_1, ...
:param condition: test if condition is equal to expected value
if there is more than one condition, set condition_0, condition_1, ...
:param expected: value expected for all conditions
if expected value is different between condition, set expected_0, expected_1, ...
:param condition_operator: OR or AND operator for condition
:param allow_none: if False, do not return list in None is present in list
:param remove_duplicate_value: if True, remote duplicated value
:param join: join all args with specified characters
:param min_args_len: if number of arguments is smaller than this value, return default value
:param operator: operator
examples:
* you want to copy value from an option to an other option:
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption
>>> val1 = StrOption('val1', '', 'val1')
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1)))
>>> od = OptionDescription('root', '', [val1, val2])
>>> cfg = Config(od)
>>> cfg.value.dict()
{'val1': 'val1', 'val2': 'val1'}
* you want to copy values from two options in one multi option
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> val1 = StrOption('val1', "", 'val1')
>>> val2 = StrOption('val2', "", 'val2')
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True)))
>>> od = OptionDescription('root', '', [val1, val2, val3])
>>> cfg = Config(od)
>>> cfg.value.dict()
{'val1': 'val1', 'val2': 'val2', 'val3': ['val1', 'val2']}
* you want to copy a value from an option is it not disabled, otherwise set 'default_value'
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> val1 = StrOption('val1', '', 'val1')
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True), default=ParamValue('default_value')))
>>> od = OptionDescription('root', '', [val1, val2])
>>> cfg = Config(od)
>>> cfg.property.read_write()
>>> cfg.value.dict()
{'val1': 'val1', 'val2': 'val1'}
>>> cfg.option('val1').property.add('disabled')
>>> cfg.value.dict()
{'val2': 'default_value'}
* you want to copy value from an option is an other is True, otherwise set 'default_value'
>>> from tiramisu import calc_value, BoolOption, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> boolean = BoolOption('boolean', '', True)
>>> val1 = StrOption('val1', '', 'val1')
>>> val2 = StrOption('val2', '', callback=calc_value, callback_params=Params(ParamOption(val1, True),
... default=ParamValue('default_value'),
... condition=ParamOption(boolean),
... expected=ParamValue(True)))
>>> od = OptionDescription('root', '', [boolean, val1, val2])
>>> cfg = Config(od)
>>> cfg.property.read_write()
>>> cfg.value.dict()
{'boolean': True, 'val1': 'val1', 'val2': 'val1'}
>>> cfg.option('boolean').value.set(False)
>>> cfg.value.dict()
{'boolean': False, 'val1': 'val1', 'val2': 'default_value'}
* you want to copy option even if None is present
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> val1 = StrOption('val1', "", 'val1')
>>> val2 = StrOption('val2', "")
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), allow_none=ParamValue(True)))
>>> od = OptionDescription('root', '', [val1, val2, val3])
>>> cfg = Config(od)
>>> cfg.value.dict()
{'val1': 'val1', 'val2': None, 'val3': ['val1', None]}
* you want uniq value
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> val1 = StrOption('val1', "", 'val1')
>>> val2 = StrOption('val2', "", 'val1')
>>> val3 = StrOption('val3', "", multi=True, callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), multi=ParamValue(True), remove_duplicate_value=ParamValue(True)))
>>> od = OptionDescription('root', '', [val1, val2, val3])
>>> cfg = Config(od)
>>> cfg.value.dict()
{'val1': 'val1', 'val2': 'val1', 'val3': ['val1']}
* you want to join two values with '.'
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> val1 = StrOption('val1', "", 'val1')
>>> val2 = StrOption('val2', "", 'val2')
>>> val3 = StrOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), join=ParamValue('.')))
>>> od = OptionDescription('root', '', [val1, val2, val3])
>>> cfg = Config(od)
>>> cfg.value.dict()
{'val1': 'val1', 'val2': 'val2', 'val3': 'val1.val2'}
* you want join three values, only if almost three values are set
>>> from tiramisu import calc_value, StrOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> val1 = StrOption('val1', "", 'val1')
>>> val2 = StrOption('val2', "", 'val2')
>>> val3 = StrOption('val3', "", 'val3')
>>> val4 = StrOption('val4', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2), ParamOption(val3, True)), join=ParamValue('.'), min_args_len=ParamValue(3)))
>>> od = OptionDescription('root', '', [val1, val2, val3, val4])
>>> cfg = Config(od)
>>> cfg.property.read_write()
>>> cfg.value.dict()
{'val1': 'val1', 'val2': 'val2', 'val3': 'val3', 'val4': 'val1.val2.val3'}
>>> cfg.option('val3').property.add('disabled')
>>> cfg.value.dict()
{'val1': 'val1', 'val2': 'val2', 'val4': ''}
* you want to add all values
>>> from tiramisu import calc_value, IntOption, OptionDescription, Config, Params, ParamOption, ParamValue
>>> val1 = IntOption('val1', "", 1)
>>> val2 = IntOption('val2', "", 2)
>>> val3 = IntOption('val3', "", callback=calc_value, callback_params=Params((ParamOption(val1), ParamOption(val2)), operator=ParamValue('add')))
>>> od = OptionDescription('root', '', [val1, val2, val3])
>>> cfg = Config(od)
>>> cfg.value.dict()
{'val1': 1, 'val2': 2, 'val3': 3}
"""
def value_from_kwargs(value: Any, pattern: str, to_dict: bool=False) -> Any:
# if value attribute exist return it's value
# otherwise pattern_0, pattern_1, ...
# otherwise undefined
if value is not undefined:
if to_dict == 'all':
returns = {0: value}
else:
returns = value
else:
kwargs_matches = {}
len_pattern = len(pattern)
for key in kwargs.keys():
if key.startswith(pattern):
index = int(key[len_pattern:])
kwargs_matches[index] = kwargs[key]
if not kwargs_matches:
return undefined
keys = sorted(kwargs_matches)
if to_dict:
returns = {}
else:
returns = []
for key in keys:
if to_dict:
returns[key] = kwargs_matches[key]
else:
returns.append(kwargs_matches[key])
return returns
def is_condition_matches():
calculated_conditions = value_from_kwargs(condition, 'condition_', to_dict='all')
if condition is not undefined:
is_matches = None
calculated_expected = value_from_kwargs(expected, 'expected_', to_dict=True)
for idx, calculated_condition in calculated_conditions.items():
if isinstance(calculated_expected, dict):
current_matches = calculated_condition == calculated_expected[idx]
else:
current_matches = calculated_condition == calculated_expected
if is_matches is None:
is_matches = current_matches
elif condition_operator == 'AND':
is_matches = is_matches and current_matches
elif condition_operator == 'OR':
is_matches = is_matches or current_matches
else:
raise ValueError(_('unexpected {} condition_operator in calc_value').format(condition_operator))
else:
is_matches = True
return is_matches
def get_value():
if not is_condition_matches():
# force to default
value = []
else:
value = list(args)
if min_args_len and not len(value) >= min_args_len:
value = []
if value == []:
# default value
new_default = value_from_kwargs(default, 'default_')
if new_default is not undefined:
if not isinstance(new_default, list):
value = [new_default]
else:
value = new_default
return value
value = get_value()
if not multi:
if join is not None:
value = join.join(value)
elif value and operator:
new_value = value[0]
op = {'mul': mul,
'add': add,
'div': truediv,
'sub': sub}[operator]
for val in value[1:]:
new_value = op(new_value, val)
value = new_value
elif value == []:
value = None
else:
value = value[0]
elif None in value and not allow_none:
value = []
elif remove_duplicate_value:
new_value = []
for val in value:
if val not in new_value:
new_value.append(val)
value = new_value
return value

View File

@ -397,7 +397,10 @@ class BaseOption(Base):
super(BaseOption, self).__setattr__(name, value)
def impl_getpath(self) -> str:
return self._path
try:
return self._path
except AttributeError:
raise AttributeError(_('"{}" not part of any Config').format(self.impl_get_display_name()))
def impl_has_callback(self) -> bool:
"to know if a callback has been defined or not"

View File

@ -27,6 +27,7 @@ from .option import Option
class BoolOption(Option):
"represents a choice between ``True`` and ``False``"
__slots__ = tuple()
_type = 'boolean'
_display_name = _('boolean')
def _validate(self,

View File

@ -28,6 +28,7 @@ from .option import Option
class BroadcastOption(Option):
__slots__ = tuple()
_type = 'broadcast_address'
_display_name = _('broadcast address')
def _validate(self,

View File

@ -33,6 +33,7 @@ class ChoiceOption(Option):
The option can also have the value ``None``
"""
__slots__ = tuple()
_type = 'choice'
_display_name = _('choice')
def __init__(self,

View File

@ -27,6 +27,7 @@ from .option import Option
class DateOption(Option):
__slots__ = tuple()
_type = 'date'
_display_name = _('date')
def _validate(self,

View File

@ -19,15 +19,14 @@
# the whole pypy projet is under MIT licence
# ____________________________________________________________
import re
from ipaddress import ip_address, IPv4Address
from ipaddress import ip_address
from ..setting import undefined, Undefined, OptionBag
from ..i18n import _
from .option import Option
from .stroption import StrOption
from .ipoption import IPOption
class DomainnameOption(StrOption):
class DomainnameOption(IPOption):
"""represents the choice of a domain name
netbios: for MS domain
hostname: to identify the device
@ -35,6 +34,7 @@ class DomainnameOption(StrOption):
fqdn: with tld, not supported yet
"""
__slots__ = tuple()
_type = 'domainname'
_display_name = _('domain name')
def __init__(self,
@ -43,16 +43,17 @@ class DomainnameOption(StrOption):
default=None,
default_multi=None,
requires=None,
multi=False,
multi: bool=False,
callback=None,
callback_params=None,
validator=None,
validator_params=None,
properties=None,
allow_ip=False,
type_='domainname',
warnings_only=False,
allow_without_dot=False):
allow_ip: bool=False,
cidr: bool=False,
type_: str='domainname',
warnings_only: bool=False,
allow_without_dot=False) -> None:
if type_ not in ['netbios', 'hostname', 'domainname']:
raise ValueError(_('unknown type_ {0} for hostname').format(type_))
@ -72,25 +73,29 @@ class DomainnameOption(StrOption):
else:
regexp = r'((?!-)[a-z0-9-]{{1,{0}}})'.format(self._get_len(type_))
if allow_ip:
regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$'.format(regexp)
if not cidr:
regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))$'.format(regexp)
else:
regexp = r'^(?:{0}|(?:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){{3}}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/[0-9][0-9]))$'.format(regexp)
else:
regexp = r'^{0}$'.format(regexp)
extra['_domain_re'] = re.compile(regexp)
extra['_has_upper'] = re.compile('[A-Z]')
super(DomainnameOption, self).__init__(name,
doc,
default=default,
default_multi=default_multi,
callback=callback,
callback_params=callback_params,
requires=requires,
multi=multi,
validator=validator,
validator_params=validator_params,
properties=properties,
warnings_only=warnings_only,
extra=extra)
super().__init__(name,
doc,
default=default,
default_multi=default_multi,
callback=callback,
callback_params=callback_params,
requires=requires,
multi=multi,
validator=validator,
validator_params=validator_params,
properties=properties,
warnings_only=warnings_only,
cidr=cidr,
_extra=extra)
def _get_len(self, type_):
if type_ == 'netbios':
@ -116,9 +121,10 @@ class DomainnameOption(StrOption):
except ValueError:
pass
else:
if self.impl_get_extra('_allow_ip') is True:
return
raise ValueError(_('must not be an IP'))
if self.impl_get_extra('_allow_ip') is False:
raise ValueError(_('must not be an IP'))
# it's an IP so validate with IPOption
return super()._validate(value, option_bag, current_opt)
part_name_length = self._get_len(self.impl_get_extra('_dom_type'))
if self.impl_get_extra('_dom_type') == 'domainname':
if not self.impl_get_extra('_allow_without_dot') and not "." in value:

View File

@ -28,4 +28,5 @@ class EmailOption(RegexpOption):
__slots__ = tuple()
#https://www.w3.org/TR/html-markup/input.email.html#input.email.attrs.value.single.
_regexp = re.compile(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
_type = 'email'
_display_name = _('email address')

View File

@ -27,4 +27,5 @@ from .stroption import RegexpOption
class FilenameOption(RegexpOption):
__slots__ = tuple()
_regexp = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
_type = 'filename'
_display_name = _('file name')

View File

@ -27,6 +27,7 @@ from .option import Option
class FloatOption(Option):
"represents a choice of a floating point number"
__slots__ = tuple()
_type = 'float'
_display_name = _('float')
def _validate(self,

View File

@ -27,6 +27,7 @@ from .option import Option
class IntOption(Option):
"represents a choice of an integer"
__slots__ = tuple()
_type = 'integer'
_display_name = _('integer')
def __init__(self,

View File

@ -32,6 +32,7 @@ from .networkoption import NetworkOption
class IPOption(StrOption):
"represents the choice of an ip"
__slots__ = tuple()
_type = 'ip'
_display_name = _('IP')
def __init__(self,
@ -49,10 +50,15 @@ class IPOption(StrOption):
private_only=False,
allow_reserved=False,
warnings_only=False,
cidr=False):
extra = {'_private_only': private_only,
'_allow_reserved': allow_reserved,
'_cidr': cidr}
cidr=False,
_extra=None):
if _extra is None:
extra = {}
else:
extra = _extra
extra['_private_only'] = private_only
extra['_allow_reserved'] = allow_reserved
extra['_cidr'] = cidr
super().__init__(name,
doc,
default=default,

View File

@ -19,6 +19,7 @@
# the whole pypy projet is under MIT licence
# ____________________________________________________________
from ipaddress import ip_interface, ip_network
from typing import List
from ..error import ConfigError
from ..setting import undefined, OptionBag, Undefined
@ -30,6 +31,7 @@ from .stroption import StrOption
class NetmaskOption(StrOption):
"represents the choice of a netmask"
__slots__ = tuple()
_type = 'netmask'
_display_name = _('netmask address')
def _validate(self,
@ -49,57 +51,56 @@ class NetmaskOption(StrOption):
raise ValueError()
def _cons_network_netmask(self,
current_opt,
opts,
vals,
warnings_only,
context):
#opts must be (netmask, network) options
current_opt: Option,
opts: List[Option],
vals: List[str],
warnings_only: bool,
context: 'Config'):
if context is undefined and len(vals) != 2:
raise ConfigError(_('network_netmask needs a network and a netmask'))
if None in vals or len(vals) != 2:
return
val_netmask, val_network = vals
opt_netmask, opt_network = opts
try:
ip_network('{0}/{1}'.format(val_network, val_netmask))
except ValueError:
if current_opt == opts[1]:
if current_opt == opt_network:
raise ValueError(_('with netmask "{0}" ("{1}")').format(val_netmask,
opts[0].impl_get_display_name()))
opt_netmask.impl_get_display_name()))
else:
raise ValueError(_('with network "{0}" ("{1}")').format(val_network,
opts[1].impl_get_display_name()))
opt_network.impl_get_display_name()))
def _cons_ip_netmask(self,
current_opt,
opts,
vals,
warnings_only,
context,
_cidr=False):
# opts must be (netmask, ip) options
current_opt: Option,
opts: List[Option],
vals: List[str],
warnings_only: bool,
context: 'config',
_cidr: bool=False):
if context is undefined and len(vals) != 2:
raise ConfigError(_('ip_netmask needs an IP and a netmask'))
if None in vals or len(vals) != 2:
return
msg = None
val_netmask, val_ip = vals
opt_netmask, opt_ip = opts
ip = ip_interface('{0}/{1}'.format(val_ip, val_netmask))
network = ip.network
if ip.ip == network.network_address:
if not _cidr and current_opt == opts[1]:
msg = _('this is a network with netmask "{0}" ("{1}")')
else:
msg = _('IP "{0}" ("{1}") is the network')
elif ip.ip == network.broadcast_address:
if not _cidr and current_opt == opts[1]:
msg = _('this is a broadcast with netmask "{0}" ("{1}")')
else:
msg = _('IP "{0}" ("{1}") is the broadcast')
if msg is not None:
if not _cidr and current_opt == opts[1]:
raise ValueError(msg.format(val_netmask,
opts[0].impl_get_display_name()))
else:
raise ValueError(msg.format(val_ip,
opts[1].impl_get_display_name()))
if not _cidr and current_opt == opt_ip:
if ip.ip == ip.network.network_address:
raise ValueError( _('this is a network with netmask "{0}" ("{1}")'
'').format(val_netmask,
opt_netmask.impl_get_display_name()))
elif ip.ip == ip.network.broadcast_address:
raise ValueError(_('this is a broadcast with netmask "{0}" ("{1}")'
'').format(val_netmask,
opt_netmask.impl_get_display_name()))
else:
if ip.ip == ip.network.network_address:
raise ValueError(_('IP "{0}" ("{1}") is the network'
'').format(val_ip,
opt_ip.impl_get_display_name()))
elif ip.ip == ip.network.broadcast_address:
raise ValueError(_('IP "{0}" ("{1}") is the broadcast'
'').format(val_ip,
opt_ip.impl_get_display_name()))

View File

@ -28,6 +28,7 @@ from .option import Option
class NetworkOption(Option):
"represents the choice of a network"
__slots__ = tuple()
_type = 'network'
_display_name = _('network address')
def __init__(self,

View File

@ -179,6 +179,10 @@ class Option(BaseOption):
def impl_is_dynsymlinkoption(self) -> bool:
return False
def get_type(self) -> str:
# _display_name for compatibility with older version than 3.0rc3
return getattr(self, '_type', self._display_name)
def get_display_type(self) -> str:
return self._display_name
@ -388,13 +392,13 @@ class Option(BaseOption):
def impl_is_leader(self):
leadership = self.impl_get_leadership()
if leadership is None:
return leadership
return self.impl_get_leadership().is_leader(self)
return False
return leadership.is_leader(self)
def impl_is_follower(self):
leadership = self.impl_get_leadership()
if leadership is None:
return leadership
return False
return not leadership.is_leader(self)
def impl_get_leadership(self):

View File

@ -28,6 +28,7 @@ from .stroption import StrOption
class PasswordOption(StrOption):
"represents the choice of a password"
__slots__ = tuple()
_type = 'password'
_display_name = _('password')
def _validate(self,

View File

@ -40,6 +40,7 @@ class PortOption(StrOption):
"""
__slots__ = tuple()
port_re = re.compile(r"^[0-9]*$")
_type = 'port'
_display_name = _('port')
def __init__(self,

View File

@ -29,6 +29,7 @@ from .option import Option
class StrOption(Option):
"represents the choice of a string"
__slots__ = tuple()
_type = 'string'
_display_name = _('string')
def _validate(self,

View File

@ -30,6 +30,7 @@ class URLOption(DomainnameOption):
__slots__ = tuple()
proto_re = re.compile(r'(http|https)://')
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
_type = 'url'
_display_name = _('URL')
def _validate(self,

View File

@ -28,4 +28,5 @@ class UsernameOption(RegexpOption):
__slots__ = tuple()
#regexp build with 'man 8 adduser' informations
_regexp = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
_type = 'username'
_display_name = _('username')

View File

@ -523,6 +523,10 @@ class Settings(object):
is_indexed = False
if option.impl_is_follower():
idx = option_bag.index
if idx is None:
continue
elif option.impl_is_leader() and option_bag.index is None:
continue
elif option.impl_is_multi() and option_bag.index is not None:
is_indexed = True
config_bag = option_bag.config_bag.copy()

View File

@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Tiramisu\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-02-25 08:47+CET\n"
"POT-Creation-Date: 2019-03-05 08:46+CET\n"
"PO-Revision-Date: \n"
"Last-Translator: Emmanuel Garette <egarette@cadoles.com>\n"
"Language-Team: Tiramisu's team <egarette@cadoles.com>\n"
@ -53,35 +53,35 @@ msgstr "l'index est obligatoire pour l'option suiveuse \"{}\""
msgid "unknown method {}"
msgstr "méthode {} inconnue"
#: tiramisu/api.py:346
#: tiramisu/api.py:360
msgid "cannot add this property: \"{0}\""
msgstr "ne peut pas ajouter cette propriété : \"{0}\""
#: tiramisu/api.py:489 tiramisu/config.py:252
#: tiramisu/api.py:503 tiramisu/config.py:252
msgid "can't delete a SymLinkOption"
msgstr "ne peut supprimer une valeur à une SymLinkOption"
#: tiramisu/api.py:622 tiramisu/api.py:1316
#: tiramisu/api.py:636 tiramisu/api.py:1322
msgid "please specify a valid sub function ({})"
msgstr "veuillez spécifier une sous fonction valide ({})"
#: tiramisu/api.py:685 tiramisu/api.py:1139
#: tiramisu/api.py:699 tiramisu/api.py:1145
msgid "unknown list type {}"
msgstr "type de liste inconnue {}"
#: tiramisu/api.py:687 tiramisu/api.py:1141
#: tiramisu/api.py:701 tiramisu/api.py:1147
msgid "unknown group_type: {0}"
msgstr "group_type inconnu: {0}"
#: tiramisu/api.py:968
#: tiramisu/api.py:974
msgid "properties must be a set"
msgstr "une propriété doit être de type set"
#: tiramisu/api.py:974 tiramisu/api.py:996
#: tiramisu/api.py:980 tiramisu/api.py:1002
msgid "unknown when {} (must be in append or remove)"
msgstr "value {} inconsistent (doit être append ou remove)"
#: tiramisu/api.py:986 tiramisu/api.py:1008 tiramisu/config.py:1226
#: tiramisu/api.py:992 tiramisu/api.py:1014 tiramisu/config.py:1227
msgid "unknown type {}"
msgstr "type inconnu {}"
@ -221,20 +221,20 @@ msgid "MetaConfig with optiondescription must have string has child, not {}"
msgstr ""
"MetaConfig avec une optiondescription doit avoir un nom comme enfant, pas {}"
#: tiramisu/config.py:1207
#: tiramisu/config.py:1208
msgid "child must be a Config or MetaConfig"
msgstr "enfant doit être une une Config ou une MetaConfig"
#: tiramisu/config.py:1211
#: tiramisu/config.py:1212
msgid "all config in metaconfig must have the same optiondescription"
msgstr ""
"toutes les configs d'une metaconfig doivent avoir la même optiondescription"
#: tiramisu/config.py:1224
#: tiramisu/config.py:1225
msgid "config name must be uniq in groupconfig for {0}"
msgstr "le nom de la config doit être unique dans un groupconfig pour {0}"
#: tiramisu/config.py:1249
#: tiramisu/config.py:1250
msgid "cannot find the config {}"
msgstr "ne peut pas trouver la config {0}"
@ -250,11 +250,11 @@ msgstr "ou"
msgid " {} "
msgstr " {} "
#: tiramisu/error.py:103 tiramisu/setting.py:559
#: tiramisu/error.py:103 tiramisu/setting.py:563
msgid "property"
msgstr "de la propriété"
#: tiramisu/error.py:105 tiramisu/setting.py:561
#: tiramisu/error.py:105 tiramisu/setting.py:565
msgid "properties"
msgstr "des propriétés"
@ -349,11 +349,15 @@ msgstr "l'attribut {2} de l'objet '{0}' ({1}) est en lecture seule"
msgid "\"{}\" ({}) object attribute \"{}\" is read-only"
msgstr "\"{}\" ({}) l'attribut de l'objet \"{}\" est en lecture seule"
#: tiramisu/option/baseoption.py:447
#: tiramisu/option/baseoption.py:403
msgid "\"{}\" not part of any Config"
msgstr "\"{}\" ne fait pas parti d'une Config"
#: tiramisu/option/baseoption.py:450
msgid "malformed requirements must be an option in option {0}"
msgstr "requirements mal formés doit être une option dans l'option {0}"
#: tiramisu/option/baseoption.py:450
#: tiramisu/option/baseoption.py:453
msgid ""
"malformed requirements multi option must not set as requires of non multi "
"option {0}"
@ -361,59 +365,59 @@ msgstr ""
"requirements mal formés une option multiple ne doit pas être spécifié comme "
"pré-requis à l'option non multiple {0}"
#: tiramisu/option/baseoption.py:483
#: tiramisu/option/baseoption.py:486
msgid ""
"malformed requirements expected must have option and value for option {0}"
msgstr ""
"expected mal formés pour le requirements, doit avoir une option et une "
"valeur pour l'option {0}"
#: tiramisu/option/baseoption.py:490 tiramisu/option/baseoption.py:506
#: tiramisu/option/baseoption.py:493 tiramisu/option/baseoption.py:509
msgid "malformed requirements expected value must be valid for option {0}: {1}"
msgstr ""
"valeur de \"expected\" malformé, doit être valide pour l'option {0} : {1}"
#: tiramisu/option/baseoption.py:520
#: tiramisu/option/baseoption.py:523
msgid ""
"malformed requirements for option: {0} action cannot be force_store_value"
msgstr ""
"requirements mal formés pour l'option : {0} action ne peut pas être "
"force_store_value"
#: tiramisu/option/baseoption.py:528
#: tiramisu/option/baseoption.py:531
msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr ""
"requirements mal formés pour l'option : {0} inverse doit être un booléen"
#: tiramisu/option/baseoption.py:535
#: tiramisu/option/baseoption.py:538
msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr ""
"requirements mal formés pour l'option : {0} transitive doit être booléen"
#: tiramisu/option/baseoption.py:542
#: tiramisu/option/baseoption.py:545
msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr ""
"requirements mal formés pour l'option : {0} same_action doit être un booléen"
#: tiramisu/option/baseoption.py:549
#: tiramisu/option/baseoption.py:552
msgid ""
"malformed requirements for option: \"{0}\" operator must be \"or\" or \"and\""
msgstr ""
"requirements mal formés pour l'option : \"{0}\" l'opérateur doit être \"or\" "
"ou \"and\""
#: tiramisu/option/baseoption.py:561
#: tiramisu/option/baseoption.py:564
msgid "malformed requirements type for option: {0}, must be a dict"
msgstr ""
"type requirements malformé pour l'option : {0}, doit être un dictionnaire"
#: tiramisu/option/baseoption.py:567
#: tiramisu/option/baseoption.py:570
msgid "malformed requirements for option: {0} unknown keys {1}, must only {2}"
msgstr ""
"requirements mal formés pour l'option : {0} clefs inconnues {1}, doit "
"seulement avoir {2}"
#: tiramisu/option/baseoption.py:576
#: tiramisu/option/baseoption.py:579
msgid ""
"malformed requirements for option: {0} require must have option, expected "
"and action keys"
@ -431,7 +435,7 @@ msgstr "adresse broadcast"
#: tiramisu/option/broadcastoption.py:38 tiramisu/option/dateoption.py:37
#: tiramisu/option/domainnameoption.py:113 tiramisu/option/ipoption.py:77
#: tiramisu/option/netmaskoption.py:40 tiramisu/option/networkoption.py:67
#: tiramisu/option/netmaskoption.py:41 tiramisu/option/networkoption.py:67
#: tiramisu/option/passwordoption.py:38 tiramisu/option/portoption.py:106
#: tiramisu/option/urloption.py:40
msgid "invalid string"
@ -653,7 +657,7 @@ msgstr ""
"requirement mal formé pour l'option \"{0}\" ne doit pas être dans une "
"suiveuse pour \"{1}\""
#: tiramisu/option/netmaskoption.py:33
#: tiramisu/option/netmaskoption.py:34
msgid "netmask address"
msgstr "adresse netmask"
@ -661,11 +665,11 @@ msgstr "adresse netmask"
msgid "network_netmask needs a network and a netmask"
msgstr "network_netmask nécessite un réseau et un masque de réseau"
#: tiramisu/option/netmaskoption.py:67
#: tiramisu/option/netmaskoption.py:68
msgid "with netmask \"{0}\" (\"{1}\")"
msgstr "avec le masque \"{0}\" (\"{1}\")"
#: tiramisu/option/netmaskoption.py:70
#: tiramisu/option/netmaskoption.py:71
msgid "with network \"{0}\" (\"{1}\")"
msgstr "avec le réseau \"{0}\" (\"{1}\")"
@ -673,19 +677,19 @@ msgstr "avec le réseau \"{0}\" (\"{1}\")"
msgid "ip_netmask needs an IP and a netmask"
msgstr "ip_netmask nécessite une IP et un masque de réseau"
#: tiramisu/option/netmaskoption.py:91
#: tiramisu/option/netmaskoption.py:90
msgid "this is a network with netmask \"{0}\" (\"{1}\")"
msgstr "c'est une adresse réseau avec le masque \"{0}\" (\"{1}\")"
#: tiramisu/option/netmaskoption.py:93
msgid "IP \"{0}\" (\"{1}\") is the network"
msgstr "IP \"{0}\" (\"{1}\") est le réseau"
#: tiramisu/option/netmaskoption.py:96
#: tiramisu/option/netmaskoption.py:94
msgid "this is a broadcast with netmask \"{0}\" (\"{1}\")"
msgstr "c'est une adresse broadcast avec le masque \"{0}\" (\"{1}\")"
#: tiramisu/option/netmaskoption.py:98
#: tiramisu/option/netmaskoption.py:99
msgid "IP \"{0}\" (\"{1}\") is the network"
msgstr "IP \"{0}\" (\"{1}\") est le réseau"
#: tiramisu/option/netmaskoption.py:103
msgid "IP \"{0}\" (\"{1}\") is the broadcast"
msgstr "IP \"{0}\" (\"{1}\") est l'adresse de broadcast"
@ -831,7 +835,7 @@ msgstr ""
msgid "the dynoption \"{0}\" cannot have \"force_store_value\" property"
msgstr "la dynoption \"{0}\" ne peut avoir la propriété \"force_store_value\""
#: tiramisu/option/optiondescription.py:97 tiramisu/setting.py:639
#: tiramisu/option/optiondescription.py:97 tiramisu/setting.py:643
msgid ""
"a leader ({0}) cannot have \"force_default_on_freeze\" or "
"\"force_metaconfig_on_freeze\" property without \"frozen\""
@ -982,48 +986,48 @@ msgstr ""
"imbrication de requirements mal formés detectée pour l'option : '{0}' avec "
"requirement sur : '{1}'"
#: tiramisu/setting.py:562
#: tiramisu/setting.py:566
msgid ""
"cannot access to option \"{0}\" because required option \"{1}\" has {2} {3}"
msgstr ""
"ne peut accéder à l'option \"{0}\" parce que l'option requise \"{1}\" a {2} "
"{3}"
#: tiramisu/setting.py:586
#: tiramisu/setting.py:590
msgid "the value of \"{0}\" is {1}"
msgstr "la valeur de \"{0}\" est {1}"
#: tiramisu/setting.py:588
#: tiramisu/setting.py:592
msgid "the value of \"{0}\" is not {1}"
msgstr "la valeur de \"{0}\" n'est pas {1}"
#: tiramisu/setting.py:629
#: tiramisu/setting.py:633
msgid "cannot set property {} for option \"{}\" this property is calculated"
msgstr ""
"ne peut ajouter la propriété {} pour l'option \"{}\" cette propriété est "
"calculée"
#: tiramisu/setting.py:634
#: tiramisu/setting.py:638
msgid "can't assign property to the symlinkoption \"{}\""
msgstr "ne peut assigner une propriété à une symlinkoption \"{}\""
#: tiramisu/setting.py:666
#: tiramisu/setting.py:670
msgid "permissive must be a frozenset"
msgstr "une permissive doit être de type frozenset"
#: tiramisu/setting.py:670
#: tiramisu/setting.py:674
msgid "can't assign permissive to the symlinkoption \"{}\""
msgstr "ne peut assigner une permissive à la symlinkoption \"{}\""
#: tiramisu/setting.py:677
#: tiramisu/setting.py:681
msgid "cannot add those permissives: {0}"
msgstr "ne peut ajouter ces permissives : {0}"
#: tiramisu/setting.py:694
#: tiramisu/setting.py:698
msgid "can't reset properties to the symlinkoption \"{}\""
msgstr "ne peut réinitialiser les propriétés de la symlinkoption \"{}\""
#: tiramisu/setting.py:709
#: tiramisu/setting.py:713
msgid "can't reset permissives to the symlinkoption \"{}\""
msgstr "ne peut réinitialiser les permissive de la symlinkoption \"{}\""

View File

@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2019-02-25 08:47+CET\n"
"POT-Creation-Date: 2019-03-05 08:46+CET\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -51,35 +51,35 @@ msgstr ""
msgid "unknown method {}"
msgstr ""
#: tiramisu/api.py:346
#: tiramisu/api.py:360
msgid "cannot add this property: \"{0}\""
msgstr ""
#: tiramisu/api.py:489 tiramisu/config.py:252
#: tiramisu/api.py:503 tiramisu/config.py:252
msgid "can't delete a SymLinkOption"
msgstr ""
#: tiramisu/api.py:622 tiramisu/api.py:1316
#: tiramisu/api.py:636 tiramisu/api.py:1322
msgid "please specify a valid sub function ({})"
msgstr ""
#: tiramisu/api.py:685 tiramisu/api.py:1139
#: tiramisu/api.py:699 tiramisu/api.py:1145
msgid "unknown list type {}"
msgstr ""
#: tiramisu/api.py:687 tiramisu/api.py:1141
#: tiramisu/api.py:701 tiramisu/api.py:1147
msgid "unknown group_type: {0}"
msgstr ""
#: tiramisu/api.py:968
#: tiramisu/api.py:974
msgid "properties must be a set"
msgstr ""
#: tiramisu/api.py:974 tiramisu/api.py:996
#: tiramisu/api.py:980 tiramisu/api.py:1002
msgid "unknown when {} (must be in append or remove)"
msgstr ""
#: tiramisu/api.py:986 tiramisu/api.py:1008 tiramisu/config.py:1226
#: tiramisu/api.py:992 tiramisu/api.py:1014 tiramisu/config.py:1227
msgid "unknown type {}"
msgstr ""
@ -195,19 +195,19 @@ msgstr ""
msgid "MetaConfig with optiondescription must have string has child, not {}"
msgstr ""
#: tiramisu/config.py:1207
#: tiramisu/config.py:1208
msgid "child must be a Config or MetaConfig"
msgstr ""
#: tiramisu/config.py:1211
#: tiramisu/config.py:1212
msgid "all config in metaconfig must have the same optiondescription"
msgstr ""
#: tiramisu/config.py:1224
#: tiramisu/config.py:1225
msgid "config name must be uniq in groupconfig for {0}"
msgstr ""
#: tiramisu/config.py:1249
#: tiramisu/config.py:1250
msgid "cannot find the config {}"
msgstr ""
@ -223,11 +223,11 @@ msgstr ""
msgid " {} "
msgstr ""
#: tiramisu/error.py:103 tiramisu/setting.py:559
#: tiramisu/error.py:103 tiramisu/setting.py:563
msgid "property"
msgstr ""
#: tiramisu/error.py:105 tiramisu/setting.py:561
#: tiramisu/error.py:105 tiramisu/setting.py:565
msgid "properties"
msgstr ""
@ -316,51 +316,55 @@ msgstr ""
msgid "\"{}\" ({}) object attribute \"{}\" is read-only"
msgstr ""
#: tiramisu/option/baseoption.py:447
msgid "malformed requirements must be an option in option {0}"
#: tiramisu/option/baseoption.py:403
msgid "\"{}\" not part of any Config"
msgstr ""
#: tiramisu/option/baseoption.py:450
msgid "malformed requirements must be an option in option {0}"
msgstr ""
#: tiramisu/option/baseoption.py:453
msgid "malformed requirements multi option must not set as requires of non multi option {0}"
msgstr ""
#: tiramisu/option/baseoption.py:483
#: tiramisu/option/baseoption.py:486
msgid "malformed requirements expected must have option and value for option {0}"
msgstr ""
#: tiramisu/option/baseoption.py:490 tiramisu/option/baseoption.py:506
#: tiramisu/option/baseoption.py:493 tiramisu/option/baseoption.py:509
msgid "malformed requirements expected value must be valid for option {0}: {1}"
msgstr ""
#: tiramisu/option/baseoption.py:520
#: tiramisu/option/baseoption.py:523
msgid "malformed requirements for option: {0} action cannot be force_store_value"
msgstr ""
#: tiramisu/option/baseoption.py:528
#: tiramisu/option/baseoption.py:531
msgid "malformed requirements for option: {0} inverse must be boolean"
msgstr ""
#: tiramisu/option/baseoption.py:535
#: tiramisu/option/baseoption.py:538
msgid "malformed requirements for option: {0} transitive must be boolean"
msgstr ""
#: tiramisu/option/baseoption.py:542
#: tiramisu/option/baseoption.py:545
msgid "malformed requirements for option: {0} same_action must be boolean"
msgstr ""
#: tiramisu/option/baseoption.py:549
#: tiramisu/option/baseoption.py:552
msgid "malformed requirements for option: \"{0}\" operator must be \"or\" or \"and\""
msgstr ""
#: tiramisu/option/baseoption.py:561
#: tiramisu/option/baseoption.py:564
msgid "malformed requirements type for option: {0}, must be a dict"
msgstr ""
#: tiramisu/option/baseoption.py:567
#: tiramisu/option/baseoption.py:570
msgid "malformed requirements for option: {0} unknown keys {1}, must only {2}"
msgstr ""
#: tiramisu/option/baseoption.py:576
#: tiramisu/option/baseoption.py:579
msgid "malformed requirements for option: {0} require must have option, expected and action keys"
msgstr ""
@ -374,7 +378,7 @@ msgstr ""
#: tiramisu/option/broadcastoption.py:38 tiramisu/option/dateoption.py:37
#: tiramisu/option/domainnameoption.py:113 tiramisu/option/ipoption.py:77
#: tiramisu/option/netmaskoption.py:40 tiramisu/option/networkoption.py:67
#: tiramisu/option/netmaskoption.py:41 tiramisu/option/networkoption.py:67
#: tiramisu/option/passwordoption.py:38 tiramisu/option/portoption.py:106
#: tiramisu/option/urloption.py:40
msgid "invalid string"
@ -576,7 +580,7 @@ msgstr ""
msgid "malformed requirements option \"{0}\" must not be in follower for \"{1}\""
msgstr ""
#: tiramisu/option/netmaskoption.py:33
#: tiramisu/option/netmaskoption.py:34
msgid "netmask address"
msgstr ""
@ -584,11 +588,11 @@ msgstr ""
msgid "network_netmask needs a network and a netmask"
msgstr ""
#: tiramisu/option/netmaskoption.py:67
#: tiramisu/option/netmaskoption.py:68
msgid "with netmask \"{0}\" (\"{1}\")"
msgstr ""
#: tiramisu/option/netmaskoption.py:70
#: tiramisu/option/netmaskoption.py:71
msgid "with network \"{0}\" (\"{1}\")"
msgstr ""
@ -596,19 +600,19 @@ msgstr ""
msgid "ip_netmask needs an IP and a netmask"
msgstr ""
#: tiramisu/option/netmaskoption.py:91
#: tiramisu/option/netmaskoption.py:90
msgid "this is a network with netmask \"{0}\" (\"{1}\")"
msgstr ""
#: tiramisu/option/netmaskoption.py:93
msgid "IP \"{0}\" (\"{1}\") is the network"
msgstr ""
#: tiramisu/option/netmaskoption.py:96
#: tiramisu/option/netmaskoption.py:94
msgid "this is a broadcast with netmask \"{0}\" (\"{1}\")"
msgstr ""
#: tiramisu/option/netmaskoption.py:98
#: tiramisu/option/netmaskoption.py:99
msgid "IP \"{0}\" (\"{1}\") is the network"
msgstr ""
#: tiramisu/option/netmaskoption.py:103
msgid "IP \"{0}\" (\"{1}\") is the broadcast"
msgstr ""
@ -737,7 +741,7 @@ msgstr ""
msgid "the dynoption \"{0}\" cannot have \"force_store_value\" property"
msgstr ""
#: tiramisu/option/optiondescription.py:97 tiramisu/setting.py:639
#: tiramisu/option/optiondescription.py:97 tiramisu/setting.py:643
msgid "a leader ({0}) cannot have \"force_default_on_freeze\" or \"force_metaconfig_on_freeze\" property without \"frozen\""
msgstr ""
@ -865,43 +869,43 @@ msgstr ""
msgid "malformed requirements imbrication detected for option: '{0}' with requirement on: '{1}'"
msgstr ""
#: tiramisu/setting.py:562
#: tiramisu/setting.py:566
msgid "cannot access to option \"{0}\" because required option \"{1}\" has {2} {3}"
msgstr ""
#: tiramisu/setting.py:586
#: tiramisu/setting.py:590
msgid "the value of \"{0}\" is {1}"
msgstr ""
#: tiramisu/setting.py:588
#: tiramisu/setting.py:592
msgid "the value of \"{0}\" is not {1}"
msgstr ""
#: tiramisu/setting.py:629
#: tiramisu/setting.py:633
msgid "cannot set property {} for option \"{}\" this property is calculated"
msgstr ""
#: tiramisu/setting.py:634
#: tiramisu/setting.py:638
msgid "can't assign property to the symlinkoption \"{}\""
msgstr ""
#: tiramisu/setting.py:666
#: tiramisu/setting.py:670
msgid "permissive must be a frozenset"
msgstr ""
#: tiramisu/setting.py:670
#: tiramisu/setting.py:674
msgid "can't assign permissive to the symlinkoption \"{}\""
msgstr ""
#: tiramisu/setting.py:677
#: tiramisu/setting.py:681
msgid "cannot add those permissives: {0}"
msgstr ""
#: tiramisu/setting.py:694
#: tiramisu/setting.py:698
msgid "can't reset properties to the symlinkoption \"{}\""
msgstr ""
#: tiramisu/setting.py:709
#: tiramisu/setting.py:713
msgid "can't reset permissives to the symlinkoption \"{}\""
msgstr ""