aa
This commit is contained in:
parent
8e743131cd
commit
897d4dd216
36 changed files with 4299 additions and 5314 deletions
File diff suppressed because it is too large
Load diff
|
@ -81,10 +81,10 @@ def test_cache_importation_property():
|
||||||
def test_cache_importation_permissive():
|
def test_cache_importation_permissive():
|
||||||
od1 = make_description()
|
od1 = make_description()
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.option('u2').permissive.set(frozenset(['prop']))
|
cfg.option('u2').permissive.add('prop')
|
||||||
export = cfg.permissive.exportation()
|
export = cfg.permissive.exportation()
|
||||||
assert cfg.option('u2').permissive.get() == {'prop'}
|
assert cfg.option('u2').permissive.get() == {'prop'}
|
||||||
cfg.option('u2').permissive.set(frozenset(['prop', 'prop2']))
|
cfg.option('u2').permissive.add('prop2')
|
||||||
assert cfg.option('u2').permissive.get() == {'prop', 'prop2'}
|
assert cfg.option('u2').permissive.get() == {'prop', 'prop2'}
|
||||||
cfg.permissive.importation(export)
|
cfg.permissive.importation(export)
|
||||||
assert cfg.option('u2').permissive.get() == {'prop'}
|
assert cfg.option('u2').permissive.get() == {'prop'}
|
||||||
|
@ -266,7 +266,7 @@ def test_cache_leadership():
|
||||||
#assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None]
|
#assert cache['ip_admin_eth0.netmask_admin_eth0'][None][0] == [None]
|
||||||
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
|
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
|
||||||
cache = settings.get_cached()
|
cache = settings.get_cached()
|
||||||
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
assert set(cache.keys()) == set(['ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
||||||
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == {0}
|
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == {0}
|
||||||
|
@ -284,7 +284,7 @@ def test_cache_leadership():
|
||||||
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
|
#assert cache['ip_admin_eth0.netmask_admin_eth0'][0][0] is None
|
||||||
#assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None
|
#assert cache['ip_admin_eth0.netmask_admin_eth0'][1][0] is None
|
||||||
cache = settings.get_cached()
|
cache = settings.get_cached()
|
||||||
assert set(cache.keys()) == set([None, 'ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
assert set(cache.keys()) == set(['ip_admin_eth0', 'ip_admin_eth0.ip_admin_eth0', 'ip_admin_eth0.netmask_admin_eth0'])
|
||||||
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
assert set(cache['ip_admin_eth0.ip_admin_eth0'].keys()) == set([None])
|
||||||
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([0, 1])
|
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([0, 1])
|
||||||
|
@ -376,26 +376,22 @@ def test_cache_leader_and_followers():
|
||||||
idx_val2 = None
|
idx_val2 = None
|
||||||
values = cfg._config_bag.context._impl_values_cache
|
values = cfg._config_bag.context._impl_values_cache
|
||||||
settings = cfg._config_bag.context.properties_cache
|
settings = cfg._config_bag.context.properties_cache
|
||||||
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
compare(settings.get_cached(), {'val1': {None: (val1_props, None)},
|
||||||
'val1': {None: (val1_props, None)},
|
'val1.val1': {None: (val1_val1_props, None)},
|
||||||
'val1.val1': {None: (val1_val1_props, None)},
|
})
|
||||||
})
|
|
||||||
# len is 0 so don't get any value
|
# len is 0 so don't get any value
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
|
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
|
||||||
#
|
#
|
||||||
cfg.option('val1.val1').value.set([None])
|
cfg.option('val1.val1').value.set([None])
|
||||||
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
|
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
|
||||||
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
compare(settings.get_cached(), {'val1.val1': {None: ({'empty', 'unique'}, None, True)}})
|
||||||
# 'val1.val1': {None: (val1_val1_props, None)},
|
|
||||||
})
|
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||||
cfg.value.get()
|
cfg.value.get()
|
||||||
#has value
|
#has value
|
||||||
idx_val2 = 0
|
idx_val2 = 0
|
||||||
val_val2 = None
|
val_val2 = None
|
||||||
val_val2_props = {idx_val2: (val1_val2_props, None)}
|
val_val2_props = {idx_val2: (val1_val2_props, None)}
|
||||||
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
compare(settings.get_cached(), {'val1': {None: (val1_props, None)},
|
||||||
'val1': {None: (val1_props, None)},
|
|
||||||
'val1.val1': {None: (val1_val1_props, None)},
|
'val1.val1': {None: (val1_val1_props, None)},
|
||||||
'val1.val2': val_val2_props})
|
'val1.val2': val_val2_props})
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None)},
|
compare(values.get_cached(), {'val1.val1': {None: ([None], None)},
|
||||||
|
@ -404,7 +400,7 @@ def test_cache_leader_and_followers():
|
||||||
cfg.option('val1.val1').value.set([None, None])
|
cfg.option('val1.val1').value.set([None, None])
|
||||||
cfg.value.get()
|
cfg.value.get()
|
||||||
cfg.option('val1.val2', 1).value.set('oui')
|
cfg.option('val1.val2', 1).value.set('oui')
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}})
|
compare(settings.get_cached(), {})
|
||||||
compare(values.get_cached(), {'val1.val2': {1: ('oui', None, True)}})
|
compare(values.get_cached(), {'val1.val2': {1: ('oui', None, True)}})
|
||||||
val1_val2_props = {0: (frozenset([]), None), 1: (frozenset([]), None)}
|
val1_val2_props = {0: (frozenset([]), None), 1: (frozenset([]), None)}
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
@ -428,15 +424,12 @@ def test_cache_leader_callback():
|
||||||
val1_val2_props = frozenset(val1_val2_props)
|
val1_val2_props = frozenset(val1_val2_props)
|
||||||
values = cfg._config_bag.context._impl_values_cache
|
values = cfg._config_bag.context._impl_values_cache
|
||||||
settings = cfg._config_bag.context.properties_cache
|
settings = cfg._config_bag.context.properties_cache
|
||||||
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
compare(settings.get_cached(), {'val1': {None: (val1_props, None)},
|
||||||
'val1': {None: (val1_props, None)},
|
|
||||||
'val1.val1': {None: (val1_val1_props, None)},
|
'val1.val1': {None: (val1_val1_props, None)},
|
||||||
})
|
})
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
|
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
|
||||||
cfg.option('val1.val1').value.set([None])
|
cfg.option('val1.val1').value.set([None])
|
||||||
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
compare(settings.get_cached(), {'val1.val1': {None: ({'unique', 'empty'}, None, True)}})
|
||||||
# 'val1.val1': {None: (val1_val1_props, None)},
|
|
||||||
})
|
|
||||||
|
|
||||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||||
cfg.value.get()
|
cfg.value.get()
|
||||||
|
@ -458,39 +451,34 @@ def test_cache_requires():
|
||||||
settings = cfg._config_bag.context.properties_cache
|
settings = cfg._config_bag.context.properties_cache
|
||||||
assert values.get_cached() == {}
|
assert values.get_cached() == {}
|
||||||
assert cfg.option('ip_address_service').value.get() == None
|
assert cfg.option('ip_address_service').value.get() == None
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||||
'activate_service': {None: (set([]), None)},
|
'ip_address_service': {None: (set([]), None)}})
|
||||||
'ip_address_service': {None: (set([]), None)}})
|
|
||||||
|
|
||||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||||
'activate_service': {None: (True, None)}})
|
'activate_service': {None: (True, None)}})
|
||||||
cfg.value.get()
|
cfg.value.get()
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||||
'activate_service': {None: (set([]), None)},
|
'ip_address_service': {None: (set([]), None)}})
|
||||||
'ip_address_service': {None: (set([]), None)}})
|
|
||||||
|
|
||||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||||
'activate_service': {None: (True, None)}})
|
'activate_service': {None: (True, None)}})
|
||||||
cfg.option('ip_address_service').value.set('1.1.1.1')
|
cfg.option('ip_address_service').value.set('1.1.1.1')
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}})
|
||||||
'activate_service': {None: (set([]), None)}})
|
|
||||||
|
|
||||||
compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}})
|
compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}})
|
||||||
cfg.value.get()
|
cfg.value.get()
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||||
'activate_service': {None: (set([]), None)},
|
'ip_address_service': {None: (set([]), None)}})
|
||||||
'ip_address_service': {None: (set([]), None)}})
|
|
||||||
|
|
||||||
compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)},
|
compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)},
|
||||||
'activate_service': {None: (True, None)}})
|
'activate_service': {None: (True, None)}})
|
||||||
cfg.option('activate_service').value.set(False)
|
cfg.option('activate_service').value.set(False)
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)}})
|
compare(settings.get_cached(), {})
|
||||||
|
|
||||||
compare(values.get_cached(), {'activate_service': {None: (False, None)}})
|
compare(values.get_cached(), {'activate_service': {None: (False, None)}})
|
||||||
cfg.value.get()
|
cfg.value.get()
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||||
'activate_service': {None: (set([]), None)},
|
'ip_address_service': {None: (set(['disabled']), None)}})
|
||||||
'ip_address_service': {None: (set(['disabled']), None)}})
|
|
||||||
|
|
||||||
compare(values.get_cached(), {'activate_service': {None: (False, None)}})
|
compare(values.get_cached(), {'activate_service': {None: (False, None)}})
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
@ -511,22 +499,19 @@ def test_cache_global_properties():
|
||||||
settings = cfg._config_bag.context.properties_cache
|
settings = cfg._config_bag.context.properties_cache
|
||||||
assert values.get_cached() == {}
|
assert values.get_cached() == {}
|
||||||
assert cfg.option('ip_address_service').value.get() == None
|
assert cfg.option('ip_address_service').value.get() == None
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||||
'activate_service': {None: (set([]), None)},
|
'ip_address_service': {None: (set([]), None)}})
|
||||||
'ip_address_service': {None: (set([]), None)}})
|
|
||||||
|
|
||||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||||
'activate_service': {None: (True, None)}})
|
'activate_service': {None: (True, None)}})
|
||||||
cfg.property.remove('disabled')
|
cfg.property.remove('disabled')
|
||||||
assert cfg.option('ip_address_service').value.get() == None
|
assert cfg.option('ip_address_service').value.get() == None
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||||
'activate_service': {None: (set([]), None)},
|
'ip_address_service': {None: (set([]), None)}})
|
||||||
'ip_address_service': {None: (set([]), None)}})
|
|
||||||
cfg.property.add('test')
|
cfg.property.add('test')
|
||||||
assert cfg.option('ip_address_service').value.get() == None
|
assert cfg.option('ip_address_service').value.get() == None
|
||||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'frozen', 'hidden', 'validator', 'warnings', 'test', 'force_store_value']), None)},
|
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||||
'activate_service': {None: (set([]), None)},
|
'ip_address_service': {None: (set([]), None)}})
|
||||||
'ip_address_service': {None: (set([]), None)}})
|
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from py.test import raises
|
|
||||||
|
|
||||||
from .autopath import do_autopath
|
from .autopath import do_autopath
|
||||||
do_autopath()
|
do_autopath()
|
||||||
from .config import config_type, get_config, value_list, global_owner
|
from .config import config_type, get_config, value_list, global_owner, parse_od_get
|
||||||
|
|
||||||
|
from pytest import raises
|
||||||
from tiramisu import ChoiceOption, StrOption, OptionDescription, Config, owners, Calculation, \
|
from tiramisu import ChoiceOption, StrOption, OptionDescription, Config, owners, Calculation, \
|
||||||
undefined, Params, ParamValue, ParamOption
|
undefined, Params, ParamValue, ParamOption
|
||||||
from tiramisu.error import ConfigError
|
from tiramisu.error import ConfigError
|
||||||
|
@ -76,6 +75,29 @@ def test_choiceoption_function(config_type):
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
def test_choiceoption_subfunction(config_type):
|
||||||
|
choice = ChoiceOption('choice', '', values=(Calculation(return_val, Params(ParamValue('val1'))), Calculation(return_val, Params(ParamValue('val2')))))
|
||||||
|
od1 = OptionDescription('od', '', [choice])
|
||||||
|
cfg = Config(od1)
|
||||||
|
cfg.property.read_write()
|
||||||
|
cfg = get_config(cfg, config_type)
|
||||||
|
owner = global_owner(cfg, config_type)
|
||||||
|
assert cfg.option('choice').owner.isdefault()
|
||||||
|
#
|
||||||
|
cfg.option('choice').value.set('val1')
|
||||||
|
assert cfg.option('choice').owner.get() == owner
|
||||||
|
#
|
||||||
|
cfg.option('choice').value.reset()
|
||||||
|
assert cfg.option('choice').owner.isdefault()
|
||||||
|
#
|
||||||
|
with raises(ValueError):
|
||||||
|
cfg.option('choice').value.set('no')
|
||||||
|
assert cfg.option('choice').owner.isdefault()
|
||||||
|
#
|
||||||
|
assert value_list(cfg.option('choice').value.list()) == ('val1', 'val2')
|
||||||
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_choiceoption_function_error():
|
def test_choiceoption_function_error():
|
||||||
choice = ChoiceOption('choice', '', values=Calculation(return_error))
|
choice = ChoiceOption('choice', '', values=Calculation(return_error))
|
||||||
od1 = OptionDescription('od', '', [choice])
|
od1 = OptionDescription('od', '', [choice])
|
||||||
|
@ -262,3 +284,13 @@ def test_choiceoption_calc_not_list():
|
||||||
with raises(ConfigError):
|
with raises(ConfigError):
|
||||||
cfg.option('choice').value.set(['val1'])
|
cfg.option('choice').value.set(['val1'])
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
def test_choiceoption_calc_default_value():
|
||||||
|
var1 = StrOption("var1", '', default="val1")
|
||||||
|
var2 = StrOption("var2", '', default="val2")
|
||||||
|
choice = ChoiceOption("choice", '', values=(Calculation(return_val, Params((ParamOption(var1)))), Calculation(return_val, Params((ParamOption(var2))))), default="val1")
|
||||||
|
od2 = OptionDescription("rougail", '', children=[var1, var2, choice])
|
||||||
|
od1 = OptionDescription("baseoption", "", children=[od2])
|
||||||
|
cfg = Config(od1)
|
||||||
|
assert parse_od_get(cfg.value.get()) == {'rougail.var1': 'val1', 'rougail.var2': 'val2', 'rougail.choice': 'val1'}
|
||||||
|
|
|
@ -26,8 +26,7 @@ def make_description():
|
||||||
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
||||||
stroption = StrOption('str', 'Test string option', default="abc", properties=('mandatory', ))
|
stroption = StrOption('str', 'Test string option', default="abc", properties=('mandatory', ))
|
||||||
boolop = BoolOption('boolop', 'Test boolean option op', default=True, properties=('hidden',))
|
boolop = BoolOption('boolop', 'Test boolean option op', default=True, properties=('hidden',))
|
||||||
wantref_option = BoolOption('wantref', 'Test requires', default=False)
|
wantref_option = BoolOption('wantref', 'Test requires', default=False, informations={'info': 'default value'})
|
||||||
wantref_option.impl_set_information('info', 'default value')
|
|
||||||
wantframework_option = BoolOption('wantframework', 'Test requires',
|
wantframework_option = BoolOption('wantframework', 'Test requires',
|
||||||
default=False)
|
default=False)
|
||||||
|
|
||||||
|
@ -143,11 +142,11 @@ def test_information_config():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.information.get('noinfo')
|
cfg.information.get('noinfo')
|
||||||
assert cfg.information.get('noinfo', 'default') == 'default'
|
assert cfg.information.get('noinfo', 'default') == 'default'
|
||||||
cfg.information.reset('info')
|
cfg.information.remove('info')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.information.get('info')
|
cfg.information.remove('info')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.information.reset('noinfo')
|
cfg.information.remove('noinfo')
|
||||||
assert list(cfg.information.list()) == ['doc']
|
assert list(cfg.information.list()) == ['doc']
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
@ -194,26 +193,23 @@ def test_information_option():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.option('gc.name').information.get('noinfo')
|
cfg.option('gc.name').information.get('noinfo')
|
||||||
assert cfg.option('gc.name').information.get('noinfo', 'default') == 'default'
|
assert cfg.option('gc.name').information.get('noinfo', 'default') == 'default'
|
||||||
cfg.option('gc.name').information.reset('info')
|
cfg.option('gc.name').information.remove('info')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.option('gc.name').information.get('info')
|
cfg.option('gc.name').information.get('info')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.option('gc.name').information.reset('noinfo')
|
cfg.option('gc.name').information.remove('noinfo')
|
||||||
assert list(cfg.option('gc.name').information.list()) == ['doc']
|
assert list(cfg.option('gc.name').information.list()) == ['doc']
|
||||||
#
|
#
|
||||||
assert cfg.option('wantref').information.get('info') == 'default value'
|
assert cfg.option('wantref').information.get('info') == 'default value'
|
||||||
cfg.option('wantref').information.set('info', 'default value')
|
cfg.option('wantref').information.set('info', 'default value')
|
||||||
assert cfg.option('wantref').information.get('info') == 'default value'
|
assert cfg.option('wantref').information.get('info') == 'default value'
|
||||||
cfg.option('wantref').information.reset('info')
|
cfg.option('wantref').information.remove('info')
|
||||||
assert cfg.option('wantref').information.get('info') == 'default value'
|
assert cfg.option('wantref').information.get('info') == 'default value'
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_information_option_2():
|
def test_information_option_2():
|
||||||
i1 = IntOption('test1', '')
|
i1 = IntOption('test1', '', informations={'info': 'value'})
|
||||||
i1.impl_set_information('info', 'value')
|
|
||||||
# it's a dict
|
|
||||||
assert set(i1.impl_list_information()) == {'info', 'doc'}
|
|
||||||
od1 = OptionDescription('test', '', [i1])
|
od1 = OptionDescription('test', '', [i1])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
# it's tuples
|
# it's tuples
|
||||||
|
@ -234,11 +230,11 @@ def test_information_optiondescription():
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.option('gc').information.get('noinfo')
|
cfg.option('gc').information.get('noinfo')
|
||||||
assert cfg.option('gc').information.get('noinfo', 'default') == 'default'
|
assert cfg.option('gc').information.get('noinfo', 'default') == 'default'
|
||||||
cfg.option('gc').information.reset('info')
|
cfg.option('gc').information.remove('info')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.option('gc').information.get('info')
|
cfg.option('gc').information.get('info')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.option('gc').information.reset('noinfo')
|
cfg.option('gc').information.remove('noinfo')
|
||||||
assert list(cfg.option('gc').information.list()) == ['doc']
|
assert list(cfg.option('gc').information.list()) == ['doc']
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
|
@ -412,7 +412,6 @@ def test_help():
|
||||||
cfg = Config(od2)
|
cfg = Config(od2)
|
||||||
cfg.help(_display=False)
|
cfg.help(_display=False)
|
||||||
cfg.config.help(_display=False)
|
cfg.config.help(_display=False)
|
||||||
cfg.option.help(_display=False)
|
|
||||||
cfg.option('o').help(_display=False)
|
cfg.option('o').help(_display=False)
|
||||||
cfg.option('o.s').help(_display=False)
|
cfg.option('o.s').help(_display=False)
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
@ -430,7 +429,7 @@ def test_config_reset():
|
||||||
#
|
#
|
||||||
cfg.option('gc.gc2.bool').value.set(True)
|
cfg.option('gc.gc2.bool').value.set(True)
|
||||||
cfg.option('boolop').property.add('test')
|
cfg.option('boolop').property.add('test')
|
||||||
cfg.option('float').permissive.set(frozenset(['test']))
|
cfg.option('float').permissive.add('test')
|
||||||
cfg.option('wantref').information.set('info', 'info')
|
cfg.option('wantref').information.set('info', 'info')
|
||||||
assert cfg.option('gc.gc2.bool').value.get()
|
assert cfg.option('gc.gc2.bool').value.get()
|
||||||
assert cfg.option('boolop').property.get()
|
assert cfg.option('boolop').property.get()
|
||||||
|
|
|
@ -59,27 +59,27 @@ def test_copy_information():
|
||||||
ncfg = cfg.config.copy()
|
ncfg = cfg.config.copy()
|
||||||
assert ncfg.information.get('key') == 'value'
|
assert ncfg.information.get('key') == 'value'
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_copy_force_store_value():
|
def test_copy_force_store_value():
|
||||||
# od1 = make_description()
|
od1 = make_description()
|
||||||
# conf = Config(od1)
|
conf = Config(od1)
|
||||||
# conf2 = Config(od1)
|
conf2 = Config(od1)
|
||||||
# assert conf.value.exportation() == {}
|
assert conf.value.exportation() == {}
|
||||||
# assert conf2.value.exportation() == {}
|
assert conf2.value.exportation() == {}
|
||||||
# #
|
#
|
||||||
# conf.property.read_write()
|
conf.property.read_write()
|
||||||
# assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||||
# assert conf2.value.exportation() == {}
|
assert conf2.value.exportation() == {}
|
||||||
# #
|
#
|
||||||
# conf2.property.read_only()
|
conf2.property.read_only()
|
||||||
# assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||||
# assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||||
# #
|
#
|
||||||
# conf.option('creole.general.wantref').value.set(True)
|
conf.option('creole.general.wantref').value.set(True)
|
||||||
# assert conf.value.exportation() == {'creole.general.wantref': {None: [True, 'user']}}
|
assert conf.value.exportation() == {'creole.general.wantref': {None: [True, 'user']}}
|
||||||
# assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#def test_copy_force_store_value_metaconfig():
|
#def test_copy_force_store_value_metaconfig():
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -160,57 +160,57 @@ def test_freeze_multi():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
#def test_force_store_value():
|
def test_force_store_value():
|
||||||
# od1 = make_description_freeze()
|
od1 = make_description_freeze()
|
||||||
# cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
# compare(cfg.value.exportation(), {})
|
compare(cfg.value.exportation(), {})
|
||||||
# cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
# compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||||
# cfg.option('bool').value.set(False)
|
cfg.option('bool').value.set(False)
|
||||||
# cfg.option('wantref').value.set(True)
|
cfg.option('wantref').value.set(True)
|
||||||
# cfg.option('bool').value.reset()
|
cfg.option('bool').value.reset()
|
||||||
# compare(cfg.value.exportation(), {'wantref': {None: [True, 'user']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
compare(cfg.value.exportation(), {'wantref': {None: [True, 'user']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||||
# cfg.option('bool').value.set(False)
|
cfg.option('bool').value.set(False)
|
||||||
# cfg.option('wantref').value.reset()
|
cfg.option('wantref').value.reset()
|
||||||
# cfg.option('bool').value.reset()
|
cfg.option('bool').value.reset()
|
||||||
# compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_force_store_value_leadership_sub():
|
def test_force_store_value_leadership_sub():
|
||||||
# b = IntOption('int', 'Test int option', multi=True, properties=('force_store_value',))
|
b = IntOption('int', 'Test int option', multi=True, properties=('force_store_value',))
|
||||||
# c = StrOption('str', 'Test string option', multi=True)
|
c = StrOption('str', 'Test string option', multi=True)
|
||||||
# descr = Leadership("int", "", [b, c])
|
descr = Leadership("int", "", [b, c])
|
||||||
# od1 = OptionDescription('odr', '', [descr])
|
od1 = OptionDescription('odr', '', [descr])
|
||||||
# cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
# cfg.property.read_only()
|
cfg.property.read_only()
|
||||||
# compare(cfg.value.exportation(), {'int.int': {None: [[], 'forced']}})
|
compare(cfg.value.exportation(), {'int.int': {None: [[], 'forced']}})
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_force_store_value_callback():
|
def test_force_store_value_callback():
|
||||||
# b = IntOption('int', 'Test int option', Calculation(return_val), properties=('force_store_value',))
|
b = IntOption('int', 'Test int option', Calculation(return_val), properties=('force_store_value',))
|
||||||
# od1 = OptionDescription("int", "", [b])
|
od1 = OptionDescription("int", "", [b])
|
||||||
# cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
# cfg.property.read_only()
|
cfg.property.read_only()
|
||||||
# compare(cfg.value.exportation(), {'int': {None: [1, 'forced']}})
|
compare(cfg.value.exportation(), {'int': {None: [1, 'forced']}})
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_force_store_value_callback_params():
|
def test_force_store_value_callback_params():
|
||||||
# b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamValue(2)})), properties=('force_store_value',))
|
b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamValue(2)})), properties=('force_store_value',))
|
||||||
# od1 = OptionDescription("int", "", [b])
|
od1 = OptionDescription("int", "", [b])
|
||||||
# cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
# cfg.property.read_only()
|
cfg.property.read_only()
|
||||||
# compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_force_store_value_callback_params_with_opt():
|
def test_force_store_value_callback_params_with_opt():
|
||||||
# a = IntOption('val1', "", 2)
|
a = IntOption('val1', "", 2)
|
||||||
# b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamOption(a)})), properties=('force_store_value',))
|
b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamOption(a)})), properties=('force_store_value',))
|
||||||
# od1 = OptionDescription("int", "", [a, b])
|
od1 = OptionDescription("int", "", [a, b])
|
||||||
# cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
# cfg.property.read_only()
|
cfg.property.read_only()
|
||||||
# compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
|
@ -159,7 +159,7 @@ def test_iter_on_empty_group():
|
||||||
od1 = OptionDescription("name", "descr", [])
|
od1 = OptionDescription("name", "descr", [])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
result = list(cfg.option.list())
|
result = list(cfg.list())
|
||||||
assert result == []
|
assert result == []
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ def test_leader_list(config_type):
|
||||||
od1 = OptionDescription('od', '', [interface1])
|
od1 = OptionDescription('od', '', [interface1])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg = get_config(cfg, config_type)
|
cfg = get_config(cfg, config_type)
|
||||||
ret = cfg.option.list()
|
ret = cfg.list()
|
||||||
assert len(ret) == 1
|
assert len(ret) == 1
|
||||||
assert ret[0].name() == 'leadership'
|
assert ret[0].name() == 'leadership'
|
||||||
#
|
#
|
||||||
|
@ -983,65 +983,65 @@ def test_follower_not_multi():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
#def test_follower_force_store_value_none():
|
def test_follower_force_store_value_none():
|
||||||
# ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
||||||
# netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('force_store_value',))
|
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('force_store_value',))
|
||||||
# interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||||
# od1 = OptionDescription('od', '', [interface0])
|
od1 = OptionDescription('od', '', [interface0])
|
||||||
# od2 = OptionDescription('toto', '', [od1])
|
od2 = OptionDescription('toto', '', [od1])
|
||||||
# cfg = Config(od2)
|
cfg = Config(od2)
|
||||||
# cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
# assert cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
assert cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_follower_force_store_value():
|
def test_follower_force_store_value():
|
||||||
# ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
||||||
# netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
|
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
|
||||||
# interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||||
# od1 = OptionDescription('od', '', [interface0])
|
od1 = OptionDescription('od', '', [interface0])
|
||||||
# od2 = OptionDescription('toto', '', [od1])
|
od2 = OptionDescription('toto', '', [od1])
|
||||||
# cfg = Config(od2)
|
cfg = Config(od2)
|
||||||
# cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_follower_force_store_value_read_only():
|
def test_follower_force_store_value_read_only():
|
||||||
# ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
||||||
# netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
|
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
|
||||||
# interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||||
# od1 = OptionDescription('od', '', [interface0])
|
od1 = OptionDescription('od', '', [interface0])
|
||||||
# od2 = OptionDescription('toto', '', [od1])
|
od2 = OptionDescription('toto', '', [od1])
|
||||||
# cfg = Config(od2)
|
cfg = Config(od2)
|
||||||
# cfg.property.read_only()
|
cfg.property.read_only()
|
||||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_follower_force_store_value_reset():
|
def test_follower_force_store_value_reset():
|
||||||
# ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
|
||||||
# netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
|
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
|
||||||
# interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||||
# od1 = OptionDescription('od', '', [interface0])
|
od1 = OptionDescription('od', '', [interface0])
|
||||||
# od2 = OptionDescription('toto', '', [od1])
|
od2 = OptionDescription('toto', '', [od1])
|
||||||
# cfg = Config(od2)
|
cfg = Config(od2)
|
||||||
# cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
# cfg.option('od.interface0.ip_admin_eth0').value.set(['1.1.1.1', '192.168.0.0'])
|
cfg.option('od.interface0.ip_admin_eth0').value.set(['1.1.1.1', '192.168.0.0'])
|
||||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 1).owner.isdefault()
|
assert not cfg.option('od.interface0.netmask_admin_eth0', 1).owner.isdefault()
|
||||||
# #
|
#
|
||||||
# cfg.option('od.interface0.netmask_admin_eth0', 1).value.reset()
|
cfg.option('od.interface0.netmask_admin_eth0', 1).value.reset()
|
||||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 1).owner.isdefault()
|
assert not cfg.option('od.interface0.netmask_admin_eth0', 1).owner.isdefault()
|
||||||
# #
|
#
|
||||||
# cfg.option('od.interface0.ip_admin_eth0').value.pop(0)
|
cfg.option('od.interface0.ip_admin_eth0').value.pop(0)
|
||||||
# cfg.option('od.interface0.ip_admin_eth0').value.pop(0)
|
cfg.option('od.interface0.ip_admin_eth0').value.pop(0)
|
||||||
# assert cfg.option('od.interface0.ip_admin_eth0').value.get() == []
|
assert cfg.option('od.interface0.ip_admin_eth0').value.get() == []
|
||||||
# cfg.option('od.interface0.ip_admin_eth0').value.reset()
|
cfg.option('od.interface0.ip_admin_eth0').value.reset()
|
||||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||||
## assert not list_sessions()
|
# assert not list_sessions()
|
||||||
#
|
|
||||||
#
|
|
||||||
#def test_follower_properties():
|
#def test_follower_properties():
|
||||||
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
|
ip_admin_eth0 = StrOption('ip_admin_eth0', "ip réseau autorisé", multi=True)
|
||||||
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('aproperty',))
|
netmask_admin_eth0 = StrOption('netmask_admin_eth0', "masque du sous-réseau", multi=True, properties=('aproperty',))
|
||||||
|
|
|
@ -34,20 +34,6 @@ def test_option_valid_name():
|
||||||
i = SymLinkOption("test1", i)
|
i = SymLinkOption("test1", i)
|
||||||
|
|
||||||
|
|
||||||
def test_option_get_information():
|
|
||||||
description = "it's ok"
|
|
||||||
string = 'some informations'
|
|
||||||
i = IntOption('test', description)
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
i.impl_get_information('noinfo')
|
|
||||||
i.impl_set_information('info', string)
|
|
||||||
assert i.impl_get_information('info') == string
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
i.impl_get_information('noinfo')
|
|
||||||
assert i.impl_get_information('noinfo', 'default') == 'default'
|
|
||||||
assert i.impl_get_information('doc') == description
|
|
||||||
|
|
||||||
|
|
||||||
def test_option_get_information_config():
|
def test_option_get_information_config():
|
||||||
description = "it's ok"
|
description = "it's ok"
|
||||||
string = 'some informations'
|
string = 'some informations'
|
||||||
|
@ -55,21 +41,16 @@ def test_option_get_information_config():
|
||||||
od = OptionDescription('od', '', [i])
|
od = OptionDescription('od', '', [i])
|
||||||
cfg = Config(od)
|
cfg = Config(od)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
i.impl_get_information('noinfo')
|
cfg.option('test').information.get('noinfo')
|
||||||
with pytest.raises(AttributeError):
|
assert cfg.option('test').information.get('noinfo', 'default') == 'default'
|
||||||
i.impl_set_information('info', string)
|
assert cfg.option('test').information.get('doc') == description
|
||||||
with pytest.raises(ValueError):
|
|
||||||
i.impl_get_information('noinfo')
|
|
||||||
assert i.impl_get_information('noinfo', 'default') == 'default'
|
|
||||||
assert i.impl_get_information('doc') == description
|
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_option_unknown():
|
def test_option_unknown():
|
||||||
description = "it's ok"
|
description = "it's ok"
|
||||||
string = 'some informations'
|
string = 'some informations'
|
||||||
i = IntOption('test', description)
|
i = IntOption('test', description, informations={'noinfo': 'optdefault'})
|
||||||
i.impl_set_information('noinfo', 'optdefault')
|
|
||||||
od = OptionDescription('od', '', [i])
|
od = OptionDescription('od', '', [i])
|
||||||
cfg = Config(od)
|
cfg = Config(od)
|
||||||
#
|
#
|
||||||
|
@ -93,8 +74,7 @@ def test_option_description():
|
||||||
def test_option_get_information_default():
|
def test_option_get_information_default():
|
||||||
description = "it's ok"
|
description = "it's ok"
|
||||||
string = 'some informations'
|
string = 'some informations'
|
||||||
i = IntOption('test', description)
|
i = IntOption('test', description, informations={'noinfo': 'optdefault'})
|
||||||
i.impl_set_information('noinfo', 'optdefault')
|
|
||||||
od = OptionDescription('od', '', [i])
|
od = OptionDescription('od', '', [i])
|
||||||
cfg = Config(od)
|
cfg = Config(od)
|
||||||
#
|
#
|
||||||
|
@ -108,32 +88,30 @@ def test_option_get_information_default():
|
||||||
def test_option_get_information_config2():
|
def test_option_get_information_config2():
|
||||||
description = "it's ok"
|
description = "it's ok"
|
||||||
string = 'some informations'
|
string = 'some informations'
|
||||||
i = IntOption('test', description)
|
i = IntOption('test', description, informations={'info': string})
|
||||||
i.impl_set_information('info', string)
|
|
||||||
od = OptionDescription('od', '', [i])
|
od = OptionDescription('od', '', [i])
|
||||||
cfg = Config(od)
|
cfg = Config(od)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
i.impl_get_information('noinfo')
|
cfg.option('test').information.get('noinfo')
|
||||||
with pytest.raises(AttributeError):
|
assert cfg.option('test').information.get('info') == string
|
||||||
i.impl_set_information('info', 'hello')
|
|
||||||
assert i.impl_get_information('info') == string
|
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
i.impl_get_information('noinfo')
|
cfg.option('test').information.get('noinfo')
|
||||||
assert i.impl_get_information('noinfo', 'default') == 'default'
|
assert cfg.option('test').information.get('noinfo', 'default') == 'default'
|
||||||
assert i.impl_get_information('doc') == description
|
assert cfg.option('test').information.get('doc') == description
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_optiondescription_get_information():
|
def test_optiondescription_get_information():
|
||||||
description = "it's ok"
|
description = "it's ok"
|
||||||
string = 'some informations'
|
string = 'some informations'
|
||||||
o = OptionDescription('test', description, [])
|
o = OptionDescription('test', description, [], informations={'info': string})
|
||||||
o.impl_set_information('info', string)
|
od = OptionDescription('od', '', [o])
|
||||||
assert o.impl_get_information('info') == string
|
cfg = Config(od)
|
||||||
|
assert cfg.option('test').information.get('info') == string
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
o.impl_get_information('noinfo')
|
cfg.option('test').information.get('noinfo')
|
||||||
assert o.impl_get_information('noinfo', 'default') == 'default'
|
assert cfg.option('test').information.get('noinfo', 'default') == 'default'
|
||||||
assert o.impl_get_information('doc') == description
|
assert cfg.option('test').information.get('doc') == description
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -218,7 +196,7 @@ def test_optiondescription_group():
|
||||||
od3.impl_set_group_type(groups.notfamily)
|
od3.impl_set_group_type(groups.notfamily)
|
||||||
od2 = OptionDescription('od', '', [od1, od3])
|
od2 = OptionDescription('od', '', [od1, od3])
|
||||||
cfg = Config(od2)
|
cfg = Config(od2)
|
||||||
assert len(list(cfg.option.list())) == 2
|
assert len(list(cfg.list())) == 2
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -415,8 +415,7 @@ def test_callback_information(config_type):
|
||||||
|
|
||||||
def test_callback_information2(config_type):
|
def test_callback_information2(config_type):
|
||||||
val1 = StrOption('val1', "", Calculation(return_value, Params(ParamSelfInformation('information', 'no_value'))))
|
val1 = StrOption('val1', "", Calculation(return_value, Params(ParamSelfInformation('information', 'no_value'))))
|
||||||
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamSelfInformation('information'))))
|
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamSelfInformation('information'))), informations={'information': 'new_value'})
|
||||||
val2.impl_set_information('information', 'new_value')
|
|
||||||
val3 = StrOption('val3', "", Calculation(return_value, Params(ParamSelfInformation('information'))))
|
val3 = StrOption('val3', "", Calculation(return_value, Params(ParamSelfInformation('information'))))
|
||||||
od1 = OptionDescription('rootconfig', '', [val1, val2, val3])
|
od1 = OptionDescription('rootconfig', '', [val1, val2, val3])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
|
@ -432,9 +431,8 @@ def test_callback_information2(config_type):
|
||||||
|
|
||||||
|
|
||||||
def test_callback_information3(config_type):
|
def test_callback_information3(config_type):
|
||||||
val1 = StrOption('val1', "")
|
val1 = StrOption('val1', "", informations={'information': 'new_value'})
|
||||||
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamInformation('information', option=val1))))
|
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamInformation('information', option=val1))))
|
||||||
val1.impl_set_information('information', 'new_value')
|
|
||||||
od1 = OptionDescription('rootconfig', '', [val1, val2])
|
od1 = OptionDescription('rootconfig', '', [val1, val2])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
|
@ -1691,3 +1689,38 @@ def test_calc_dependencies(config_type):
|
||||||
def test_callback__kwargs_wrong(config_type):
|
def test_callback__kwargs_wrong(config_type):
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
Params(kwargs='string')
|
Params(kwargs='string')
|
||||||
|
|
||||||
|
|
||||||
|
def test_callback_information_parent(config_type):
|
||||||
|
information = ParamInformation('information')
|
||||||
|
val1 = StrOption('val1', "", Calculation(return_value, Params(information)))
|
||||||
|
od2 = OptionDescription('od', '', [val1], informations={'information': 'new_value'})
|
||||||
|
information.set_option(od2)
|
||||||
|
od1 = OptionDescription('rootconfig', '', [od2])
|
||||||
|
cfg = Config(od1)
|
||||||
|
cfg.property.read_write()
|
||||||
|
cfg = get_config(cfg, config_type)
|
||||||
|
assert cfg.option('od.val1').value.get() == 'new_value'
|
||||||
|
cfg.option('od').information.set('information', 'new_value2')
|
||||||
|
assert cfg.option('od.val1').value.get() == 'new_value2'
|
||||||
|
|
||||||
|
|
||||||
|
def test_callback_information_redefined(config_type):
|
||||||
|
val1 = StrOption('val1', "")
|
||||||
|
information = ParamInformation('information', option=val1)
|
||||||
|
val2 = StrOption('val2', "", Calculation(return_value, Params(information)))
|
||||||
|
od2 = OptionDescription('od', '', [val1, val2], informations={'information': 'new_value'})
|
||||||
|
with pytest.raises(ConfigError):
|
||||||
|
information.set_option(od2)
|
||||||
|
|
||||||
|
|
||||||
|
def test_callback_information_redefined_after(config_type):
|
||||||
|
information = ParamInformation('information')
|
||||||
|
val1 = StrOption('val1', "", Calculation(return_value, Params(information)))
|
||||||
|
od2 = OptionDescription('od', '', [val1], informations={'information': 'new_value'})
|
||||||
|
od1 = OptionDescription('rootconfig', '', [od2])
|
||||||
|
cfg = Config(od1)
|
||||||
|
cfg.property.read_write()
|
||||||
|
cfg = get_config(cfg, config_type)
|
||||||
|
with pytest.raises(ConfigError):
|
||||||
|
information.set_option(od2)
|
||||||
|
|
|
@ -166,28 +166,6 @@ def test_force_default_on_freeze_multi():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_force_default_on_freeze_leader_frozen():
|
|
||||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_default_on_freeze', 'frozen'))
|
|
||||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
|
||||||
descr = Leadership("dummy1", "", [dummy1, dummy2])
|
|
||||||
od1 = OptionDescription("root", "", [descr])
|
|
||||||
cfg = Config(od1)
|
|
||||||
with pytest.raises(LeadershipError):
|
|
||||||
cfg.option('dummy1.dummy1').property.remove('frozen')
|
|
||||||
# assert not list_sessions()
|
|
||||||
|
|
||||||
|
|
||||||
def test_force_metaconfig_on_freeze_leader_frozen():
|
|
||||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze', 'frozen'))
|
|
||||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
|
||||||
descr = Leadership("dummy1", "", [dummy1, dummy2])
|
|
||||||
od1 = OptionDescription("root", "", [descr])
|
|
||||||
cfg = Config(od1)
|
|
||||||
with pytest.raises(LeadershipError):
|
|
||||||
cfg.option('dummy1.dummy1').property.remove('frozen')
|
|
||||||
# assert not list_sessions()
|
|
||||||
|
|
||||||
|
|
||||||
def test_force_default_on_freeze_follower(config_type):
|
def test_force_default_on_freeze_follower(config_type):
|
||||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('notunique',))
|
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('notunique',))
|
||||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
|
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
|
||||||
|
|
|
@ -82,7 +82,7 @@ def test_mod_read_only_write():
|
||||||
'empty',
|
'empty',
|
||||||
}
|
}
|
||||||
#
|
#
|
||||||
config.property.setdefault(frozenset(['cache']))
|
# config.property.setdefault(frozenset(['cache']))
|
||||||
config.property.setdefault(type='read_only', when='append', properties=frozenset(['disabled']))
|
config.property.setdefault(type='read_only', when='append', properties=frozenset(['disabled']))
|
||||||
config.property.setdefault(type='read_only', when='remove', properties=frozenset(['hidden']))
|
config.property.setdefault(type='read_only', when='remove', properties=frozenset(['hidden']))
|
||||||
config.property.setdefault(type='read_write', when='append', properties=frozenset(['disabled', 'hidden']))
|
config.property.setdefault(type='read_write', when='append', properties=frozenset(['disabled', 'hidden']))
|
||||||
|
@ -94,7 +94,7 @@ def test_mod_read_only_write():
|
||||||
with pytest.raises(TypeError):
|
with pytest.raises(TypeError):
|
||||||
config.property.setdefault(type='read_only', when='append', properties=['disabled'])
|
config.property.setdefault(type='read_only', when='append', properties=['disabled'])
|
||||||
|
|
||||||
assert config.property.default() == {'cache'}
|
assert config.property.default() == {'warnings', 'validator', 'cache'}
|
||||||
assert config.property.default('read_only', 'append') == {'disabled'}
|
assert config.property.default('read_only', 'append') == {'disabled'}
|
||||||
assert config.property.default('read_only', 'remove') == {'hidden'}
|
assert config.property.default('read_only', 'remove') == {'hidden'}
|
||||||
assert config.property.default('read_write', 'append') == {'disabled',
|
assert config.property.default('read_write', 'append') == {'disabled',
|
||||||
|
@ -102,11 +102,11 @@ def test_mod_read_only_write():
|
||||||
assert config.property.default('read_write', 'remove') == set([])
|
assert config.property.default('read_write', 'remove') == set([])
|
||||||
#
|
#
|
||||||
config.property.read_only()
|
config.property.read_only()
|
||||||
assert config.property.get() == {'cache', 'disabled'}
|
assert config.property.get() == {'warnings', 'validator', 'cache', 'disabled'}
|
||||||
config.property.read_write()
|
config.property.read_write()
|
||||||
assert config.property.get() == {'cache', 'disabled', 'hidden'}
|
assert config.property.get() == {'warnings', 'validator', 'cache', 'disabled', 'hidden'}
|
||||||
config.property.read_only()
|
config.property.read_only()
|
||||||
assert config.property.get() == {'cache', 'disabled'}
|
assert config.property.get() == {'warnings', 'validator', 'cache', 'disabled'}
|
||||||
#
|
#
|
||||||
assert config2.property.default() == {'cache', 'validator', 'warnings'}
|
assert config2.property.default() == {'cache', 'validator', 'warnings'}
|
||||||
assert config2.property.default('read_only', 'append') == {'frozen',
|
assert config2.property.default('read_only', 'append') == {'frozen',
|
||||||
|
@ -138,6 +138,19 @@ def test_mod_read_only_write():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
def test_setting_tree(config_type):
|
||||||
|
s = StrOption("string", "", default=["string", "sdfsdf"], default_multi="prout", multi=True)
|
||||||
|
od4 = OptionDescription("option4", "", [s])
|
||||||
|
od3 = OptionDescription("option3", "", [od4])
|
||||||
|
od2 = OptionDescription("option2", "", [od3], properties=('hidden',))
|
||||||
|
od1 = OptionDescription("root", "", [od2])
|
||||||
|
cfg = Config(od1)
|
||||||
|
cfg = get_config(cfg, config_type)
|
||||||
|
cfg.property.read_write()
|
||||||
|
with pytest.raises(PropertiesOptionError):
|
||||||
|
cfg.option('option2.option3.option4.string').value.get()
|
||||||
|
|
||||||
|
|
||||||
def test_setitem(config_type):
|
def test_setitem(config_type):
|
||||||
s = StrOption("string", "", default=["string", "sdfsdf"], default_multi="prout", multi=True)
|
s = StrOption("string", "", default=["string", "sdfsdf"], default_multi="prout", multi=True)
|
||||||
od1 = OptionDescription("options", "", [s])
|
od1 = OptionDescription("options", "", [s])
|
||||||
|
@ -365,8 +378,7 @@ def test_apply_requires_from_config():
|
||||||
with pytest.raises(PropertiesOptionError):
|
with pytest.raises(PropertiesOptionError):
|
||||||
cfg.option('opt.str').value.get()
|
cfg.option('opt.str').value.get()
|
||||||
assert 'hidden' in cfg.forcepermissive.option('opt.str').property.get()
|
assert 'hidden' in cfg.forcepermissive.option('opt.str').property.get()
|
||||||
assert 'hidden' not in cfg.forcepermissive.option('opt.str').properties()
|
assert 'hidden' not in cfg.forcepermissive.option('opt.str').property.get(only_raises=True)
|
||||||
assert 'hidden' not in cfg.forcepermissive.option('opt.str').properties(only_raises=True)
|
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -386,8 +398,7 @@ def test_apply_requires_with_disabled():
|
||||||
cfg.option('int').value.set(1)
|
cfg.option('int').value.set(1)
|
||||||
with pytest.raises(PropertiesOptionError):
|
with pytest.raises(PropertiesOptionError):
|
||||||
cfg.option('opt.str').value.get()
|
cfg.option('opt.str').value.get()
|
||||||
assert 'disabled' not in cfg.unrestraint.option('opt.str').properties()
|
assert 'disabled' not in cfg.unrestraint.option('opt.str').property.get(only_raises=True, apply_requires=False)
|
||||||
assert 'disabled' not in cfg.unrestraint.option('opt.str').properties(only_raises=True)
|
|
||||||
assert 'disabled' in cfg.unrestraint.option('opt.str').property.get()
|
assert 'disabled' in cfg.unrestraint.option('opt.str').property.get()
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
@ -607,7 +618,7 @@ def test_properties_get_add_reset():
|
||||||
cfg.property.add('frozen')
|
cfg.property.add('frozen')
|
||||||
assert cfg.property.get() == {'validator', 'warnings', 'cache', 'frozen'}
|
assert cfg.property.get() == {'validator', 'warnings', 'cache', 'frozen'}
|
||||||
cfg.property.reset()
|
cfg.property.reset()
|
||||||
assert cfg.property.get() == {'validator', 'warnings', 'cache'}
|
assert cfg.property.get() == frozenset()
|
||||||
|
|
||||||
|
|
||||||
def test_reset_properties_force_store_value():
|
def test_reset_properties_force_store_value():
|
||||||
|
@ -615,28 +626,25 @@ def test_reset_properties_force_store_value():
|
||||||
gcgroup = OptionDescription('gc', '', [gcdummy])
|
gcgroup = OptionDescription('gc', '', [gcdummy])
|
||||||
od1 = OptionDescription('tiramisu', '', [gcgroup])
|
od1 = OptionDescription('tiramisu', '', [gcgroup])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
assert cfg.property.exportation() == {}
|
assert cfg.property.exportation() == {None: {None: frozenset({'validator', 'warnings', 'cache'})}}
|
||||||
cfg.property.add('frozen')
|
cfg.property.add('frozen')
|
||||||
assert cfg.property.exportation() == \
|
assert cfg.property.exportation() == \
|
||||||
{None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}}
|
{None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}}
|
||||||
cfg.property.reset()
|
cfg.property.reset()
|
||||||
assert cfg.property.exportation() == {None: {}}
|
assert cfg.property.exportation() == {None: {}}
|
||||||
cfg.option('gc.dummy').property.add('test')
|
cfg.option('gc.dummy').property.add('test')
|
||||||
assert cfg.property.exportation() == {None: {}, 'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
assert cfg.property.exportation() == {None: {}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||||
cfg.property.reset()
|
cfg.property.reset()
|
||||||
assert cfg.property.exportation() == {None: {}, 'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
assert cfg.property.exportation() == {None: {}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||||
cfg.property.add('frozen')
|
cfg.property.add('frozen')
|
||||||
assert cfg.property.exportation() == \
|
assert cfg.property.exportation() == \
|
||||||
{None: {None: set(('frozen', 'validator', 'cache', 'warnings'))},
|
{None: {None: frozenset({'frozen'})}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||||
'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
|
||||||
cfg.property.add('frozen')
|
cfg.property.add('frozen')
|
||||||
assert cfg.property.exportation() == \
|
assert cfg.property.exportation() == \
|
||||||
{None: {None: set(('frozen', 'validator', 'cache', 'warnings'))},
|
{None: {None: frozenset({'frozen'})}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||||
'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
|
||||||
cfg.option('gc.dummy').property.add('test')
|
cfg.option('gc.dummy').property.add('test')
|
||||||
assert cfg.property.exportation() == \
|
assert cfg.property.exportation() == \
|
||||||
{None: {None: set(('frozen', 'validator', 'cache', 'warnings'))},
|
{None: {None: frozenset({'frozen'})}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||||
'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -666,7 +674,7 @@ def test_set_modified_value():
|
||||||
gcgroup = OptionDescription('gc', '', [gcdummy])
|
gcgroup = OptionDescription('gc', '', [gcdummy])
|
||||||
od1 = OptionDescription('tiramisu', '', [gcgroup])
|
od1 = OptionDescription('tiramisu', '', [gcgroup])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
assert cfg.property.exportation() == {}
|
assert cfg.property.exportation() == {None: {None: frozenset({'warnings', 'validator', 'cache'})}}
|
||||||
cfg.property.importation({None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}})
|
cfg.property.importation({None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}})
|
||||||
assert cfg.property.exportation() == \
|
assert cfg.property.exportation() == \
|
||||||
{None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}}
|
{None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}}
|
||||||
|
|
|
@ -64,7 +64,10 @@ def test_is_hidden(config_type):
|
||||||
|
|
||||||
|
|
||||||
def test_group_is_hidden(config_type):
|
def test_group_is_hidden(config_type):
|
||||||
od1 = make_description()
|
gcdummy = BoolOption('dummy', 'dummy', default=False, properties=(('hidden'),))
|
||||||
|
floatoption = FloatOption('float', 'Test float option', default=2.3)
|
||||||
|
gcgroup = OptionDescription('gc', '', [gcdummy, floatoption])
|
||||||
|
od1 = OptionDescription('trs', '', [gcgroup])
|
||||||
cfg_ori = Config(od1)
|
cfg_ori = Config(od1)
|
||||||
cfg_ori.property.read_write()
|
cfg_ori.property.read_write()
|
||||||
cfg_ori.option('gc').property.add('hidden')
|
cfg_ori.option('gc').property.add('hidden')
|
||||||
|
@ -73,14 +76,14 @@ def test_group_is_hidden(config_type):
|
||||||
cfg.option('gc.dummy').value.get()
|
cfg.option('gc.dummy').value.get()
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
assert 'hidden' in cfg_ori.forcepermissive.option('gc').property.get()
|
assert 'hidden' in cfg_ori.option('gc').property.get()
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
with pytest.raises(PropertiesOptionError):
|
with pytest.raises(PropertiesOptionError):
|
||||||
cfg.option('gc.float').value.get()
|
cfg.option('gc.float').value.get()
|
||||||
# manually set the subconfigs to "show"
|
# manually set the subconfigs to "show"
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.forcepermissive.option('gc').property.remove('hidden')
|
cfg_ori.option('gc').property.remove('hidden')
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
assert not 'hidden' in cfg.option('gc').property.get()
|
assert not 'hidden' in cfg.option('gc').property.get()
|
||||||
assert cfg.option('gc.float').value.get() == 2.3
|
assert cfg.option('gc.float').value.get() == 2.3
|
||||||
|
|
|
@ -1260,18 +1260,24 @@ def test_consistency_not_equal_has_dependency():
|
||||||
def test_validator_information(config_type):
|
def test_validator_information(config_type):
|
||||||
opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params((ParamSelfInformation('key'), ParamValue('yes'))))], default='val')
|
opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params((ParamSelfInformation('key'), ParamValue('yes'))))], default='val')
|
||||||
opt2 = StrOption('opt2', '', validators=[Calculation(return_true, Params((ParamInformation('key'), ParamValue('yes'))))], default='val')
|
opt2 = StrOption('opt2', '', validators=[Calculation(return_true, Params((ParamInformation('key'), ParamValue('yes'))))], default='val')
|
||||||
od1 = OptionDescription('root', '', [opt1, opt2])
|
opt3 = StrOption('opt3', '', validators=[Calculation(return_true, Params((ParamInformation('key', option=opt1), ParamValue('yes'))))], default='val')
|
||||||
|
od1 = OptionDescription('root', '', [opt1, opt2, opt3])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
with pytest.raises(ConfigError):
|
with pytest.raises(ConfigError):
|
||||||
cfg.option('opt1').value.get()
|
cfg.option('opt1').value.get()
|
||||||
|
with pytest.raises(ConfigError):
|
||||||
|
cfg.option('opt3').value.get()
|
||||||
cfg.option('opt1').information.set('key', 'val')
|
cfg.option('opt1').information.set('key', 'val')
|
||||||
assert cfg.option('opt1').value.get() == 'val'
|
assert cfg.option('opt1').value.get() == 'val'
|
||||||
|
assert cfg.option('opt3').value.get() == 'val'
|
||||||
cfg.option('opt1').information.set('key', 'val1')
|
cfg.option('opt1').information.set('key', 'val1')
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
cfg.option('opt1').value.get()
|
cfg.option('opt1').value.get()
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
cfg.option('opt3').value.get()
|
||||||
#
|
#
|
||||||
with pytest.raises(ConfigError):
|
with pytest.raises(ConfigError):
|
||||||
assert cfg.option('opt2').value.get()
|
cfg.option('opt2').value.get()
|
||||||
cfg.information.set('key', 'val')
|
cfg.information.set('key', 'val')
|
||||||
assert cfg.option('opt2').value.get() == 'val'
|
assert cfg.option('opt2').value.get() == 'val'
|
||||||
cfg.information.set('key', 'val1')
|
cfg.information.set('key', 'val1')
|
||||||
|
|
|
@ -22,7 +22,7 @@ def test_forcepermissive_and_unrestraint(config_type):
|
||||||
cfg_ori.property.read_write()
|
cfg_ori.property.read_write()
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
with pytest.raises(ConfigError):
|
with pytest.raises(ConfigError):
|
||||||
cfg_ori.unrestraint.forcepermissive.add('disabled')
|
cfg_ori.forcepermissive.add('disabled')
|
||||||
|
|
||||||
|
|
||||||
def test_permissive(config_type):
|
def test_permissive(config_type):
|
||||||
|
@ -39,9 +39,9 @@ def test_permissive(config_type):
|
||||||
assert set(props) == {'disabled'}
|
assert set(props) == {'disabled'}
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.unrestraint.permissive.add('disabled')
|
cfg_ori.permissive.add('disabled')
|
||||||
cfg_ori.unrestraint.permissive.remove('hidden')
|
cfg_ori.permissive.remove('hidden')
|
||||||
assert cfg_ori.unrestraint.permissive.get() == frozenset(['disabled'])
|
assert cfg_ori.permissive.get() == frozenset(['disabled'])
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
props = frozenset()
|
props = frozenset()
|
||||||
try:
|
try:
|
||||||
|
@ -81,8 +81,8 @@ def test_permissive_add(config_type):
|
||||||
assert set(props) == {'disabled'}
|
assert set(props) == {'disabled'}
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.unrestraint.permissive.add('disabled')
|
cfg_ori.permissive.add('disabled')
|
||||||
assert cfg_ori.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
|
assert cfg_ori.permissive.get() == frozenset(['hidden', 'disabled'])
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
props = frozenset()
|
props = frozenset()
|
||||||
try:
|
try:
|
||||||
|
@ -119,10 +119,10 @@ def test_permissive_pop():
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
props = err.proptype
|
props = err.proptype
|
||||||
assert set(props) == {'disabled'}
|
assert set(props) == {'disabled'}
|
||||||
cfg.unrestraint.permissive.add('disabled')
|
cfg.permissive.add('disabled')
|
||||||
assert cfg.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
|
assert cfg.permissive.get() == frozenset(['hidden', 'disabled'])
|
||||||
cfg.forcepermissive.option('u1').value.get()
|
cfg.forcepermissive.option('u1').value.get()
|
||||||
cfg.unrestraint.permissive.remove('disabled')
|
cfg.permissive.remove('disabled')
|
||||||
props = frozenset()
|
props = frozenset()
|
||||||
try:
|
try:
|
||||||
cfg.forcepermissive.option('u1').value.get()
|
cfg.forcepermissive.option('u1').value.get()
|
||||||
|
@ -136,14 +136,14 @@ def test_permissive_reset():
|
||||||
od1 = make_description()
|
od1 = make_description()
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
assert cfg.unrestraint.permissive.get() == frozenset(['hidden'])
|
assert cfg.permissive.get() == frozenset(['hidden'])
|
||||||
#
|
#
|
||||||
cfg.unrestraint.permissive.add('disabled')
|
cfg.permissive.add('disabled')
|
||||||
cfg.unrestraint.permissive.remove('hidden')
|
cfg.permissive.remove('hidden')
|
||||||
assert cfg.unrestraint.permissive.get() == frozenset(['disabled'])
|
assert cfg.permissive.get() == frozenset(['disabled'])
|
||||||
#
|
#
|
||||||
cfg.unrestraint.permissive.reset()
|
cfg.permissive.reset()
|
||||||
assert cfg.unrestraint.permissive.get() == frozenset()
|
assert cfg.permissive.get() == frozenset(['hidden'])
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,9 +157,9 @@ def test_permissive_mandatory():
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
props = err.proptype
|
props = err.proptype
|
||||||
assert frozenset(props) == frozenset(['disabled'])
|
assert frozenset(props) == frozenset(['disabled'])
|
||||||
cfg.unrestraint.permissive.add('mandatory')
|
cfg.permissive.add('mandatory')
|
||||||
cfg.unrestraint.permissive.add('disabled')
|
cfg.permissive.add('disabled')
|
||||||
assert cfg.unrestraint.permissive.get() == frozenset(['mandatory', 'disabled'])
|
assert cfg.permissive.get() == frozenset(['hidden', 'mandatory', 'disabled'])
|
||||||
cfg.property.add('permissive')
|
cfg.property.add('permissive')
|
||||||
cfg.option('u1').value.get()
|
cfg.option('u1').value.get()
|
||||||
cfg.property.remove('permissive')
|
cfg.property.remove('permissive')
|
||||||
|
@ -175,10 +175,10 @@ def test_permissive_frozen():
|
||||||
od1 = make_description()
|
od1 = make_description()
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
cfg.unrestraint.permissive.remove('hidden')
|
cfg.permissive.remove('hidden')
|
||||||
cfg.unrestraint.permissive.add('frozen')
|
cfg.permissive.add('frozen')
|
||||||
cfg.unrestraint.permissive.add('disabled')
|
cfg.permissive.add('disabled')
|
||||||
assert cfg.unrestraint.permissive.get() == frozenset(['frozen', 'disabled'])
|
assert cfg.permissive.get() == frozenset(['frozen', 'disabled'])
|
||||||
assert cfg.permissive.get() == frozenset(['frozen', 'disabled'])
|
assert cfg.permissive.get() == frozenset(['frozen', 'disabled'])
|
||||||
try:
|
try:
|
||||||
cfg.option('u1').value.set(1)
|
cfg.option('u1').value.set(1)
|
||||||
|
@ -229,7 +229,7 @@ def test_permissive_option(config_type):
|
||||||
|
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.unrestraint.option('u1').permissive.set(frozenset(['disabled']))
|
cfg_ori.option('u1').permissive.add('disabled')
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
props = frozenset()
|
props = frozenset()
|
||||||
try:
|
try:
|
||||||
|
@ -293,7 +293,7 @@ def test_permissive_option_cache():
|
||||||
props = err.proptype
|
props = err.proptype
|
||||||
assert set(props) == {'disabled'}
|
assert set(props) == {'disabled'}
|
||||||
|
|
||||||
cfg.unrestraint.option('u1').permissive.set(frozenset(['disabled']))
|
cfg.option('u1').permissive.add('disabled')
|
||||||
props = frozenset()
|
props = frozenset()
|
||||||
try:
|
try:
|
||||||
cfg.option('u1').value.get()
|
cfg.option('u1').value.get()
|
||||||
|
@ -342,8 +342,9 @@ def test_permissive_option_mandatory():
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
props = err.proptype
|
props = err.proptype
|
||||||
assert frozenset(props) == frozenset(['disabled'])
|
assert frozenset(props) == frozenset(['disabled'])
|
||||||
cfg.unrestraint.option('u1').permissive.set(frozenset(['mandatory', 'disabled']))
|
cfg.option('u1').permissive.add('mandatory')
|
||||||
assert cfg.unrestraint.option('u1').permissive.get() == frozenset(['mandatory', 'disabled'])
|
cfg.option('u1').permissive.add('disabled')
|
||||||
|
assert cfg.option('u1').permissive.get() == frozenset(['mandatory', 'disabled'])
|
||||||
cfg.property.add('permissive')
|
cfg.property.add('permissive')
|
||||||
cfg.option('u1').value.get()
|
cfg.option('u1').value.get()
|
||||||
cfg.property.remove('permissive')
|
cfg.property.remove('permissive')
|
||||||
|
@ -359,7 +360,8 @@ def test_permissive_option_frozen():
|
||||||
od1 = make_description()
|
od1 = make_description()
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
cfg.unrestraint.option('u1').permissive.set(frozenset(['frozen', 'disabled']))
|
cfg.option('u1').permissive.add('disabled')
|
||||||
|
cfg.option('u1').permissive.add('frozen')
|
||||||
cfg.option('u1').value.set(1)
|
cfg.option('u1').value.set(1)
|
||||||
assert cfg.option('u1').value.get() == 1
|
assert cfg.option('u1').value.get() == 1
|
||||||
cfg.property.add('permissive')
|
cfg.property.add('permissive')
|
||||||
|
@ -369,15 +371,6 @@ def test_permissive_option_frozen():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_option_permissive():
|
|
||||||
od1 = make_description()
|
|
||||||
cfg = Config(od1)
|
|
||||||
cfg.property.read_write()
|
|
||||||
with pytest.raises(TypeError):
|
|
||||||
cfg.unrestraint.option('u1').permissive.set(['frozen', 'disabled'])
|
|
||||||
# assert not list_sessions()
|
|
||||||
|
|
||||||
|
|
||||||
def test_remove_option_permissive(config_type):
|
def test_remove_option_permissive(config_type):
|
||||||
var1 = StrOption('var1', '', u'value', properties=('hidden',))
|
var1 = StrOption('var1', '', u'value', properties=('hidden',))
|
||||||
od1 = OptionDescription('od1', '', [var1])
|
od1 = OptionDescription('od1', '', [var1])
|
||||||
|
@ -389,13 +382,13 @@ def test_remove_option_permissive(config_type):
|
||||||
cfg.option('od1.var1').value.get()
|
cfg.option('od1.var1').value.get()
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden']))
|
cfg_ori.forcepermissive.option('od1.var1').permissive.add('hidden')
|
||||||
assert cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
|
assert cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
assert cfg.option('od1.var1').value.get() == 'value'
|
assert cfg.option('od1.var1').value.get() == 'value'
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset())
|
cfg_ori.forcepermissive.option('od1.var1').permissive.reset()
|
||||||
assert cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset()
|
assert cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset()
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
with pytest.raises(PropertiesOptionError):
|
with pytest.raises(PropertiesOptionError):
|
||||||
|
@ -414,7 +407,7 @@ def test_reset_option_permissive(config_type):
|
||||||
cfg.option('od1.var1').value.get()
|
cfg.option('od1.var1').value.get()
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.forcepermissive.option('od1.var1').permissive.set(frozenset(['hidden']))
|
cfg_ori.forcepermissive.option('od1.var1').permissive.add('hidden')
|
||||||
assert cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
|
assert cfg_ori.forcepermissive.option('od1.var1').permissive.get() == frozenset(['hidden'])
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
assert cfg.option('od1.var1').value.get() == 'value'
|
assert cfg.option('od1.var1').value.get() == 'value'
|
||||||
|
|
|
@ -31,12 +31,12 @@ def test_properties(config_type):
|
||||||
assert frozenset(props) == frozenset(['disabled'])
|
assert frozenset(props) == frozenset(['disabled'])
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.unrestraint.option('ip_address_service').property.remove('disabled')
|
cfg_ori.unrestraint.option('ip_address_service').permissive.add('disabled')
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
cfg.option('ip_address_service').value.get()
|
cfg.option('ip_address_service').value.get()
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.unrestraint.option('ip_address_service').property.add('disabled')
|
cfg_ori.unrestraint.option('ip_address_service').permissive.remove('disabled')
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
props = []
|
props = []
|
||||||
try:
|
try:
|
||||||
|
@ -47,8 +47,8 @@ def test_properties(config_type):
|
||||||
# pop twice
|
# pop twice
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
cfg.send()
|
cfg.send()
|
||||||
cfg_ori.unrestraint.option('ip_address_service').property.remove('disabled')
|
cfg_ori.unrestraint.option('ip_address_service').permissive.add('disabled')
|
||||||
cfg_ori.unrestraint.option('ip_address_service').property.remove('disabled')
|
cfg_ori.unrestraint.option('ip_address_service').permissive.remove('disabled')
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -613,6 +613,7 @@ def test_requires_transitive_hidden_disabled_multiple(config_type):
|
||||||
del req
|
del req
|
||||||
#
|
#
|
||||||
cfg_ori.permissive.reset()
|
cfg_ori.permissive.reset()
|
||||||
|
cfg_ori.permissive.remove('hidden')
|
||||||
if config_type == 'tiramisu-api':
|
if config_type == 'tiramisu-api':
|
||||||
try:
|
try:
|
||||||
cfg = get_config(cfg_ori, config_type)
|
cfg = get_config(cfg_ori, config_type)
|
||||||
|
|
|
@ -141,7 +141,7 @@ def test_symlink_getpermissive():
|
||||||
od1 = OptionDescription('opt', '', [boolopt, linkopt])
|
od1 = OptionDescription('opt', '', [boolopt, linkopt])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.property.read_write()
|
cfg.property.read_write()
|
||||||
cfg.option('b').permissive.set(frozenset(['perm']))
|
cfg.option('b').permissive.add('perm')
|
||||||
cfg.option('c').permissive.get() == frozenset(['perm'])
|
cfg.option('c').permissive.get() == frozenset(['perm'])
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
@ -266,14 +266,26 @@ def test_symlink_owner(config_type):
|
||||||
|
|
||||||
|
|
||||||
def test_symlink_get_information():
|
def test_symlink_get_information():
|
||||||
boolopt = BoolOption("b", "", default=False)
|
boolopt = BoolOption("b", "", default=False, informations={'test': 'test'})
|
||||||
linkopt = SymLinkOption("c", boolopt)
|
linkopt = SymLinkOption("c", boolopt)
|
||||||
boolopt.impl_set_information('test', 'test')
|
od1 = OptionDescription('opt', '', [linkopt, boolopt])
|
||||||
assert boolopt.impl_get_information('test') == 'test'
|
cfg = Config(od1)
|
||||||
assert linkopt.impl_get_information('test') == 'test'
|
assert cfg.option('b').information.get('test') == 'test'
|
||||||
boolopt.impl_set_information('test', 'test2')
|
assert cfg.option('c').information.get('test') == 'test'
|
||||||
assert boolopt.impl_get_information('test') == 'test2'
|
cfg.option('b').information.set('test', 'test2')
|
||||||
assert linkopt.impl_get_information('test') == 'test2'
|
assert cfg.option('b').information.get('test') == 'test2'
|
||||||
|
assert cfg.option('c').information.get('test') == 'test2'
|
||||||
|
|
||||||
|
|
||||||
|
def test_symlink_informations():
|
||||||
|
boolopt = BoolOption("b", "", default=False)
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
linkopt = SymLinkOption("c", boolopt, informations={'test': 'test'})
|
||||||
|
linkopt = SymLinkOption("c", boolopt)
|
||||||
|
od1 = OptionDescription('opt', '', [linkopt, boolopt])
|
||||||
|
cfg = Config(od1)
|
||||||
|
with pytest.raises(ConfigError):
|
||||||
|
cfg.option('c').information.set('test', 'test2')
|
||||||
|
|
||||||
|
|
||||||
def test_symlink_leader():
|
def test_symlink_leader():
|
||||||
|
@ -359,9 +371,9 @@ def test_symlink_dependency():
|
||||||
[linkopt, OptionDescription("s1", "", [boolopt])])
|
[linkopt, OptionDescription("s1", "", [boolopt])])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
assert cfg.option('s1.b').has_dependency() is False
|
assert cfg.option('s1.b').has_dependency() is False
|
||||||
assert cfg.option('c').has_dependency() is True
|
assert cfg.option('c').has_dependency() is False
|
||||||
assert cfg.option('s1.b').has_dependency(False) is True
|
assert cfg.option('s1.b').has_dependency(False) is True
|
||||||
assert cfg.option('c').has_dependency(False) is False
|
assert cfg.option('c').has_dependency(False) is True
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -385,7 +397,7 @@ def test_symlink_list(config_type):
|
||||||
[linkopt, OptionDescription("s1", "", [boolopt])])
|
[linkopt, OptionDescription("s1", "", [boolopt])])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg = get_config(cfg, config_type)
|
cfg = get_config(cfg, config_type)
|
||||||
assert [opt.path() for opt in cfg.option.list()] == ['c', 's1']
|
assert [opt.path() for opt in cfg.list()] == ['c', 's1']
|
||||||
#
|
#
|
||||||
assert [opt.path() for opt in cfg.option('s1').list()] == ['s1.b']
|
assert [opt.path() for opt in cfg.option('s1').list()] == ['s1.b']
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
705
tiramisu/api.py
705
tiramisu/api.py
File diff suppressed because it is too large
Load diff
|
@ -19,16 +19,47 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
"enables us to carry out a calculation and return an option's value"
|
"enables us to carry out a calculation and return an option's value"
|
||||||
from typing import Any, Optional, Union, Callable, Dict, List
|
from typing import Any, Optional, Union, Callable, Dict, List
|
||||||
from os.path import commonprefix
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
import weakref
|
||||||
|
|
||||||
from .error import PropertiesOptionError, ConfigError, LeadershipError, ValueWarning
|
from .error import PropertiesOptionError, ConfigError, LeadershipError, ValueWarning
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
from .setting import undefined, ConfigBag, Undefined
|
from .setting import undefined, ConfigBag
|
||||||
from .function import FUNCTION_WAITING_FOR_DICT
|
from .function import FUNCTION_WAITING_FOR_DICT
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
|
def get_calculated_value(subconfig: "SubConfig",
|
||||||
|
value: Any,
|
||||||
|
*,
|
||||||
|
reset_cache: bool=True,
|
||||||
|
validate_properties: bool=True,
|
||||||
|
) -> Any:
|
||||||
|
"""value could be a calculation, in this case do calculation
|
||||||
|
"""
|
||||||
|
has_calculation = False
|
||||||
|
if isinstance(value, Calculation):
|
||||||
|
if subconfig is None:
|
||||||
|
return undefined, False
|
||||||
|
value = value.execute(subconfig,
|
||||||
|
validate_properties=validate_properties,
|
||||||
|
)
|
||||||
|
has_calculation = True
|
||||||
|
elif isinstance(value, list):
|
||||||
|
# if value is a list, do subcalculation
|
||||||
|
for idx, val in enumerate(value):
|
||||||
|
value[idx], _has_calculation = get_calculated_value(subconfig,
|
||||||
|
val,
|
||||||
|
reset_cache=False,
|
||||||
|
validate_properties=validate_properties,
|
||||||
|
)
|
||||||
|
if value[idx] is undefined:
|
||||||
|
return undefined, False
|
||||||
|
if _has_calculation:
|
||||||
|
has_calculation = True
|
||||||
|
return value, has_calculation
|
||||||
|
|
||||||
|
|
||||||
class Params:
|
class Params:
|
||||||
__slots__ = ('args', 'kwargs')
|
__slots__ = ('args', 'kwargs')
|
||||||
def __init__(self, args=None, kwargs=None, **kwgs):
|
def __init__(self, args=None, kwargs=None, **kwgs):
|
||||||
|
@ -85,13 +116,11 @@ class ParamOption(Param):
|
||||||
|
|
||||||
class ParamDynOption(ParamOption):
|
class ParamDynOption(ParamOption):
|
||||||
__slots__ = ('suffixes',
|
__slots__ = ('suffixes',
|
||||||
'dynoptiondescription',
|
|
||||||
'optional',
|
'optional',
|
||||||
)
|
)
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
option: 'Option',
|
option: 'Option',
|
||||||
suffixes: list[str],
|
suffixes: list[str],
|
||||||
dynoptiondescription: 'DynOptionDescription'=None,
|
|
||||||
notraisepropertyerror: bool=False,
|
notraisepropertyerror: bool=False,
|
||||||
raisepropertyerror: bool=False,
|
raisepropertyerror: bool=False,
|
||||||
optional: bool=False,
|
optional: bool=False,
|
||||||
|
@ -101,7 +130,6 @@ class ParamDynOption(ParamOption):
|
||||||
raisepropertyerror,
|
raisepropertyerror,
|
||||||
)
|
)
|
||||||
self.suffixes = suffixes
|
self.suffixes = suffixes
|
||||||
self.dynoptiondescription = dynoptiondescription
|
|
||||||
self.optional = optional
|
self.optional = optional
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,6 +153,7 @@ class ParamInformation(Param):
|
||||||
__slots__ = ('information_name',
|
__slots__ = ('information_name',
|
||||||
'default_value',
|
'default_value',
|
||||||
'option',
|
'option',
|
||||||
|
'self_option',
|
||||||
)
|
)
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
information_name: str,
|
information_name: str,
|
||||||
|
@ -133,7 +162,22 @@ class ParamInformation(Param):
|
||||||
) -> None:
|
) -> None:
|
||||||
self.information_name = information_name
|
self.information_name = information_name
|
||||||
self.default_value = default_value
|
self.default_value = default_value
|
||||||
|
self.self_option = None
|
||||||
|
self.option = None
|
||||||
if option:
|
if option:
|
||||||
|
self.set_option(option)
|
||||||
|
|
||||||
|
def set_self_option(self, option):
|
||||||
|
self.self_option = option
|
||||||
|
|
||||||
|
def set_option(self,
|
||||||
|
option: 'Option'=None
|
||||||
|
) -> None:
|
||||||
|
if not hasattr(self, 'self_option'):
|
||||||
|
raise ConfigError('cannot add option in information after creating config')
|
||||||
|
if self.option:
|
||||||
|
raise ConfigError('cannot redefine option in information')
|
||||||
|
if not option.impl_is_optiondescription():
|
||||||
if option.impl_is_symlinkoption():
|
if option.impl_is_symlinkoption():
|
||||||
raise ValueError(_('option in ParamInformation cannot be a symlinkoption'))
|
raise ValueError(_('option in ParamInformation cannot be a symlinkoption'))
|
||||||
if option.impl_is_follower():
|
if option.impl_is_follower():
|
||||||
|
@ -141,10 +185,27 @@ class ParamInformation(Param):
|
||||||
if option.impl_is_dynsymlinkoption():
|
if option.impl_is_dynsymlinkoption():
|
||||||
raise ValueError(_('option in ParamInformation cannot be a dynamic option'))
|
raise ValueError(_('option in ParamInformation cannot be a dynamic option'))
|
||||||
self.option = option
|
self.option = option
|
||||||
|
if self.self_option:
|
||||||
|
informations = self.self_option._dependencies_information
|
||||||
|
if set(informations) == {None, self.information_name}:
|
||||||
|
del self.self_option._dependencies_information
|
||||||
|
else:
|
||||||
|
informations.remove(None)
|
||||||
|
if not getattr(option, '_dependencies_information', {}):
|
||||||
|
option._dependencies_information = {None: []}
|
||||||
|
option._dependencies_information[None].append(self)
|
||||||
|
option._dependencies_information.setdefault(self.information_name, []).append(weakref.ref(self.self_option))
|
||||||
|
|
||||||
|
|
||||||
class ParamSelfInformation(ParamInformation):
|
class ParamSelfInformation(ParamInformation):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
def __init__(self,
|
||||||
|
information_name: str,
|
||||||
|
default_value: Any=undefined,
|
||||||
|
) -> None:
|
||||||
|
return super().__init__(information_name,
|
||||||
|
default_value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ParamIndex(Param):
|
class ParamIndex(Param):
|
||||||
|
@ -152,7 +213,11 @@ class ParamIndex(Param):
|
||||||
|
|
||||||
|
|
||||||
class ParamSuffix(Param):
|
class ParamSuffix(Param):
|
||||||
__slots__ = tuple()
|
__slots__ = ('suffix_index',)
|
||||||
|
def __init__(self,
|
||||||
|
suffix_index: int=-1,
|
||||||
|
) -> None:
|
||||||
|
self.suffix_index = suffix_index
|
||||||
|
|
||||||
|
|
||||||
class Calculation:
|
class Calculation:
|
||||||
|
@ -190,6 +255,7 @@ class Calculation:
|
||||||
allow_value_error: bool=False,
|
allow_value_error: bool=False,
|
||||||
force_value_warning: bool=False,
|
force_value_warning: bool=False,
|
||||||
for_settings: bool=False,
|
for_settings: bool=False,
|
||||||
|
validate_properties: bool=True,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
return carry_out_calculation(subconfig,
|
return carry_out_calculation(subconfig,
|
||||||
callback=self.function,
|
callback=self.function,
|
||||||
|
@ -200,6 +266,7 @@ class Calculation:
|
||||||
allow_value_error=allow_value_error,
|
allow_value_error=allow_value_error,
|
||||||
force_value_warning=force_value_warning,
|
force_value_warning=force_value_warning,
|
||||||
for_settings=for_settings,
|
for_settings=for_settings,
|
||||||
|
validate_properties=validate_properties,
|
||||||
)
|
)
|
||||||
|
|
||||||
def help(self,
|
def help(self,
|
||||||
|
@ -229,6 +296,7 @@ def manager_callback(callback: Callable,
|
||||||
orig_value,
|
orig_value,
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
for_settings: bool,
|
for_settings: bool,
|
||||||
|
validate_properties: bool,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""replace Param by true value"""
|
"""replace Param by true value"""
|
||||||
option = subconfig.option
|
option = subconfig.option
|
||||||
|
@ -297,18 +365,18 @@ def manager_callback(callback: Callable,
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _get_value(param: Params,
|
def _get_value(param: Params,
|
||||||
subconfig: SubConfig,
|
subconfig: 'SubConfig',
|
||||||
) -> Any:
|
) -> Any:
|
||||||
try:
|
try:
|
||||||
# get value
|
# get value
|
||||||
value = config_bag.context.get_value(subconfig)
|
value = config_bag.context.get_value(subconfig)
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||||
if param.notraisepropertyerror or param.raisepropertyerror:
|
if isinstance(param, ParamSelfOption) or param.notraisepropertyerror or param.raisepropertyerror:
|
||||||
raise err from err
|
raise err from err
|
||||||
raise ConfigError(_('unable to carry out a calculation for "{}", {}').format(display_name, err)) from err
|
raise ConfigError(_('unable to carry out a calculation for "{}", {}').format(display_name, err)) from err
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
display_name = subconfig.option.impl_get_display_name()
|
display_name = subconfig.option.impl_get_display_name(subconfig)
|
||||||
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(display_name, err)) from err
|
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(display_name, err)) from err
|
||||||
except AttributeError as err:
|
except AttributeError as err:
|
||||||
if isinstance(param, ParamDynOption) and param.optional:
|
if isinstance(param, ParamDynOption) and param.optional:
|
||||||
|
@ -317,7 +385,7 @@ def manager_callback(callback: Callable,
|
||||||
['configerror'],
|
['configerror'],
|
||||||
config_bag.context.get_settings(),
|
config_bag.context.get_settings(),
|
||||||
)
|
)
|
||||||
display_name = subconfig.option.impl_get_display_name()
|
display_name = subconfig.option.impl_get_display_name(subconfig)
|
||||||
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@ -341,20 +409,20 @@ def manager_callback(callback: Callable,
|
||||||
config_bag.remove_validation()
|
config_bag.remove_validation()
|
||||||
# root = config_bag.context.get_root(config_bag)
|
# root = config_bag.context.get_root(config_bag)
|
||||||
try:
|
try:
|
||||||
subconfig = config_bag.context.get_sub_config(config_bag,
|
subsubconfig = config_bag.context.get_sub_config(config_bag,
|
||||||
opt.impl_getpath(),
|
opt.impl_getpath(),
|
||||||
index_,
|
index_,
|
||||||
validate_properties=not self_calc,
|
validate_properties=not self_calc,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
)
|
)
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||||
if param.notraisepropertyerror or param.raisepropertyerror:
|
if param.notraisepropertyerror or param.raisepropertyerror:
|
||||||
raise err from err
|
raise err from err
|
||||||
display_name = option.impl_get_display_name()
|
display_name = option.impl_get_display_name(subconfig)
|
||||||
raise ConfigError(_('unable to carry out a calculation for "{}", {}').format(display_name, err)) from err
|
raise ConfigError(_('unable to carry out a calculation for "{}", {}').format(display_name, err)) from err
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option.impl_get_display_name(), err)) from err
|
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option.impl_get_display_name(subconfig), err)) from err
|
||||||
except AttributeError as err:
|
except AttributeError as err:
|
||||||
if isinstance(param, ParamDynOption) and param.optional:
|
if isinstance(param, ParamDynOption) and param.optional:
|
||||||
# cannot acces, simulate a propertyerror
|
# cannot acces, simulate a propertyerror
|
||||||
|
@ -362,19 +430,9 @@ def manager_callback(callback: Callable,
|
||||||
['configerror'],
|
['configerror'],
|
||||||
config_bag.context.get_settings(),
|
config_bag.context.get_settings(),
|
||||||
)
|
)
|
||||||
display_name = option.impl_get_display_name()
|
display_name = option.impl_get_display_name(subconfig)
|
||||||
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
||||||
return subconfig
|
return subsubconfig
|
||||||
|
|
||||||
def get_common_path(path1, path2):
|
|
||||||
common_path = commonprefix([path1, path2])
|
|
||||||
if common_path in [path1, path2]:
|
|
||||||
return common_path
|
|
||||||
if common_path.endswith('.'):
|
|
||||||
return common_path[:-1]
|
|
||||||
if '.' in common_path:
|
|
||||||
return common_path.rsplit('.', 1)[0]
|
|
||||||
return None
|
|
||||||
|
|
||||||
if isinstance(param, ParamValue):
|
if isinstance(param, ParamValue):
|
||||||
return param.value
|
return param.value
|
||||||
|
@ -383,22 +441,30 @@ def manager_callback(callback: Callable,
|
||||||
if isinstance(param, ParamSelfInformation):
|
if isinstance(param, ParamSelfInformation):
|
||||||
isubconfig = subconfig
|
isubconfig = subconfig
|
||||||
elif param.option:
|
elif param.option:
|
||||||
isubconfig = get_option_bag(config_bag,
|
if param.option.issubdyn():
|
||||||
param.option,
|
search_option = param.option
|
||||||
param,
|
isubconfig = subconfig.get_common_child(search_option,
|
||||||
None,
|
true_path=subconfig.path,
|
||||||
False,
|
)
|
||||||
#properties=properties,
|
if isinstance(isubconfig, list):
|
||||||
)
|
raise ConfigError(f'cannot find information for "{option.impl_get_display_name(subconfig)}", "{search_option.impl_get_display_name(None)}" is a dynamic option')
|
||||||
|
else:
|
||||||
|
isubconfig = get_option_bag(config_bag,
|
||||||
|
param.option,
|
||||||
|
param,
|
||||||
|
None,
|
||||||
|
False,
|
||||||
|
#properties=properties,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
isubconfig = None
|
isubconfig = config_bag.context.get_root(config_bag)
|
||||||
try:
|
try:
|
||||||
return config_bag.context.get_values().get_information(isubconfig,
|
return config_bag.context.get_values().get_information(isubconfig,
|
||||||
param.information_name,
|
param.information_name,
|
||||||
param.default_value,
|
param.default_value,
|
||||||
)
|
)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
display_name = option.impl_get_display_name()
|
display_name = option.impl_get_display_name(subconfig)
|
||||||
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
||||||
|
|
||||||
if isinstance(param, ParamIndex):
|
if isinstance(param, ParamIndex):
|
||||||
|
@ -406,9 +472,9 @@ def manager_callback(callback: Callable,
|
||||||
|
|
||||||
if isinstance(param, ParamSuffix):
|
if isinstance(param, ParamSuffix):
|
||||||
if not option.issubdyn():
|
if not option.issubdyn():
|
||||||
display_name = subconfig.option.impl_get_display_name()
|
display_name = subconfig.option.impl_get_display_name(subconfig)
|
||||||
raise ConfigError(_('option "{display_name}" is not in a dynoptiondescription'))
|
raise ConfigError(_('option "{display_name}" is not in a dynoptiondescription'))
|
||||||
return subconfig.suffixes[-1]
|
return subconfig.suffixes[param.suffix_index]
|
||||||
|
|
||||||
if isinstance(param, ParamSelfOption):
|
if isinstance(param, ParamSelfOption):
|
||||||
value = calc_self(param,
|
value = calc_self(param,
|
||||||
|
@ -418,45 +484,13 @@ def manager_callback(callback: Callable,
|
||||||
)
|
)
|
||||||
if callback.__name__ not in FUNCTION_WAITING_FOR_DICT:
|
if callback.__name__ not in FUNCTION_WAITING_FOR_DICT:
|
||||||
return value
|
return value
|
||||||
return {'name': option.impl_get_display_name(),
|
return {'name': option.impl_get_display_name(subconfig),
|
||||||
'value': value,
|
'value': value,
|
||||||
}
|
}
|
||||||
|
|
||||||
if isinstance(param, ParamOption):
|
if isinstance(param, ParamOption):
|
||||||
callbk_option = param.option
|
callbk_option = param.option
|
||||||
callbk_options = None
|
config_bag = subconfig.config_bag
|
||||||
subconfigs = None
|
|
||||||
if callbk_option.issubdyn():
|
|
||||||
found = False
|
|
||||||
|
|
||||||
if isinstance(param, ParamDynOption):
|
|
||||||
# SUBDYN INSIDE CURRENT != SUBDYN OUTSIDE ?
|
|
||||||
callbk_option = callbk_option.to_sub_dyoption(param.suffixes)
|
|
||||||
found = True
|
|
||||||
else:
|
|
||||||
search_option = param.option
|
|
||||||
current_option_path = option.impl_getpath()
|
|
||||||
search_option_path = search_option.impl_getpath()
|
|
||||||
common_path = get_common_path(current_option_path, search_option_path)
|
|
||||||
if common_path:
|
|
||||||
parent_number = current_option_path[len(common_path) + 2:].count('.')
|
|
||||||
if parent_number:
|
|
||||||
raise Exception('pfff')
|
|
||||||
subconfig = subconfig.parent.get_child(search_option,
|
|
||||||
None,
|
|
||||||
True,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
raise Exception('pfff')
|
|
||||||
subconfigs = [subconfig]
|
|
||||||
found = True
|
|
||||||
if not found:
|
|
||||||
callbk_options = []
|
|
||||||
for doption_bag in callbk_option.getsubdyn().get_sub_children(callbk_option,
|
|
||||||
config_bag,
|
|
||||||
index=None,
|
|
||||||
):
|
|
||||||
callbk_options.append(doption_bag.option)
|
|
||||||
if index is not None and callbk_option.impl_get_leadership() and \
|
if index is not None and callbk_option.impl_get_leadership() and \
|
||||||
callbk_option.impl_get_leadership().in_same_leadership(option):
|
callbk_option.impl_get_leadership().in_same_leadership(option):
|
||||||
if not callbk_option.impl_is_follower():
|
if not callbk_option.impl_is_follower():
|
||||||
|
@ -470,7 +504,69 @@ def manager_callback(callback: Callable,
|
||||||
else:
|
else:
|
||||||
index_ = None
|
index_ = None
|
||||||
with_index = False
|
with_index = False
|
||||||
if subconfigs is None:
|
if callbk_option.issubdyn():
|
||||||
|
if isinstance(param, ParamDynOption):
|
||||||
|
#callbk_option = callbk_option.to_sub_dyoption(param.suffixes)
|
||||||
|
suffixes = param.suffixes.copy()
|
||||||
|
paths = callbk_option.impl_getpath().split('.')
|
||||||
|
parents = [config_bag.context.get_root(config_bag)]
|
||||||
|
subconfigs_is_a_list = False
|
||||||
|
for name in paths:
|
||||||
|
new_parents = []
|
||||||
|
for parent in parents:
|
||||||
|
doption = parent.option.get_child(name,
|
||||||
|
config_bag,
|
||||||
|
parent,
|
||||||
|
allow_dynoption=True,
|
||||||
|
)
|
||||||
|
if doption.impl_is_dynoptiondescription():
|
||||||
|
if suffixes:
|
||||||
|
suffix = suffixes.pop(0)
|
||||||
|
name = doption.impl_getname(suffix)
|
||||||
|
try:
|
||||||
|
doption = parent.option.get_child(name,
|
||||||
|
config_bag,
|
||||||
|
parent,
|
||||||
|
)
|
||||||
|
except AttributeError as err:
|
||||||
|
raise ConfigError(err) from err
|
||||||
|
new_parents.append(parent.get_child(doption,
|
||||||
|
None,
|
||||||
|
True,
|
||||||
|
name=name,
|
||||||
|
suffix=suffix,
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
subconfigs_is_a_list = True
|
||||||
|
new_parents.extend(parent.dyn_to_subconfig(doption,
|
||||||
|
True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
new_parents.append(parent.get_child(doption,
|
||||||
|
None,
|
||||||
|
True,
|
||||||
|
name=name,
|
||||||
|
))
|
||||||
|
parents = new_parents
|
||||||
|
|
||||||
|
if subconfigs_is_a_list:
|
||||||
|
subconfigs = parents
|
||||||
|
else:
|
||||||
|
subconfigs = parents[0]
|
||||||
|
|
||||||
|
else:
|
||||||
|
search_option = param.option
|
||||||
|
subconfigs = subconfig.get_common_child(search_option,
|
||||||
|
true_path=subconfig.path,
|
||||||
|
validate_properties=validate_properties,
|
||||||
|
)
|
||||||
|
if isinstance(subconfigs, list):
|
||||||
|
values = []
|
||||||
|
else:
|
||||||
|
values = None
|
||||||
|
subconfigs = [subconfigs]
|
||||||
|
else:
|
||||||
subconfigs = [get_option_bag(config_bag,
|
subconfigs = [get_option_bag(config_bag,
|
||||||
callbk_option,
|
callbk_option,
|
||||||
param,
|
param,
|
||||||
|
@ -479,13 +575,7 @@ def manager_callback(callback: Callable,
|
||||||
#properties=properties,
|
#properties=properties,
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
# callbk_options = [callbk_option]
|
|
||||||
values = None
|
values = None
|
||||||
else:
|
|
||||||
values = []
|
|
||||||
#FIXME
|
|
||||||
values = None
|
|
||||||
# for callbk_option in callbk_options:
|
|
||||||
for subconfig in subconfigs:
|
for subconfig in subconfigs:
|
||||||
callbk_option = subconfig.option
|
callbk_option = subconfig.option
|
||||||
value = get_value(config_bag,
|
value = get_value(config_bag,
|
||||||
|
@ -501,7 +591,7 @@ def manager_callback(callback: Callable,
|
||||||
value = values
|
value = values
|
||||||
if callback.__name__ not in FUNCTION_WAITING_FOR_DICT:
|
if callback.__name__ not in FUNCTION_WAITING_FOR_DICT:
|
||||||
return value
|
return value
|
||||||
return {'name': callbk_option.impl_get_display_name(),
|
return {'name': callbk_option.impl_get_display_name(subconfig),
|
||||||
'value': value}
|
'value': value}
|
||||||
|
|
||||||
|
|
||||||
|
@ -514,6 +604,8 @@ def carry_out_calculation(subconfig: 'SubConfig',
|
||||||
allow_value_error: bool=False,
|
allow_value_error: bool=False,
|
||||||
force_value_warning: bool=False,
|
force_value_warning: bool=False,
|
||||||
for_settings: bool=False,
|
for_settings: bool=False,
|
||||||
|
*,
|
||||||
|
validate_properties: bool=True,
|
||||||
):
|
):
|
||||||
"""a function that carries out a calculation for an option's value
|
"""a function that carries out a calculation for an option's value
|
||||||
|
|
||||||
|
@ -533,7 +625,7 @@ def carry_out_calculation(subconfig: 'SubConfig',
|
||||||
Values could have multiple values only when key is ''."""
|
Values could have multiple values only when key is ''."""
|
||||||
option = subconfig.option
|
option = subconfig.option
|
||||||
if not option.impl_is_optiondescription() and option.impl_is_follower() and index is None:
|
if not option.impl_is_optiondescription() and option.impl_is_follower() and index is None:
|
||||||
raise Exception('follower must have index in carry_out_calculation!')
|
raise ConfigError(f'the follower "{option.impl_get_display_name(subconfig)}" must have index in carry_out_calculation!')
|
||||||
def fake_items(iterator):
|
def fake_items(iterator):
|
||||||
return ((None, i) for i in iterator)
|
return ((None, i) for i in iterator)
|
||||||
args = []
|
args = []
|
||||||
|
@ -548,20 +640,21 @@ def carry_out_calculation(subconfig: 'SubConfig',
|
||||||
orig_value,
|
orig_value,
|
||||||
config_bag,
|
config_bag,
|
||||||
for_settings,
|
for_settings,
|
||||||
|
validate_properties,
|
||||||
)
|
)
|
||||||
if key is None:
|
if key is None:
|
||||||
args.append(value)
|
args.append(value)
|
||||||
else:
|
else:
|
||||||
kwargs[key] = value
|
kwargs[key] = value
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
if param.raisepropertyerror:
|
if isinstance(param, ParamSelfOption) or param.raisepropertyerror:
|
||||||
raise err
|
raise err
|
||||||
if callback.__name__ in FUNCTION_WAITING_FOR_DICT:
|
if callback.__name__ in FUNCTION_WAITING_FOR_DICT:
|
||||||
if key is None:
|
if key is None:
|
||||||
args.append({'propertyerror': str(err), 'name': option.impl_get_display_name()})
|
args.append({'propertyerror': str(err), 'name': option.impl_get_display_name(subconfig)})
|
||||||
else:
|
else:
|
||||||
kwargs[key] = {'propertyerror': str(err), 'name': option.impl_get_display_name()}
|
kwargs[key] = {'propertyerror': str(err), 'name': option.impl_get_display_name(subconfig)}
|
||||||
ret = calculate(option,
|
ret = calculate(subconfig,
|
||||||
callback,
|
callback,
|
||||||
allow_value_error,
|
allow_value_error,
|
||||||
force_value_warning,
|
force_value_warning,
|
||||||
|
@ -579,17 +672,17 @@ def carry_out_calculation(subconfig: 'SubConfig',
|
||||||
args,
|
args,
|
||||||
kwargs,
|
kwargs,
|
||||||
ret,
|
ret,
|
||||||
option.impl_get_display_name()))
|
option.impl_get_display_name(subconfig)))
|
||||||
else:
|
else:
|
||||||
raise LeadershipError(_('the "{}" function must not return a list ("{}") '
|
raise LeadershipError(_('the "{}" function must not return a list ("{}") '
|
||||||
'for the follower option "{}"'
|
'for the follower option "{}"'
|
||||||
'').format(callback.__name__,
|
'').format(callback.__name__,
|
||||||
ret,
|
ret,
|
||||||
option.impl_get_display_name()))
|
option.impl_get_display_name(subconfig)))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def calculate(option,
|
def calculate(subconfig,
|
||||||
callback: Callable,
|
callback: Callable,
|
||||||
allow_value_error: bool,
|
allow_value_error: bool,
|
||||||
force_value_warning: bool,
|
force_value_warning: bool,
|
||||||
|
@ -617,12 +710,12 @@ def calculate(option,
|
||||||
msg = _('unexpected error "{0}" in function "{1}" with arguments "{3}" and "{4}" '
|
msg = _('unexpected error "{0}" in function "{1}" with arguments "{3}" and "{4}" '
|
||||||
'for option "{2}"').format(str(error),
|
'for option "{2}"').format(str(error),
|
||||||
callback.__name__,
|
callback.__name__,
|
||||||
option.impl_get_display_name(),
|
subconfig.option.impl_get_display_name(subconfig),
|
||||||
args,
|
args,
|
||||||
kwargs)
|
kwargs)
|
||||||
else:
|
else:
|
||||||
msg = _('unexpected error "{0}" in function "{1}" for option "{2}"'
|
msg = _('unexpected error "{0}" in function "{1}" for option "{2}"'
|
||||||
'').format(str(error),
|
'').format(str(error),
|
||||||
callback.__name__,
|
callback.__name__,
|
||||||
option.impl_get_display_name())
|
subconfig.option.impl_get_display_name(subconfig))
|
||||||
raise ConfigError(msg) from error
|
raise ConfigError(msg) from error
|
||||||
|
|
|
@ -47,17 +47,12 @@ class Cache:
|
||||||
if path not in self._cache or index not in self._cache[path]:
|
if path not in self._cache or index not in self._cache[path]:
|
||||||
return no_cache
|
return no_cache
|
||||||
value, timestamp, validated = self._cache[path][index]
|
value, timestamp, validated = self._cache[path][index]
|
||||||
if type_ == 'context_props':
|
props = subconfig.config_bag.properties
|
||||||
# cached value is settings properties so value is props
|
if type_ == 'self_props':
|
||||||
props = value
|
# cached value is self_props
|
||||||
self_props = {}
|
self_props = value
|
||||||
else:
|
else:
|
||||||
props = subconfig.config_bag.properties
|
self_props = subconfig.properties
|
||||||
if type_ == 'self_props':
|
|
||||||
# cached value is self_props
|
|
||||||
self_props = value
|
|
||||||
else:
|
|
||||||
self_props = subconfig.properties
|
|
||||||
if 'cache' in props or \
|
if 'cache' in props or \
|
||||||
'cache' in self_props:
|
'cache' in self_props:
|
||||||
if expiration and timestamp and \
|
if expiration and timestamp and \
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
import weakref
|
import weakref
|
||||||
from copy import copy, deepcopy
|
from copy import copy, deepcopy
|
||||||
from typing import Optional, List, Any, Union
|
from typing import Optional, List, Any, Union
|
||||||
|
from os.path import commonprefix
|
||||||
|
|
||||||
from .error import PropertiesOptionError, ConfigError, ConflictError, \
|
from .error import PropertiesOptionError, ConfigError, ConflictError, \
|
||||||
LeadershipError
|
LeadershipError
|
||||||
|
@ -35,6 +36,17 @@ from .autolib import Calculation
|
||||||
from . import autolib
|
from . import autolib
|
||||||
|
|
||||||
|
|
||||||
|
def get_common_path(path1, path2):
|
||||||
|
common_path = commonprefix([path1, path2])
|
||||||
|
if common_path in [path1, path2]:
|
||||||
|
return common_path
|
||||||
|
if common_path.endswith('.'):
|
||||||
|
return common_path[:-1]
|
||||||
|
if '.' in common_path:
|
||||||
|
return common_path.rsplit('.', 1)[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class CCache:
|
class CCache:
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
@ -171,6 +183,7 @@ class SubConfig:
|
||||||
'path',
|
'path',
|
||||||
'true_path',
|
'true_path',
|
||||||
'properties',
|
'properties',
|
||||||
|
'raises_properties',
|
||||||
'is_dynamic',
|
'is_dynamic',
|
||||||
'suffixes',
|
'suffixes',
|
||||||
'_length',
|
'_length',
|
||||||
|
@ -187,8 +200,6 @@ class SubConfig:
|
||||||
properties: Union[list[str], undefined]=undefined,
|
properties: Union[list[str], undefined]=undefined,
|
||||||
validate_properties: bool=True,
|
validate_properties: bool=True,
|
||||||
) -> None:
|
) -> None:
|
||||||
if path and '.' in path and not parent:
|
|
||||||
raise Exception('pff connard')
|
|
||||||
self.index = index
|
self.index = index
|
||||||
self.suffixes = suffixes
|
self.suffixes = suffixes
|
||||||
self.option = option
|
self.option = option
|
||||||
|
@ -198,12 +209,14 @@ class SubConfig:
|
||||||
self.path = path
|
self.path = path
|
||||||
if true_path is None:
|
if true_path is None:
|
||||||
true_path = path
|
true_path = path
|
||||||
|
is_follower = not option.impl_is_optiondescription() and option.impl_is_follower()
|
||||||
|
apply_requires = not is_follower or index is not None
|
||||||
self.true_path = true_path
|
self.true_path = true_path
|
||||||
|
settings = config_bag.context.get_settings()
|
||||||
if properties is undefined:
|
if properties is undefined:
|
||||||
if path is None:
|
if path is None:
|
||||||
self.properties = frozenset()
|
self.properties = frozenset()
|
||||||
else:
|
else:
|
||||||
settings = config_bag.context.get_settings()
|
|
||||||
self.properties = frozenset()
|
self.properties = frozenset()
|
||||||
if validate_properties:
|
if validate_properties:
|
||||||
self.properties = settings.getproperties(self,
|
self.properties = settings.getproperties(self,
|
||||||
|
@ -211,7 +224,7 @@ class SubConfig:
|
||||||
)
|
)
|
||||||
self.config_bag.context.get_settings().validate_properties(self)
|
self.config_bag.context.get_settings().validate_properties(self)
|
||||||
self.properties = settings.getproperties(self,
|
self.properties = settings.getproperties(self,
|
||||||
apply_requires=True,
|
apply_requires=apply_requires,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.properties = properties
|
self.properties = properties
|
||||||
|
@ -221,6 +234,15 @@ class SubConfig:
|
||||||
self.is_dynamic = False
|
self.is_dynamic = False
|
||||||
if validate_properties:
|
if validate_properties:
|
||||||
self.config_bag.context.get_settings().validate_properties(self)
|
self.config_bag.context.get_settings().validate_properties(self)
|
||||||
|
if self.option.impl_is_optiondescription():
|
||||||
|
if self.properties is not None:
|
||||||
|
self.raises_properties = settings.calc_raises_properties(self,
|
||||||
|
apply_requires=apply_requires,
|
||||||
|
not_unrestraint=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.raises_properties = frozenset()
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'<SubConfig path={self.path}, index={self.index}>'
|
return f'<SubConfig path={self.path}, index={self.index}>'
|
||||||
|
@ -228,7 +250,8 @@ class SubConfig:
|
||||||
def dyn_to_subconfig(self,
|
def dyn_to_subconfig(self,
|
||||||
child: Option,
|
child: Option,
|
||||||
validate_properties: bool,
|
validate_properties: bool,
|
||||||
follower_not_apply_requires: bool=False,
|
*,
|
||||||
|
true_path: Optional[str]=None,
|
||||||
) -> List['SubConfig']:
|
) -> List['SubConfig']:
|
||||||
config_bag = self.config_bag
|
config_bag = self.config_bag
|
||||||
for suffix in child.get_suffixes(self):
|
for suffix in child.get_suffixes(self):
|
||||||
|
@ -241,10 +264,10 @@ class SubConfig:
|
||||||
yield self.get_child(child,
|
yield self.get_child(child,
|
||||||
None,
|
None,
|
||||||
validate_properties,
|
validate_properties,
|
||||||
follower_not_apply_requires=follower_not_apply_requires,
|
|
||||||
suffix=suffix,
|
suffix=suffix,
|
||||||
name=name,
|
name=name,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
|
true_path=true_path,
|
||||||
)
|
)
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
if err.proptype in (['mandatory'], ['empty']):
|
if err.proptype in (['mandatory'], ['empty']):
|
||||||
|
@ -298,7 +321,6 @@ class SubConfig:
|
||||||
validate_properties: bool,
|
validate_properties: bool,
|
||||||
*,
|
*,
|
||||||
properties=undefined,
|
properties=undefined,
|
||||||
follower_not_apply_requires: bool=False,
|
|
||||||
allow_dynoption: bool=False,
|
allow_dynoption: bool=False,
|
||||||
suffix: Optional[str]=None,
|
suffix: Optional[str]=None,
|
||||||
name: Optional[str]=None,
|
name: Optional[str]=None,
|
||||||
|
@ -312,24 +334,6 @@ class SubConfig:
|
||||||
|
|
||||||
if not self.option.impl_is_optiondescription():
|
if not self.option.impl_is_optiondescription():
|
||||||
raise TypeError(f'"{self.path}" is not an optiondescription')
|
raise TypeError(f'"{self.path}" is not an optiondescription')
|
||||||
|
|
||||||
if check_index and index is not None:
|
|
||||||
if option.impl_is_optiondescription() or \
|
|
||||||
option.impl_is_symlinkoption() or \
|
|
||||||
not option.impl_is_follower():
|
|
||||||
raise ConfigError('index must be set only with a follower option')
|
|
||||||
length = self.get_length_leadership()
|
|
||||||
if index >= length:
|
|
||||||
raise LeadershipError(_(f'index "{index}" is greater than the leadership '
|
|
||||||
f'length "{length}" for option '
|
|
||||||
f'"{option.impl_get_display_name()}"'))
|
|
||||||
if properties is undefined and not validate_properties:
|
|
||||||
# not transitive property error
|
|
||||||
apply_requires = False
|
|
||||||
else:
|
|
||||||
apply_requires = not follower_not_apply_requires or \
|
|
||||||
option.impl_is_optiondescription() or \
|
|
||||||
not option.impl_is_follower()
|
|
||||||
path = self.get_path(name,
|
path = self.get_path(name,
|
||||||
option,
|
option,
|
||||||
)
|
)
|
||||||
|
@ -340,16 +344,27 @@ class SubConfig:
|
||||||
suffixes = self.suffixes + [suffix]
|
suffixes = self.suffixes + [suffix]
|
||||||
else:
|
else:
|
||||||
suffixes = [suffix]
|
suffixes = [suffix]
|
||||||
return SubConfig(option,
|
subsubconfig = SubConfig(option,
|
||||||
index,
|
index,
|
||||||
path,
|
path,
|
||||||
self.config_bag,
|
self.config_bag,
|
||||||
self,
|
self,
|
||||||
suffixes,
|
suffixes,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
validate_properties=validate_properties,
|
validate_properties=validate_properties,
|
||||||
true_path=true_path,
|
true_path=true_path,
|
||||||
)
|
)
|
||||||
|
if check_index and index is not None:
|
||||||
|
if option.impl_is_optiondescription() or \
|
||||||
|
option.impl_is_symlinkoption() or \
|
||||||
|
not option.impl_is_follower():
|
||||||
|
raise ConfigError('index must be set only with a follower option')
|
||||||
|
length = self.get_length_leadership()
|
||||||
|
if index >= length:
|
||||||
|
raise LeadershipError(_(f'index "{index}" is greater than the leadership '
|
||||||
|
f'length "{length}" for option '
|
||||||
|
f'"{option.impl_get_display_name(subsubconfig)}"'))
|
||||||
|
return subsubconfig
|
||||||
|
|
||||||
def get_path(self,
|
def get_path(self,
|
||||||
name: str,
|
name: str,
|
||||||
|
@ -379,10 +394,77 @@ class SubConfig:
|
||||||
cconfig_bag,
|
cconfig_bag,
|
||||||
self,
|
self,
|
||||||
self.suffixes,
|
self.suffixes,
|
||||||
|
validate_properties=False,
|
||||||
)
|
)
|
||||||
self._length = len(cconfig_bag.context.get_value(subconfig))
|
self._length = len(cconfig_bag.context.get_value(subconfig))
|
||||||
return self._length
|
return self._length
|
||||||
autolib.SubConfig = SubConfig
|
|
||||||
|
def get_common_child(self,
|
||||||
|
search_option: 'BaseOption',
|
||||||
|
true_path: Optional[str]=None,
|
||||||
|
validate_properties: bool=True,
|
||||||
|
):
|
||||||
|
current_option_path = self.option.impl_getpath()
|
||||||
|
search_option_path = search_option.impl_getpath()
|
||||||
|
common_path = get_common_path(current_option_path, search_option_path)
|
||||||
|
config_bag = self.config_bag
|
||||||
|
index = None
|
||||||
|
if not self.option.impl_is_optiondescription() and \
|
||||||
|
self.option.impl_is_follower() and search_option.impl_is_follower() and \
|
||||||
|
self.parent.option == search_option.impl_get_leadership():
|
||||||
|
index = self.index
|
||||||
|
search_child_number = 0
|
||||||
|
parents = [self.parent]
|
||||||
|
else:
|
||||||
|
if common_path:
|
||||||
|
parent = self.parent
|
||||||
|
common_parent_number = common_path.count('.') + 1
|
||||||
|
for idx in range(current_option_path.count('.') - common_parent_number):
|
||||||
|
parent = parent.parent
|
||||||
|
parents = [parent]
|
||||||
|
else:
|
||||||
|
common_parent_number = 0
|
||||||
|
parents = [config_bag.context.get_root(config_bag)]
|
||||||
|
search_child_number = search_option_path.count('.') - common_parent_number
|
||||||
|
subconfigs_is_a_list = False
|
||||||
|
if search_child_number:
|
||||||
|
if common_parent_number:
|
||||||
|
parent_paths = search_option_path.rsplit('.', search_child_number + 1)[1:-1]
|
||||||
|
else:
|
||||||
|
parent_paths = search_option_path.split('.')[:-1]
|
||||||
|
for parent_path in parent_paths:
|
||||||
|
new_parents = []
|
||||||
|
for parent in parents:
|
||||||
|
sub_option = parent.option.get_child(parent_path,
|
||||||
|
config_bag,
|
||||||
|
parent,
|
||||||
|
allow_dynoption=True,
|
||||||
|
)
|
||||||
|
if sub_option.impl_is_dynoptiondescription():
|
||||||
|
new_parents.extend(parent.dyn_to_subconfig(sub_option,
|
||||||
|
True,
|
||||||
|
true_path=true_path,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
subconfigs_is_a_list = True
|
||||||
|
else:
|
||||||
|
new_parents.append(parent.get_child(sub_option,
|
||||||
|
None,
|
||||||
|
validate_properties,
|
||||||
|
true_path=true_path,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
parents = new_parents
|
||||||
|
subconfigs = []
|
||||||
|
for parent in parents:
|
||||||
|
subconfigs.append(parent.get_child(search_option,
|
||||||
|
index,
|
||||||
|
validate_properties,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if subconfigs_is_a_list:
|
||||||
|
return subconfigs
|
||||||
|
return subconfigs[0]
|
||||||
|
|
||||||
|
|
||||||
class _Config(CCache):
|
class _Config(CCache):
|
||||||
|
@ -486,7 +568,6 @@ class _Config(CCache):
|
||||||
path,
|
path,
|
||||||
None,
|
None,
|
||||||
validate_properties=True,
|
validate_properties=True,
|
||||||
follower_not_apply_requires=False,
|
|
||||||
)
|
)
|
||||||
except PropertiesOptionError:
|
except PropertiesOptionError:
|
||||||
continue
|
continue
|
||||||
|
@ -541,7 +622,6 @@ class _Config(CCache):
|
||||||
index,
|
index,
|
||||||
*,
|
*,
|
||||||
validate_properties: bool=True,
|
validate_properties: bool=True,
|
||||||
follower_not_apply_requires: bool=False,
|
|
||||||
properties=undefined,
|
properties=undefined,
|
||||||
true_path: Optional[str]=None,
|
true_path: Optional[str]=None,
|
||||||
):
|
):
|
||||||
|
@ -577,7 +657,6 @@ class _Config(CCache):
|
||||||
subconfig = subconfig.get_child(option,
|
subconfig = subconfig.get_child(option,
|
||||||
index_,
|
index_,
|
||||||
validate_properties,
|
validate_properties,
|
||||||
follower_not_apply_requires=follower_not_apply_requires,
|
|
||||||
properties=properties,
|
properties=properties,
|
||||||
name=name,
|
name=name,
|
||||||
suffix=suffix,
|
suffix=suffix,
|
||||||
|
@ -647,17 +726,6 @@ class _Config(CCache):
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Manage value
|
# Manage value
|
||||||
def set_value(self,
|
|
||||||
subconfig: SubConfig,
|
|
||||||
value: Any,
|
|
||||||
) -> Any:
|
|
||||||
"""set value
|
|
||||||
"""
|
|
||||||
self.get_settings().validate_properties(subconfig)
|
|
||||||
return self.get_values().set_value(subconfig,
|
|
||||||
value
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_value(self,
|
def get_value(self,
|
||||||
subconfig,
|
subconfig,
|
||||||
need_help=True,
|
need_help=True,
|
||||||
|
@ -672,8 +740,9 @@ class _Config(CCache):
|
||||||
if isinstance(subconfig, list):
|
if isinstance(subconfig, list):
|
||||||
value = []
|
value = []
|
||||||
follower_subconfig = None
|
follower_subconfig = None
|
||||||
|
is_follower = not subconfig or subconfig[0].option.impl_is_follower()
|
||||||
for sconfig in subconfig:
|
for sconfig in subconfig:
|
||||||
if follower_subconfig is None:
|
if not is_follower or follower_subconfig is None:
|
||||||
follower_subconfig = self.get_sub_config(sconfig.config_bag,
|
follower_subconfig = self.get_sub_config(sconfig.config_bag,
|
||||||
sconfig.path,
|
sconfig.path,
|
||||||
sconfig.index,
|
sconfig.index,
|
||||||
|
@ -692,7 +761,7 @@ class _Config(CCache):
|
||||||
length = subconfig.parent.get_length_leadership()
|
length = subconfig.parent.get_length_leadership()
|
||||||
follower_len = self.get_values().get_max_length(subconfig.path)
|
follower_len = self.get_values().get_max_length(subconfig.path)
|
||||||
if follower_len > length:
|
if follower_len > length:
|
||||||
option_name = subconfig.option.impl_get_display_name()
|
option_name = subconfig.option.impl_get_display_name(subconfig)
|
||||||
raise LeadershipError(_(f'the follower option "{option_name}" '
|
raise LeadershipError(_(f'the follower option "{option_name}" '
|
||||||
f'has greater length ({follower_len}) than the leader '
|
f'has greater length ({follower_len}) than the leader '
|
||||||
f'length ({length})'))
|
f'length ({length})'))
|
||||||
|
@ -704,6 +773,7 @@ class _Config(CCache):
|
||||||
def _get(self,
|
def _get(self,
|
||||||
subconfig: "SubConfig",
|
subconfig: "SubConfig",
|
||||||
need_help: bool,
|
need_help: bool,
|
||||||
|
validate_properties: bool=True,
|
||||||
) -> "OptionBag":
|
) -> "OptionBag":
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
option = subconfig.option
|
option = subconfig.option
|
||||||
|
@ -712,17 +782,15 @@ class _Config(CCache):
|
||||||
suboption = option.impl_getopt()
|
suboption = option.impl_getopt()
|
||||||
if suboption.issubdyn():
|
if suboption.issubdyn():
|
||||||
dynopt = suboption.getsubdyn()
|
dynopt = suboption.getsubdyn()
|
||||||
return list(dynopt.get_sub_children(suboption,
|
return subconfig.get_common_child(suboption,
|
||||||
suboption.config_bag,
|
true_path=subconfig.path,
|
||||||
index=suboption.index,
|
validate_properties=validate_properties,
|
||||||
true_path=subconfig.path,
|
)
|
||||||
))
|
|
||||||
if suboption.impl_is_follower():
|
if suboption.impl_is_follower():
|
||||||
subconfig = self.get_sub_config(subconfig.config_bag, # pylint: disable=no-member
|
subconfig = self.get_sub_config(subconfig.config_bag, # pylint: disable=no-member
|
||||||
suboption.impl_getpath(),
|
suboption.impl_getpath(),
|
||||||
None,
|
None,
|
||||||
validate_properties=True,
|
validate_properties=validate_properties,
|
||||||
follower_not_apply_requires=False,
|
|
||||||
true_path=subconfig.path,
|
true_path=subconfig.path,
|
||||||
)
|
)
|
||||||
leadership_length = subconfig.parent.get_length_leadership()
|
leadership_length = subconfig.parent.get_length_leadership()
|
||||||
|
@ -739,8 +807,7 @@ class _Config(CCache):
|
||||||
s_subconfig = self.get_sub_config(subconfig.config_bag, # pylint: disable=no-member
|
s_subconfig = self.get_sub_config(subconfig.config_bag, # pylint: disable=no-member
|
||||||
suboption.impl_getpath(),
|
suboption.impl_getpath(),
|
||||||
None,
|
None,
|
||||||
validate_properties=True,
|
validate_properties=validate_properties,
|
||||||
follower_not_apply_requires=False,
|
|
||||||
true_path=subconfig.path,
|
true_path=subconfig.path,
|
||||||
)
|
)
|
||||||
return self._get(s_subconfig,
|
return self._get(s_subconfig,
|
||||||
|
@ -818,6 +885,7 @@ class _CommonConfig(_Config):
|
||||||
self.reset_cache(option_bag)
|
self.reset_cache(option_bag)
|
||||||
|
|
||||||
def impl_get_information(self,
|
def impl_get_information(self,
|
||||||
|
subconfig,
|
||||||
key,
|
key,
|
||||||
default,
|
default,
|
||||||
):
|
):
|
||||||
|
@ -893,7 +961,7 @@ class _CommonConfig(_Config):
|
||||||
duplicated_settings.rw_append = self.get_settings().rw_append
|
duplicated_settings.rw_append = self.get_settings().rw_append
|
||||||
duplicated_settings.ro_remove = self.get_settings().ro_remove
|
duplicated_settings.ro_remove = self.get_settings().ro_remove
|
||||||
duplicated_settings.rw_remove = self.get_settings().rw_remove
|
duplicated_settings.rw_remove = self.get_settings().rw_remove
|
||||||
duplicated_settings.default_properties = self.get_settings().default_properties
|
# duplicated_settings.default_properties = self.get_settings().default_properties
|
||||||
duplicated_config.reset_cache(None, None)
|
duplicated_config.reset_cache(None, None)
|
||||||
if child is not None:
|
if child is not None:
|
||||||
duplicated_config._impl_children.append(child) # pylint: disable=protected-access
|
duplicated_config._impl_children.append(child) # pylint: disable=protected-access
|
||||||
|
@ -1412,7 +1480,7 @@ class KernelMixConfig(KernelGroupConfig):
|
||||||
)
|
)
|
||||||
# Copy context properties/permissives
|
# Copy context properties/permissives
|
||||||
settings = config.get_settings()
|
settings = config.get_settings()
|
||||||
properties = settings.get_context_properties(config.properties_cache)
|
properties = settings.get_context_properties()
|
||||||
settings.set_context_properties(properties,
|
settings.set_context_properties(properties,
|
||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
|
@ -1421,7 +1489,7 @@ class KernelMixConfig(KernelGroupConfig):
|
||||||
settings.rw_append = settings.rw_append
|
settings.rw_append = settings.rw_append
|
||||||
settings.ro_remove = settings.ro_remove
|
settings.ro_remove = settings.ro_remove
|
||||||
settings.rw_remove = settings.rw_remove
|
settings.rw_remove = settings.rw_remove
|
||||||
settings.default_properties = settings.default_properties
|
# settings.default_properties = settings.default_properties
|
||||||
|
|
||||||
config.parents.append(weakref.ref(self))
|
config.parents.append(weakref.ref(self))
|
||||||
self._impl_children.append(config)
|
self._impl_children.append(config)
|
||||||
|
|
|
@ -70,8 +70,9 @@ class PropertiesOptionError(AttributeError):
|
||||||
self._opt_type = 'optiondescription'
|
self._opt_type = 'optiondescription'
|
||||||
else:
|
else:
|
||||||
self._opt_type = 'option'
|
self._opt_type = 'option'
|
||||||
self._name = subconfig.option.impl_get_display_name()
|
self._name = subconfig.option.impl_get_display_name(subconfig)
|
||||||
self._orig_opt = None
|
self._orig_opt = None
|
||||||
|
self._subconfig = subconfig
|
||||||
self.proptype = proptype
|
self.proptype = proptype
|
||||||
self.help_properties = help_properties
|
self.help_properties = help_properties
|
||||||
self._settings = settings
|
self._settings = settings
|
||||||
|
@ -108,8 +109,9 @@ class PropertiesOptionError(AttributeError):
|
||||||
else:
|
else:
|
||||||
msg = 'cannot access to {0} "{1}" because has {2} {3}'
|
msg = 'cannot access to {0} "{1}" because has {2} {3}'
|
||||||
if self._orig_opt:
|
if self._orig_opt:
|
||||||
|
# FIXME _orig_opt ?
|
||||||
self.msg = _(msg).format(self._opt_type,
|
self.msg = _(msg).format(self._opt_type,
|
||||||
self._orig_opt.impl_get_display_name(),
|
self._orig_opt.impl_get_display_name(subconfig),
|
||||||
self._name,
|
self._name,
|
||||||
prop_msg,
|
prop_msg,
|
||||||
properties_msg)
|
properties_msg)
|
||||||
|
@ -156,6 +158,7 @@ class ConstError(TypeError):
|
||||||
|
|
||||||
class _CommonError:
|
class _CommonError:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
|
subconfig,
|
||||||
val,
|
val,
|
||||||
display_type,
|
display_type,
|
||||||
opt,
|
opt,
|
||||||
|
@ -164,7 +167,7 @@ class _CommonError:
|
||||||
self.val = val
|
self.val = val
|
||||||
self.display_type = display_type
|
self.display_type = display_type
|
||||||
self.opt = weakref.ref(opt)
|
self.opt = weakref.ref(opt)
|
||||||
self.name = opt.impl_get_display_name()
|
self.name = opt.impl_get_display_name(subconfig)
|
||||||
self.err_msg = err_msg
|
self.err_msg = err_msg
|
||||||
self.index = index
|
self.index = index
|
||||||
super().__init__(self.err_msg)
|
super().__init__(self.err_msg)
|
||||||
|
|
|
@ -944,7 +944,7 @@ msgstr "option \"{0}\" inconnue dans l'optiondescription \"{1}\""
|
||||||
|
|
||||||
#: tiramisu/option/optiondescription.py:279
|
#: tiramisu/option/optiondescription.py:279
|
||||||
msgid "children in optiondescription \"{}\" must be a list"
|
msgid "children in optiondescription \"{}\" must be a list"
|
||||||
msgstr "les enfants d'une optiondescription \"{}\" doit être une liste"
|
msgstr "les enfants d'une optiondescription \"{}\" doivent être une liste"
|
||||||
|
|
||||||
#: tiramisu/option/optiondescription.py:303
|
#: tiramisu/option/optiondescription.py:303
|
||||||
msgid "duplicate option name: \"{0}\""
|
msgid "duplicate option name: \"{0}\""
|
||||||
|
|
|
@ -20,14 +20,14 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
"""base option
|
"""base option
|
||||||
"""
|
"""
|
||||||
from typing import FrozenSet, Set, Any, List
|
from typing import FrozenSet, Set, Any, List, Optional, Dict
|
||||||
import weakref
|
import weakref
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..setting import undefined
|
from ..setting import undefined
|
||||||
from ..autolib import Calculation, ParamOption
|
from ..autolib import Calculation, ParamOption, ParamInformation, ParamSelfInformation
|
||||||
|
|
||||||
STATIC_TUPLE = frozenset()
|
STATIC_TUPLE = frozenset()
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ class Base:
|
||||||
'_properties',
|
'_properties',
|
||||||
'_has_dependency',
|
'_has_dependency',
|
||||||
'_dependencies',
|
'_dependencies',
|
||||||
|
'_dependencies_information',
|
||||||
'_suffixes_dependencies',
|
'_suffixes_dependencies',
|
||||||
'__weakref__'
|
'__weakref__'
|
||||||
)
|
)
|
||||||
|
@ -64,8 +65,11 @@ class Base:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
doc: str,
|
doc: str,
|
||||||
|
informations: Optional[Dict],
|
||||||
|
*,
|
||||||
properties=None,
|
properties=None,
|
||||||
is_multi: bool=False) -> None:
|
is_multi: bool=False,
|
||||||
|
) -> None:
|
||||||
if not valid_name(name):
|
if not valid_name(name):
|
||||||
raise ValueError(_('"{0}" is an invalid name for an option').format(name))
|
raise ValueError(_('"{0}" is an invalid name for an option').format(name))
|
||||||
if properties is None:
|
if properties is None:
|
||||||
|
@ -83,6 +87,9 @@ class Base:
|
||||||
assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},'
|
assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},'
|
||||||
' must be a frozenset').format(type(properties),
|
' must be a frozenset').format(type(properties),
|
||||||
name)
|
name)
|
||||||
|
_setattr = object.__setattr__
|
||||||
|
_setattr(self, '_name', name)
|
||||||
|
_setattr(self, '_informations', {'doc': doc})
|
||||||
for prop in properties:
|
for prop in properties:
|
||||||
if not isinstance(prop, str):
|
if not isinstance(prop, str):
|
||||||
if not isinstance(prop, Calculation):
|
if not isinstance(prop, Calculation):
|
||||||
|
@ -91,11 +98,19 @@ class Base:
|
||||||
for param in chain(prop.params.args, prop.params.kwargs.values()):
|
for param in chain(prop.params.args, prop.params.kwargs.values()):
|
||||||
if isinstance(param, ParamOption):
|
if isinstance(param, ParamOption):
|
||||||
param.option._add_dependency(self)
|
param.option._add_dependency(self)
|
||||||
_setattr = object.__setattr__
|
|
||||||
_setattr(self, '_name', name)
|
|
||||||
_setattr(self, '_informations', {'doc': doc})
|
|
||||||
if properties:
|
if properties:
|
||||||
_setattr(self, '_properties', properties)
|
_setattr(self, '_properties', properties)
|
||||||
|
self.set_informations(informations)
|
||||||
|
|
||||||
|
def set_informations(self,
|
||||||
|
informations: Optional[Dict],
|
||||||
|
) -> None:
|
||||||
|
if not informations:
|
||||||
|
return
|
||||||
|
for key, value in informations.items():
|
||||||
|
self._set_information(key,
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
|
||||||
def impl_has_dependency(self,
|
def impl_has_dependency(self,
|
||||||
self_is_dep: bool=True,
|
self_is_dep: bool=True,
|
||||||
|
@ -196,10 +211,11 @@ class Base:
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# information
|
# information
|
||||||
def impl_get_information(self,
|
def _get_information(self,
|
||||||
key: str,
|
subconfig: "SubConfig",
|
||||||
default: Any=undefined,
|
key: str,
|
||||||
) -> Any:
|
default: Any=undefined,
|
||||||
|
) -> Any:
|
||||||
"""retrieves one information's item
|
"""retrieves one information's item
|
||||||
|
|
||||||
:param key: the item string (ex: "help")
|
:param key: the item string (ex: "help")
|
||||||
|
@ -217,13 +233,13 @@ class Base:
|
||||||
if default is not undefined:
|
if default is not undefined:
|
||||||
return default
|
return default
|
||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
raise ValueError(_(f'information\'s item for "{self.impl_get_display_name()}" '
|
raise ValueError(_(f'information\'s item for "{self.impl_get_display_name(subconfig)}" '
|
||||||
f'not found: "{key}"'))
|
f'not found: "{key}"'))
|
||||||
|
|
||||||
def impl_set_information(self,
|
def _set_information(self,
|
||||||
key: str,
|
key: str,
|
||||||
value: Any,
|
value: Any,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""updates the information's attribute
|
"""updates the information's attribute
|
||||||
(which is a dictionary)
|
(which is a dictionary)
|
||||||
|
|
||||||
|
@ -237,13 +253,13 @@ class Base:
|
||||||
key))
|
key))
|
||||||
self._informations[key] = value # pylint: disable=no-member
|
self._informations[key] = value # pylint: disable=no-member
|
||||||
|
|
||||||
def impl_list_information(self) -> Any:
|
def _list_information(self) -> Any:
|
||||||
"""get the list of information keys
|
"""get the list of information keys
|
||||||
"""
|
"""
|
||||||
dico = self._informations # pylint: disable=no-member
|
dico = self._informations # pylint: disable=no-member
|
||||||
if isinstance(dico, tuple):
|
if isinstance(dico, tuple):
|
||||||
return list(dico[0])
|
return list(dico[0])
|
||||||
if isinstance(dico, str):
|
if not isinstance(dico, dict):
|
||||||
return ['doc']
|
return ['doc']
|
||||||
# it's a dict
|
# it's a dict
|
||||||
return list(dico.keys())
|
return list(dico.keys())
|
||||||
|
@ -272,7 +288,7 @@ class BaseOption(Base):
|
||||||
if self.impl_is_readonly():
|
if self.impl_is_readonly():
|
||||||
raise AttributeError(_('"{}" ({}) object attribute "{}" is'
|
raise AttributeError(_('"{}" ({}) object attribute "{}" is'
|
||||||
' read-only').format(self.__class__.__name__,
|
' read-only').format(self.__class__.__name__,
|
||||||
self.impl_get_display_name(),
|
self.impl_get_display_name(None),
|
||||||
name))
|
name))
|
||||||
super().__setattr__(name, value)
|
super().__setattr__(name, value)
|
||||||
|
|
||||||
|
@ -282,21 +298,22 @@ class BaseOption(Base):
|
||||||
try:
|
try:
|
||||||
return self._path
|
return self._path
|
||||||
except AttributeError as err:
|
except AttributeError as err:
|
||||||
raise AttributeError(_(f'"{self.impl_get_display_name()}" not part of any Config')) \
|
raise AttributeError(_(f'"{self.impl_get_display_name(None)}" not part of any Config')) \
|
||||||
from err
|
from err
|
||||||
|
|
||||||
def impl_get_display_name(self,
|
def impl_get_display_name(self,
|
||||||
dynopt=None,
|
subconfig: "SubConfig",
|
||||||
) -> str:
|
) -> str:
|
||||||
"""get display name
|
"""get display name
|
||||||
"""
|
"""
|
||||||
if dynopt is None:
|
|
||||||
dynopt = self
|
|
||||||
if hasattr(self, '_display_name_function'):
|
if hasattr(self, '_display_name_function'):
|
||||||
return self._display_name_function(dynopt)
|
return self._display_name_function(self, subconfig)
|
||||||
name = self.impl_get_information('doc', None)
|
name = self._get_information(subconfig, 'doc', None)
|
||||||
if name is None or name == '':
|
if name is None or name == '':
|
||||||
name = dynopt.impl_getname()
|
if subconfig and subconfig.path:
|
||||||
|
name = subconfig.path.rsplit('.', 1)[-1]
|
||||||
|
else:
|
||||||
|
name = self._name
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def reset_cache(self,
|
def reset_cache(self,
|
||||||
|
@ -322,33 +339,43 @@ class BaseOption(Base):
|
||||||
"""
|
"""
|
||||||
return getattr(self, '_dependencies_information', {})
|
return getattr(self, '_dependencies_information', {})
|
||||||
|
|
||||||
def to_sub_dyoption(self,
|
def value_dependencies(self,
|
||||||
suffixes: list[str],
|
value: Any,
|
||||||
):
|
is_suffix: bool=False,
|
||||||
sub_dyn = self
|
) -> Any:
|
||||||
# retrieve all subdyn options
|
"""parse dependancies to add dependencies
|
||||||
sub_dyns = []
|
"""
|
||||||
while True:
|
if isinstance(value, list):
|
||||||
sub_dyn = sub_dyn.getsubdyn()
|
for val in value:
|
||||||
sub_dyns.append(sub_dyn)
|
if isinstance(value, list):
|
||||||
if not sub_dyn.issubdyn():
|
self.value_dependencies(val, is_suffix)
|
||||||
break
|
elif isinstance(value, Calculation):
|
||||||
paths = []
|
self.value_dependency(val, is_suffix)
|
||||||
parent_path = self.impl_getpath().rsplit('.', 1)[0]
|
elif isinstance(value, Calculation):
|
||||||
suffix_idx = len(sub_dyns) - 1
|
self.value_dependency(value, is_suffix)
|
||||||
for sub_dyn in sub_dyns:
|
|
||||||
dyn_path = sub_dyn.impl_getpath()
|
def value_dependency(self,
|
||||||
if dyn_path.count('.') == parent_path.count('.'):
|
value: Any,
|
||||||
*root_paths, dyn_path_ = parent_path.split('.', dyn_path.count('.') + 1)
|
is_suffix: bool=False,
|
||||||
else:
|
) -> Any:
|
||||||
*root_paths, dyn_path_, child_path = parent_path.split('.', dyn_path.count('.') + 1)
|
"""parse dependancy to add dependencies
|
||||||
paths.insert(0, child_path)
|
"""
|
||||||
paths.insert(0, sub_dyn.impl_getname(suffixes[suffix_idx]))
|
for param in chain(value.params.args, value.params.kwargs.values()):
|
||||||
suffix_idx -= 1
|
if isinstance(param, ParamOption):
|
||||||
parent_path = '.'.join(root_paths)
|
# pylint: disable=protected-access
|
||||||
if parent_path:
|
param.option._add_dependency(self, is_suffix=is_suffix)
|
||||||
paths.insert(0, parent_path)
|
self._has_dependency = True
|
||||||
full_parent_path = '.'.join(paths)
|
elif isinstance(param, ParamInformation):
|
||||||
return self.to_dynoption(full_parent_path,
|
dest = self
|
||||||
suffixes,
|
if isinstance(param, ParamSelfInformation):
|
||||||
)
|
opt = weakref.ref(self)
|
||||||
|
elif param.option:
|
||||||
|
dest = param.option
|
||||||
|
opt = weakref.ref(self)
|
||||||
|
else:
|
||||||
|
param.set_self_option(self)
|
||||||
|
opt = None
|
||||||
|
if not getattr(dest, '_dependencies_information', {}):
|
||||||
|
dest._dependencies_information = {None: []}
|
||||||
|
dest._dependencies_information[None].append(param)
|
||||||
|
dest._dependencies_information.setdefault(param.information_name, []).append(opt)
|
||||||
|
|
|
@ -25,7 +25,7 @@ from typing import Any
|
||||||
from ..setting import undefined
|
from ..setting import undefined
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from .option import Option
|
from .option import Option
|
||||||
from ..autolib import Calculation
|
from ..autolib import Calculation, get_calculated_value
|
||||||
from ..error import ConfigError, display_list
|
from ..error import ConfigError, display_list
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,13 +61,16 @@ class ChoiceOption(Option):
|
||||||
):
|
):
|
||||||
"""get values allowed by option
|
"""get values allowed by option
|
||||||
"""
|
"""
|
||||||
if isinstance(self._choice_values, Calculation):
|
choices = self._choice_values
|
||||||
values = self._choice_values.execute(subconfig)
|
if isinstance(choices, tuple):
|
||||||
if values is not undefined and not isinstance(values, list):
|
choices = list(choices)
|
||||||
raise ConfigError(_('the calculated values "{0}" for "{1}" is not a list'
|
values = get_calculated_value(subconfig,
|
||||||
'').format(values, self.impl_getname()))
|
choices,
|
||||||
else:
|
)[0]
|
||||||
values = self._choice_values
|
|
||||||
|
if values != undefined and not isinstance(values, (list, tuple)):
|
||||||
|
raise ConfigError(_('the calculated values "{0}" for "{1}" is not a list'
|
||||||
|
'').format(values, self.impl_getname()))
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def validate(self,
|
def validate(self,
|
||||||
|
|
|
@ -20,22 +20,23 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
"""DynOptionDescription
|
"""DynOptionDescription
|
||||||
"""
|
"""
|
||||||
|
import re
|
||||||
import weakref
|
import weakref
|
||||||
from typing import List, Any, Optional
|
from typing import List, Any, Optional, Dict
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from ..autolib import ParamOption
|
from ..autolib import ParamOption
|
||||||
|
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from .optiondescription import OptionDescription
|
from .optiondescription import OptionDescription
|
||||||
from .syndynoption import CommonDyn #, SynDynLeadership
|
|
||||||
from .baseoption import BaseOption
|
from .baseoption import BaseOption
|
||||||
from ..setting import ConfigBag, undefined
|
from ..setting import ConfigBag, undefined
|
||||||
from ..error import ConfigError
|
from ..error import ConfigError
|
||||||
from ..autolib import Calculation
|
from ..autolib import Calculation, get_calculated_value
|
||||||
|
|
||||||
|
|
||||||
class DynOptionDescription(OptionDescription, CommonDyn):
|
NAME_REGEXP = re.compile(r'^[a-zA-Z\d\-_]*$')
|
||||||
|
class DynOptionDescription(OptionDescription):
|
||||||
"""dyn option description
|
"""dyn option description
|
||||||
"""
|
"""
|
||||||
__slots__ = ('_suffixes',
|
__slots__ = ('_suffixes',
|
||||||
|
@ -48,25 +49,28 @@ class DynOptionDescription(OptionDescription, CommonDyn):
|
||||||
children: List[BaseOption],
|
children: List[BaseOption],
|
||||||
suffixes: Calculation,
|
suffixes: Calculation,
|
||||||
properties=None,
|
properties=None,
|
||||||
|
informations: Optional[Dict]=None,
|
||||||
) -> None:
|
) -> None:
|
||||||
# pylint: disable=too-many-arguments
|
# pylint: disable=too-many-arguments
|
||||||
super().__init__(name,
|
super().__init__(name,
|
||||||
doc,
|
doc,
|
||||||
children,
|
children,
|
||||||
properties,
|
properties,
|
||||||
|
informations=informations,
|
||||||
)
|
)
|
||||||
# check children + set relation to this dynoptiondescription
|
# check children + set relation to this dynoptiondescription
|
||||||
wself = weakref.ref(self)
|
wself = weakref.ref(self)
|
||||||
for child in children:
|
for child in children:
|
||||||
child._setsubdyn(wself)
|
child._setsubdyn(wself)
|
||||||
# add suffixes
|
# add suffixes
|
||||||
if __debug__ and not isinstance(suffixes, Calculation):
|
self.value_dependencies(suffixes, is_suffix=True)
|
||||||
raise ConfigError(_('suffixes in dynoptiondescription has to be a calculation'))
|
# if __debug__ and not isinstance(suffixes, Calculation):
|
||||||
for param in chain(suffixes.params.args, suffixes.params.kwargs.values()):
|
# raise ConfigError(_('suffixes in dynoptiondescription has to be a calculation'))
|
||||||
if isinstance(param, ParamOption):
|
# for param in chain(suffixes.params.args, suffixes.params.kwargs.values()):
|
||||||
param.option._add_dependency(self,
|
# if isinstance(param, ParamOption):
|
||||||
is_suffix=True,
|
# param.option._add_dependency(self,
|
||||||
)
|
# is_suffix=True,
|
||||||
|
# )
|
||||||
self._suffixes = suffixes
|
self._suffixes = suffixes
|
||||||
|
|
||||||
def convert_suffix_to_path(self,
|
def convert_suffix_to_path(self,
|
||||||
|
@ -98,3 +102,42 @@ class DynOptionDescription(OptionDescription, CommonDyn):
|
||||||
return name
|
return name
|
||||||
path_suffix = self.convert_suffix_to_path(suffix)
|
path_suffix = self.convert_suffix_to_path(suffix)
|
||||||
return name + path_suffix
|
return name + path_suffix
|
||||||
|
|
||||||
|
def get_suffixes(self,
|
||||||
|
parent: 'SubConfig',
|
||||||
|
) -> List[str]:
|
||||||
|
"""get dynamic suffixes
|
||||||
|
"""
|
||||||
|
subconfig = parent.get_child(self,
|
||||||
|
None,
|
||||||
|
False,
|
||||||
|
properties=None,
|
||||||
|
)
|
||||||
|
suffixes = self._suffixes
|
||||||
|
if isinstance(suffixes, list):
|
||||||
|
suffixes = suffixes.copy()
|
||||||
|
values = get_calculated_value(subconfig,
|
||||||
|
suffixes,
|
||||||
|
validate_properties=False,
|
||||||
|
)[0]
|
||||||
|
if values is None:
|
||||||
|
values = []
|
||||||
|
values_ = []
|
||||||
|
if __debug__:
|
||||||
|
if not isinstance(values, list):
|
||||||
|
raise ValueError(_('DynOptionDescription suffixes for '
|
||||||
|
f'option "{self.impl_get_display_name(subconfig)}", is not '
|
||||||
|
f'a list ({values})'))
|
||||||
|
for val in values:
|
||||||
|
cval = self.convert_suffix_to_path(val)
|
||||||
|
if not isinstance(cval, str) or re.match(NAME_REGEXP, cval) is None:
|
||||||
|
if __debug__ and cval is not None:
|
||||||
|
raise ValueError(_('invalid suffix "{}" for option "{}"'
|
||||||
|
'').format(cval,
|
||||||
|
self.impl_get_display_name(subconfig)))
|
||||||
|
else:
|
||||||
|
values_.append(val)
|
||||||
|
if __debug__ and len(values_) > len(set(values_)):
|
||||||
|
raise ValueError(_(f'DynOptionDescription "{self._name}" suffixes return a list with '
|
||||||
|
f'same values "{values_}"'''))
|
||||||
|
return values_
|
||||||
|
|
|
@ -75,15 +75,15 @@ class Leadership(OptionDescription):
|
||||||
def _check_child_is_valid(self, child: BaseOption):
|
def _check_child_is_valid(self, child: BaseOption):
|
||||||
if child.impl_is_symlinkoption():
|
if child.impl_is_symlinkoption():
|
||||||
raise ValueError(_('leadership "{0}" shall not have '
|
raise ValueError(_('leadership "{0}" shall not have '
|
||||||
"a symlinkoption").format(self.impl_get_display_name()))
|
"a symlinkoption").format(self.impl_get_display_name(None)))
|
||||||
if not isinstance(child, Option):
|
if not isinstance(child, Option):
|
||||||
raise ValueError(_('leadership "{0}" shall not have '
|
raise ValueError(_('leadership "{0}" shall not have '
|
||||||
'a subgroup').format(self.impl_get_display_name()))
|
'a subgroup').format(self.impl_get_display_name(None)))
|
||||||
if not child.impl_is_multi():
|
if not child.impl_is_multi():
|
||||||
raise ValueError(_('only multi option allowed in leadership "{0}" but option '
|
raise ValueError(_('only multi option allowed in leadership "{0}" but option '
|
||||||
'"{1}" is not a multi'
|
'"{1}" is not a multi'
|
||||||
'').format(self.impl_get_display_name(),
|
'').format(self.impl_get_display_name(None),
|
||||||
child.impl_get_display_name()))
|
child.impl_get_display_name(None)))
|
||||||
|
|
||||||
def _check_default_value(self, child: BaseOption):
|
def _check_default_value(self, child: BaseOption):
|
||||||
default = child.impl_getdefault()
|
default = child.impl_getdefault()
|
||||||
|
@ -100,8 +100,8 @@ class Leadership(OptionDescription):
|
||||||
calculation = isinstance(default, Calculation)
|
calculation = isinstance(default, Calculation)
|
||||||
if not calculation:
|
if not calculation:
|
||||||
raise ValueError(_('not allowed default value for follower option '
|
raise ValueError(_('not allowed default value for follower option '
|
||||||
f'"{child.impl_get_display_name()}" in leadership '
|
f'"{child.impl_get_display_name(None)}" in leadership '
|
||||||
f'"{self.impl_get_display_name()}"'))
|
f'"{self.impl_get_display_name(None)}"'))
|
||||||
|
|
||||||
def _setsubdyn(self,
|
def _setsubdyn(self,
|
||||||
subdyn,
|
subdyn,
|
||||||
|
@ -143,58 +143,54 @@ class Leadership(OptionDescription):
|
||||||
def reset(self, parent: "SubConfig") -> None:
|
def reset(self, parent: "SubConfig") -> None:
|
||||||
"""reset follower value
|
"""reset follower value
|
||||||
"""
|
"""
|
||||||
#config_bag = parent.option_bag.config_bag
|
|
||||||
values = parent.config_bag.context.get_values()
|
values = parent.config_bag.context.get_values()
|
||||||
#config_bag = config_bag.copy()
|
|
||||||
#config_bag.remove_validation()
|
|
||||||
for follower in self.get_followers():
|
for follower in self.get_followers():
|
||||||
subconfig_follower = parent.get_child(follower,
|
subconfig_follower = parent.get_child(follower,
|
||||||
None,
|
None,
|
||||||
False,
|
False,
|
||||||
)
|
)
|
||||||
# OptionBag(follower,
|
values.reset(subconfig_follower,
|
||||||
# None,
|
validate=False,
|
||||||
# config_bag,
|
)
|
||||||
# )
|
|
||||||
values.reset(subconfig_follower)
|
def follower_force_store_value(self,
|
||||||
#
|
value,
|
||||||
# def follower_force_store_value(self,
|
subconfig: 'SubConfig',
|
||||||
# value,
|
owner,
|
||||||
# config_bag: 'ConfigBag',
|
) -> None:
|
||||||
# owner,
|
"""apply force_store_value to follower
|
||||||
# dyn=None,
|
"""
|
||||||
# ) -> None:
|
if not value:
|
||||||
# """apply force_store_value to follower
|
return
|
||||||
# """
|
config_bag = subconfig.config_bag
|
||||||
# if value:
|
values = config_bag.context.get_values()
|
||||||
# if dyn is None:
|
for idx, follower in enumerate(self.get_children()):
|
||||||
# dyn = self
|
sub_subconfig = subconfig.get_child(follower,
|
||||||
# values = config_bag.context.get_values()
|
None,
|
||||||
# for idx, follower in enumerate(dyn.get_children(config_bag)):
|
False,
|
||||||
# if not idx:
|
config_bag=config_bag,
|
||||||
# # it's a master
|
)
|
||||||
# apply_requires = True
|
if 'force_store_value' not in sub_subconfig.properties:
|
||||||
# indexes = [None]
|
continue
|
||||||
# else:
|
self_path = sub_subconfig.path
|
||||||
# apply_requires = False
|
if not idx:
|
||||||
# indexes = range(len(value))
|
# it's a master
|
||||||
# foption_bag = OptionBag(follower,
|
apply_requires = True
|
||||||
# None,
|
indexes = [None]
|
||||||
# config_bag,
|
else:
|
||||||
# apply_requires=apply_requires,
|
apply_requires = False
|
||||||
# )
|
indexes = range(len(value))
|
||||||
# if 'force_store_value' not in foption_bag.properties:
|
for index in indexes:
|
||||||
# continue
|
i_sub_subconfig = subconfig.get_child(follower,
|
||||||
# for index in indexes:
|
index,
|
||||||
# foption_bag_index = OptionBag(follower,
|
False,
|
||||||
# index,
|
config_bag=config_bag,
|
||||||
# config_bag,
|
)
|
||||||
# )
|
values.set_storage_value(self_path,
|
||||||
# values.set_storage_value(foption_bag_index.path,
|
index,
|
||||||
# index,
|
values.get_value(i_sub_subconfig)[0],
|
||||||
# values.get_value(foption_bag_index)[0],
|
owner,
|
||||||
# owner,
|
)
|
||||||
# )
|
|
||||||
|
|
||||||
def pop(self,
|
def pop(self,
|
||||||
subconfig: 'SubConfig',
|
subconfig: 'SubConfig',
|
||||||
|
|
|
@ -26,9 +26,8 @@ from itertools import chain
|
||||||
from .baseoption import BaseOption, submulti
|
from .baseoption import BaseOption, submulti
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..setting import undefined
|
from ..setting import undefined
|
||||||
from ..autolib import Calculation, ParamOption, ParamInformation, ParamSelfInformation
|
from ..autolib import Calculation
|
||||||
from ..error import ValueWarning, ValueErrorWarning, ValueOptionError
|
from ..error import ValueWarning, ValueErrorWarning, ValueOptionError
|
||||||
from .syndynoption import SynDynOption
|
|
||||||
|
|
||||||
|
|
||||||
class Option(BaseOption):
|
class Option(BaseOption):
|
||||||
|
@ -48,7 +47,6 @@ class Option(BaseOption):
|
||||||
#
|
#
|
||||||
'_validators',
|
'_validators',
|
||||||
#
|
#
|
||||||
'_dependencies_information',
|
|
||||||
'_leadership',
|
'_leadership',
|
||||||
'_choice_values',
|
'_choice_values',
|
||||||
'_choice_values_params',
|
'_choice_values_params',
|
||||||
|
@ -63,7 +61,9 @@ class Option(BaseOption):
|
||||||
validators: Optional[List[Calculation]]=None,
|
validators: Optional[List[Calculation]]=None,
|
||||||
properties: Optional[List[str]]=None,
|
properties: Optional[List[str]]=None,
|
||||||
warnings_only: bool=False,
|
warnings_only: bool=False,
|
||||||
extra: Optional[Dict]=None):
|
extra: Optional[Dict]=None,
|
||||||
|
informations: Optional[Dict]=None,
|
||||||
|
):
|
||||||
_setattr = object.__setattr__
|
_setattr = object.__setattr__
|
||||||
if not multi and default_multi is not None:
|
if not multi and default_multi is not None:
|
||||||
raise ValueError(_("default_multi is set whereas multi is False"
|
raise ValueError(_("default_multi is set whereas multi is False"
|
||||||
|
@ -92,8 +92,10 @@ class Option(BaseOption):
|
||||||
default = []
|
default = []
|
||||||
super().__init__(name,
|
super().__init__(name,
|
||||||
doc,
|
doc,
|
||||||
|
informations,
|
||||||
properties=properties,
|
properties=properties,
|
||||||
is_multi=is_multi)
|
is_multi=is_multi,
|
||||||
|
)
|
||||||
if validators is not None:
|
if validators is not None:
|
||||||
if __debug__ and not isinstance(validators, list):
|
if __debug__ and not isinstance(validators, list):
|
||||||
raise ValueError(_(f'validators must be a list of Calculation for "{name}"'))
|
raise ValueError(_(f'validators must be a list of Calculation for "{name}"'))
|
||||||
|
@ -126,10 +128,10 @@ class Option(BaseOption):
|
||||||
if not str_err:
|
if not str_err:
|
||||||
raise ValueError(_('invalid default_multi value "{0}" '
|
raise ValueError(_('invalid default_multi value "{0}" '
|
||||||
'for option "{1}"').format(str(value),
|
'for option "{1}"').format(str(value),
|
||||||
self.impl_get_display_name())
|
self.impl_get_display_name(None))
|
||||||
) from err
|
) from err
|
||||||
raise ValueError(_(f'invalid default_multi value "{value}" for option '
|
raise ValueError(_(f'invalid default_multi value "{value}" for option '
|
||||||
f'"{self.impl_get_display_name()}", {str_err}')
|
f'"{self.impl_get_display_name(None)}", {str_err}')
|
||||||
) from err
|
) from err
|
||||||
if _multi is submulti:
|
if _multi is submulti:
|
||||||
if not isinstance(default_multi, Calculation):
|
if not isinstance(default_multi, Calculation):
|
||||||
|
@ -137,7 +139,7 @@ class Option(BaseOption):
|
||||||
raise ValueError(_('invalid default_multi value "{0}" '
|
raise ValueError(_('invalid default_multi value "{0}" '
|
||||||
'for option "{1}", must be a list for a submulti'
|
'for option "{1}", must be a list for a submulti'
|
||||||
'').format(str(default_multi),
|
'').format(str(default_multi),
|
||||||
self.impl_get_display_name()))
|
self.impl_get_display_name(None)))
|
||||||
for value in default_multi:
|
for value in default_multi:
|
||||||
test_multi_value(value)
|
test_multi_value(value)
|
||||||
else:
|
else:
|
||||||
|
@ -164,43 +166,6 @@ class Option(BaseOption):
|
||||||
default = tuple(default)
|
default = tuple(default)
|
||||||
_setattr(self, '_default', default)
|
_setattr(self, '_default', default)
|
||||||
|
|
||||||
def value_dependencies(self,
|
|
||||||
value: Any,
|
|
||||||
) -> Any:
|
|
||||||
"""parse dependancies to add dependencies
|
|
||||||
"""
|
|
||||||
if isinstance(value, list):
|
|
||||||
for val in value:
|
|
||||||
if isinstance(value, list):
|
|
||||||
self.value_dependencies(val)
|
|
||||||
elif isinstance(value, Calculation):
|
|
||||||
self.value_dependency(val)
|
|
||||||
elif isinstance(value, Calculation):
|
|
||||||
self.value_dependency(value)
|
|
||||||
|
|
||||||
def value_dependency(self,
|
|
||||||
value: Any,
|
|
||||||
) -> Any:
|
|
||||||
"""parse dependancy to add dependencies
|
|
||||||
"""
|
|
||||||
for param in chain(value.params.args, value.params.kwargs.values()):
|
|
||||||
if isinstance(param, ParamOption):
|
|
||||||
# pylint: disable=protected-access
|
|
||||||
param.option._add_dependency(self)
|
|
||||||
self._has_dependency = True
|
|
||||||
elif isinstance(param, ParamInformation):
|
|
||||||
dest = self
|
|
||||||
if isinstance(param, ParamSelfInformation):
|
|
||||||
opt = self
|
|
||||||
elif param.option:
|
|
||||||
dest = param.option
|
|
||||||
opt = self
|
|
||||||
else:
|
|
||||||
opt = None
|
|
||||||
if not getattr(dest, '_dependencies_information', {}):
|
|
||||||
dest._dependencies_information = {}
|
|
||||||
dest._dependencies_information.setdefault(param.information_name, []).append(opt)
|
|
||||||
|
|
||||||
#__________________________________________________________________________
|
#__________________________________________________________________________
|
||||||
# option's information
|
# option's information
|
||||||
|
|
||||||
|
@ -326,7 +291,8 @@ class Option(BaseOption):
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
except ValueWarning as warn:
|
except ValueWarning as warn:
|
||||||
warnings.warn_explicit(ValueWarning(val,
|
warnings.warn_explicit(ValueWarning(subconfig,
|
||||||
|
val,
|
||||||
self.get_type(),
|
self.get_type(),
|
||||||
self,
|
self,
|
||||||
str(warn),
|
str(warn),
|
||||||
|
@ -343,7 +309,7 @@ class Option(BaseOption):
|
||||||
return
|
return
|
||||||
if isinstance(_value, list):
|
if isinstance(_value, list):
|
||||||
raise ValueError(_('which must not be a list').format(_value,
|
raise ValueError(_('which must not be a list').format(_value,
|
||||||
self.impl_get_display_name()),
|
self.impl_get_display_name(subconfig)),
|
||||||
)
|
)
|
||||||
if isinstance(_value, Calculation) and not subconfig:
|
if isinstance(_value, Calculation) and not subconfig:
|
||||||
return
|
return
|
||||||
|
@ -361,7 +327,8 @@ class Option(BaseOption):
|
||||||
is_warnings_only)
|
is_warnings_only)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
if is_warnings_only:
|
if is_warnings_only:
|
||||||
warnings.warn_explicit(ValueWarning(_value,
|
warnings.warn_explicit(ValueWarning(subconfig,
|
||||||
|
_value,
|
||||||
self.get_type(),
|
self.get_type(),
|
||||||
self,
|
self,
|
||||||
str(err),
|
str(err),
|
||||||
|
@ -420,12 +387,14 @@ class Option(BaseOption):
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
if not subconfig or \
|
if not subconfig or \
|
||||||
'demoting_error_warning' not in subconfig.config_bag.properties:
|
'demoting_error_warning' not in subconfig.config_bag.properties:
|
||||||
raise ValueOptionError(val,
|
raise ValueOptionError(subconfig,
|
||||||
|
val,
|
||||||
self.get_type(),
|
self.get_type(),
|
||||||
self,
|
self,
|
||||||
str(err),
|
str(err),
|
||||||
err_index) from err
|
err_index) from err
|
||||||
warnings.warn_explicit(ValueErrorWarning(val,
|
warnings.warn_explicit(ValueErrorWarning(subconfig,
|
||||||
|
val,
|
||||||
self.get_type(),
|
self.get_type(),
|
||||||
self,
|
self,
|
||||||
str(err),
|
str(err),
|
||||||
|
@ -476,16 +445,6 @@ class Option(BaseOption):
|
||||||
#pylint: disable=not-callable
|
#pylint: disable=not-callable
|
||||||
return leadership()
|
return leadership()
|
||||||
|
|
||||||
def to_dynoption(self,
|
|
||||||
rootpath: str,
|
|
||||||
suffixes: list[str],
|
|
||||||
) -> SynDynOption:
|
|
||||||
"""tranforme a dynoption to a syndynoption
|
|
||||||
"""
|
|
||||||
return SynDynOption(self,
|
|
||||||
rootpath,
|
|
||||||
suffixes,
|
|
||||||
)
|
|
||||||
def validate(self, value: Any):
|
def validate(self, value: Any):
|
||||||
"""option needs a validate function
|
"""option needs a validate function
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
"""OptionDescription
|
"""OptionDescription
|
||||||
"""
|
"""
|
||||||
import weakref
|
import weakref
|
||||||
from typing import Optional, Iterator, Union, List
|
from typing import Optional, Iterator, Union, List, Dict
|
||||||
|
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
|
@ -87,6 +87,10 @@ class CacheOptionDescription(BaseOption):
|
||||||
dependencies_information,
|
dependencies_information,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
informations = option.get_dependencies_information()
|
||||||
|
if informations:
|
||||||
|
for param in informations.pop(None):
|
||||||
|
del param.self_option
|
||||||
for information, options in option.get_dependencies_information().items():
|
for information, options in option.get_dependencies_information().items():
|
||||||
if None in options:
|
if None in options:
|
||||||
dependencies_information.setdefault(information, []).append(option)
|
dependencies_information.setdefault(information, []).append(option)
|
||||||
|
@ -105,71 +109,86 @@ class CacheOptionDescription(BaseOption):
|
||||||
self._cache_dependencies_information = dependencies_information # pylint: disable=attribute-defined-outside-init
|
self._cache_dependencies_information = dependencies_information # pylint: disable=attribute-defined-outside-init
|
||||||
self._path = None # pylint: disable=attribute-defined-outside-init,no-member
|
self._path = None # pylint: disable=attribute-defined-outside-init,no-member
|
||||||
self._set_readonly()
|
self._set_readonly()
|
||||||
#
|
|
||||||
# def impl_build_force_store_values(self,
|
def impl_build_force_store_values(self,
|
||||||
# config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
# ) -> None:
|
) -> None:
|
||||||
# """set value to force_store_values option
|
"""set value to force_store_values option
|
||||||
# """
|
"""
|
||||||
# # pylint: disable=too-many-branches
|
# pylint: disable=too-many-branches
|
||||||
# def do_option_bags(option):
|
context = config_bag.context
|
||||||
# if option.issubdyn():
|
if 'force_store_value' not in config_bag.properties:
|
||||||
# dynopt = option.getsubdyn()
|
return
|
||||||
# yield from dynopt.get_sub_children(option,
|
|
||||||
# config_bag,
|
values = config_bag.context.get_values()
|
||||||
# index=None,
|
for option in self._cache_force_store_values:
|
||||||
# )
|
if option.issubdyn():
|
||||||
# else:
|
paths = option.impl_getpath().split('.')
|
||||||
# yield OptionBag(option,
|
parents = [config_bag.context.get_root(config_bag)]
|
||||||
# None,
|
for name in paths:
|
||||||
# config_bag,
|
new_parents = []
|
||||||
# properties=None,
|
for parent in parents:
|
||||||
# )
|
doption = parent.option.get_child(name,
|
||||||
# if 'force_store_value' not in config_bag.properties:
|
config_bag,
|
||||||
# return
|
parent,
|
||||||
# values = config_bag.context.get_values()
|
allow_dynoption=True,
|
||||||
# for option in self._cache_force_store_values:
|
)
|
||||||
# if option.impl_is_follower():
|
if doption.impl_is_dynoptiondescription():
|
||||||
# leader = option.impl_get_leadership().get_leader()
|
new_parents.extend(parent.dyn_to_subconfig(doption,
|
||||||
# for leader_option_bag in do_option_bags(leader):
|
True,
|
||||||
# leader_option_bag.properties = frozenset()
|
)
|
||||||
# follower_len = len(values.get_value(leader_option_bag)[0])
|
)
|
||||||
# if option.issubdyn():
|
else:
|
||||||
# doption = option.to_dynoption(leader_option_bag.option.rootpath,
|
new_parents.append(parent.get_child(doption,
|
||||||
# leader_option_bag.option.get_current_suffixes(),
|
None,
|
||||||
# )
|
True,
|
||||||
# else:
|
name=name,
|
||||||
# doption = option
|
))
|
||||||
# subpath = doption.impl_getpath()
|
parents = new_parents
|
||||||
# for index in range(follower_len):
|
subconfigs = new_parents
|
||||||
# option_bag = OptionBag(doption,
|
else:
|
||||||
# index,
|
subconfigs = [context.get_sub_config(config_bag,
|
||||||
# config_bag,
|
option.impl_getpath(),
|
||||||
# properties=frozenset(),
|
None,
|
||||||
# )
|
properties=None,
|
||||||
# if values.hasvalue(subpath, index=index):
|
validate_properties=False,
|
||||||
# continue
|
)]
|
||||||
# value = values.get_value(option_bag)[0]
|
|
||||||
# if value is None:
|
if option.impl_is_follower():
|
||||||
# continue
|
for follower_subconfig in subconfigs:
|
||||||
# values.set_storage_value(subpath,
|
parent = follower_subconfig.parent
|
||||||
# index,
|
follower_len = parent.get_length_leadership()
|
||||||
# value,
|
for index in range(follower_len):
|
||||||
# owners.forced,
|
if values.hasvalue(follower_subconfig.path,
|
||||||
# )
|
index=index,
|
||||||
# else:
|
):
|
||||||
# for option_bag in do_option_bags(option):
|
continue
|
||||||
# option_bag.properties = frozenset()
|
idx_follower_subconfig = parent.get_child(follower_subconfig.option,
|
||||||
# value = values.get_value(option_bag)[0]
|
index,
|
||||||
# if value is None:
|
validate_properties=False,
|
||||||
# continue
|
)
|
||||||
# if values.hasvalue(option_bag.path):
|
|
||||||
# continue
|
value = values.get_value(idx_follower_subconfig)[0]
|
||||||
# values.set_storage_value(option_bag.path,
|
if value is None:
|
||||||
# None,
|
continue
|
||||||
# value,
|
values.set_storage_value(follower_subconfig.path,
|
||||||
# owners.forced,
|
index,
|
||||||
# )
|
value,
|
||||||
|
owners.forced,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
for subconfig in subconfigs:
|
||||||
|
subconfig.properties = frozenset()
|
||||||
|
value = values.get_value(subconfig)[0]
|
||||||
|
if value is None:
|
||||||
|
continue
|
||||||
|
if values.hasvalue(subconfig.path):
|
||||||
|
continue
|
||||||
|
values.set_storage_value(subconfig.path,
|
||||||
|
None,
|
||||||
|
value,
|
||||||
|
owners.forced,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OptionDescriptionWalk(CacheOptionDescription):
|
class OptionDescriptionWalk(CacheOptionDescription):
|
||||||
|
@ -228,7 +247,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||||
'in root optiondescription'
|
'in root optiondescription'
|
||||||
))
|
))
|
||||||
raise AttributeError(_(f'unknown option "{name}" '
|
raise AttributeError(_(f'unknown option "{name}" '
|
||||||
f'in optiondescription "{self.impl_get_display_name()}"'
|
f'in optiondescription "{self.impl_get_display_name(parent)}"'
|
||||||
))
|
))
|
||||||
|
|
||||||
def get_children(self) -> List[BaseOption]:
|
def get_children(self) -> List[BaseOption]:
|
||||||
|
@ -278,7 +297,9 @@ class OptionDescription(OptionDescriptionWalk):
|
||||||
name: str,
|
name: str,
|
||||||
doc: str,
|
doc: str,
|
||||||
children: List[BaseOption],
|
children: List[BaseOption],
|
||||||
properties=None) -> None:
|
properties=None,
|
||||||
|
informations: Optional[Dict]=None,
|
||||||
|
) -> None:
|
||||||
"""
|
"""
|
||||||
:param children: a list of options (including optiondescriptions)
|
:param children: a list of options (including optiondescriptions)
|
||||||
|
|
||||||
|
@ -286,8 +307,10 @@ class OptionDescription(OptionDescriptionWalk):
|
||||||
assert isinstance(children, list), _('children in optiondescription "{}" '
|
assert isinstance(children, list), _('children in optiondescription "{}" '
|
||||||
'must be a list').format(name)
|
'must be a list').format(name)
|
||||||
super().__init__(name,
|
super().__init__(name,
|
||||||
doc=doc,
|
doc,
|
||||||
properties=properties)
|
informations,
|
||||||
|
properties=properties,
|
||||||
|
)
|
||||||
child_names = []
|
child_names = []
|
||||||
if __debug__:
|
if __debug__:
|
||||||
dynopt_names = []
|
dynopt_names = []
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
"""SymLinkOption link to an other option
|
"""SymLinkOption link to an other option
|
||||||
"""
|
"""
|
||||||
from typing import Any
|
from typing import Any, Optional, Dict
|
||||||
from .baseoption import BaseOption, valid_name
|
from .baseoption import BaseOption, valid_name
|
||||||
from ..error import ConfigError
|
from ..error import ConfigError
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
|
@ -41,55 +41,46 @@ class SymLinkOption(BaseOption):
|
||||||
if not isinstance(opt, BaseOption) or \
|
if not isinstance(opt, BaseOption) or \
|
||||||
opt.impl_is_optiondescription() or \
|
opt.impl_is_optiondescription() or \
|
||||||
opt.impl_is_symlinkoption():
|
opt.impl_is_symlinkoption():
|
||||||
raise ValueError(_('malformed symlinkoption must be an option for symlink {0}'
|
raise ValueError(_(f'malformed symlink second parameters must be an option for "{name}", not {opt}'))
|
||||||
'').format(name))
|
self._name = name
|
||||||
_setattr = object.__setattr__
|
self._opt = opt
|
||||||
_setattr(self, '_name', name)
|
|
||||||
_setattr(self, '_opt', opt)
|
|
||||||
opt._add_dependency(self)
|
opt._add_dependency(self)
|
||||||
|
|
||||||
def __getattr__(self,
|
def __getattr__(self,
|
||||||
name: str,
|
name: str,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
|
if name == '_subdyns':
|
||||||
|
return None
|
||||||
if name == '_path':
|
if name == '_path':
|
||||||
raise AttributeError()
|
raise AttributeError()
|
||||||
return getattr(self._opt, name)
|
return getattr(self._opt, name)
|
||||||
|
|
||||||
def _setsubdyn(self,
|
|
||||||
subdyn,
|
|
||||||
) -> None:
|
|
||||||
raise ConfigError(_('cannot set symlinkoption in a '
|
|
||||||
'dynoptiondescription'))
|
|
||||||
|
|
||||||
def impl_has_dependency(self,
|
|
||||||
self_is_dep: bool=True,
|
|
||||||
) -> bool:
|
|
||||||
"""If self_is_dep is True, it has dependency (self._opt), so return True
|
|
||||||
if self_is_dep is False, cannot has validation or callback, so return False
|
|
||||||
"""
|
|
||||||
return self_is_dep
|
|
||||||
|
|
||||||
def impl_is_symlinkoption(self) -> bool:
|
def impl_is_symlinkoption(self) -> bool:
|
||||||
"""it's a symlinkoption
|
"""it's a symlinkoption
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def impl_is_leader(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def impl_is_follower(self) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
def impl_getopt(self) -> BaseOption:
|
def impl_getopt(self) -> BaseOption:
|
||||||
"""get to linked option
|
"""get to linked option
|
||||||
"""
|
"""
|
||||||
return self._opt
|
return self._opt
|
||||||
|
|
||||||
def issubdyn(self) -> bool:
|
|
||||||
"""it's not a sub dyn option
|
|
||||||
"""
|
|
||||||
return False
|
|
||||||
|
|
||||||
def impl_is_multi(self) -> bool:
|
def impl_is_multi(self) -> bool:
|
||||||
"""is it a multi?
|
"""is it a multi?
|
||||||
"""
|
"""
|
||||||
if self._opt.issubdyn():
|
if self._opt.impl_is_multi():
|
||||||
return True
|
return True
|
||||||
return self._opt.impl_is_multi()
|
if self._opt.issubdyn() or self.issubdyn():
|
||||||
|
if self.issubdyn() != self._opt.issubdyn():
|
||||||
|
return self._opt.issubdyn()
|
||||||
|
return self._opt.issubdyn() in self.get_sub_dyns()
|
||||||
|
return False
|
||||||
|
|
||||||
def impl_is_submulti(self) -> bool:
|
def impl_is_submulti(self) -> bool:
|
||||||
"""is it a submulti?
|
"""is it a submulti?
|
||||||
|
|
|
@ -1,351 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (C) 2017-2024 Team tiramisu (see AUTHORS for all contributors)
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published by the
|
|
||||||
# Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
# option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# 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/>.
|
|
||||||
#
|
|
||||||
# The original `Config` design model is unproudly borrowed from
|
|
||||||
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
|
|
||||||
# the whole pypy projet is under MIT licence
|
|
||||||
# ____________________________________________________________
|
|
||||||
"""SynDynOption internal option, it's an instanciate synoption
|
|
||||||
"""
|
|
||||||
import re
|
|
||||||
from typing import Optional, Iterator, Any, List, Tuple
|
|
||||||
|
|
||||||
from .baseoption import BaseOption
|
|
||||||
from ..i18n import _
|
|
||||||
from ..setting import ConfigBag, undefined
|
|
||||||
|
|
||||||
|
|
||||||
NAME_REGEXP = re.compile(r'^[a-zA-Z\d\-_]*$')
|
|
||||||
|
|
||||||
|
|
||||||
class CommonDyn:
|
|
||||||
def get_path(self,
|
|
||||||
config_bag,
|
|
||||||
):
|
|
||||||
if config_bag is undefined or \
|
|
||||||
config_bag.context.get_description() == self:
|
|
||||||
return ''
|
|
||||||
return self.impl_getpath()
|
|
||||||
|
|
||||||
def get_suffixes(self,
|
|
||||||
parent: 'SubConfig',
|
|
||||||
) -> List[str]:
|
|
||||||
"""get dynamic suffixes
|
|
||||||
"""
|
|
||||||
subconfig = parent.get_child(self,
|
|
||||||
None,
|
|
||||||
False,
|
|
||||||
properties=None,
|
|
||||||
)
|
|
||||||
values = self._suffixes.execute(subconfig)
|
|
||||||
if values is None:
|
|
||||||
values = []
|
|
||||||
values_ = []
|
|
||||||
if __debug__:
|
|
||||||
if not isinstance(values, list):
|
|
||||||
raise ValueError(_('DynOptionDescription suffixes for '
|
|
||||||
f'option "{self.impl_get_display_name()}", is not '
|
|
||||||
f'a list ({values})'))
|
|
||||||
for val in values:
|
|
||||||
cval = self.convert_suffix_to_path(val)
|
|
||||||
if not isinstance(cval, str) or re.match(NAME_REGEXP, cval) is None:
|
|
||||||
if __debug__ and cval is not None:
|
|
||||||
raise ValueError(_('invalid suffix "{}" for option "{}"'
|
|
||||||
'').format(cval,
|
|
||||||
self.impl_get_display_name()))
|
|
||||||
else:
|
|
||||||
values_.append(val)
|
|
||||||
if __debug__ and len(values_) > len(set(values_)):
|
|
||||||
raise ValueError(_(f'DynOptionDescription "{self._name}" suffixes return a list with '
|
|
||||||
f'same values "{values_}"'''))
|
|
||||||
return values_
|
|
||||||
|
|
||||||
def split_path(self,
|
|
||||||
option,
|
|
||||||
*,
|
|
||||||
dynoption=None,
|
|
||||||
) -> Tuple[str, str]:
|
|
||||||
"""self.impl_getpath() is something like root.xxx.dynoption_path
|
|
||||||
option.impl_getpath() is something like root.xxx.dynoption_path.sub.path
|
|
||||||
must return ('root.xxx.', '.sub')
|
|
||||||
"""
|
|
||||||
if dynoption is None:
|
|
||||||
self_path = self.impl_getpath()
|
|
||||||
else:
|
|
||||||
self_path = dynoption.impl_getpath()
|
|
||||||
root_path = self_path.rsplit('.', 1)[0] if '.' in self_path else None
|
|
||||||
#
|
|
||||||
if self.option_is_self(option):
|
|
||||||
sub_path = ''
|
|
||||||
else:
|
|
||||||
option_path = option.impl_getpath()
|
|
||||||
if root_path:
|
|
||||||
if isinstance(option, SynDynLeadership):
|
|
||||||
count_root_path = option_path.count('.') - root_path.count('.')
|
|
||||||
root_path = option_path.rsplit('.', count_root_path)[0]
|
|
||||||
root_path += '.'
|
|
||||||
self_number_child = self_path.count('.') + 1
|
|
||||||
option_sub_path = option_path.split('.', self_number_child)[-1]
|
|
||||||
sub_path = '.' + option_sub_path.rsplit('.', 1)[0] if '.' in option_sub_path else ''
|
|
||||||
return root_path, sub_path
|
|
||||||
|
|
||||||
|
|
||||||
class Syn:
|
|
||||||
__slots__ = ('rootpath',
|
|
||||||
'opt',
|
|
||||||
'_current_suffixes',
|
|
||||||
'__weakref__')
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
opt: BaseOption,
|
|
||||||
rootpath: str,
|
|
||||||
suffixes: list,
|
|
||||||
) -> None:
|
|
||||||
self.opt = opt
|
|
||||||
self.rootpath = rootpath
|
|
||||||
self._current_suffixes = suffixes
|
|
||||||
|
|
||||||
def __getattr__(self,
|
|
||||||
name: str,
|
|
||||||
) -> Any:
|
|
||||||
# if not in SynDynOptionDescription, get value in self.opt
|
|
||||||
return getattr(self.opt,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
|
|
||||||
def impl_get_display_name(self) -> str:
|
|
||||||
return self.opt.impl_get_display_name(self)
|
|
||||||
|
|
||||||
def get_current_suffixes(self) -> str:
|
|
||||||
"""get suffixes
|
|
||||||
"""
|
|
||||||
return self.current__suffixes
|
|
||||||
|
|
||||||
def impl_is_dynsymlinkoption(self) -> bool:
|
|
||||||
"""it's a dynsymlinkoption
|
|
||||||
"""
|
|
||||||
return True
|
|
||||||
|
|
||||||
def impl_getpath(self) -> str:
|
|
||||||
"""get path
|
|
||||||
"""
|
|
||||||
path = self.impl_getname()
|
|
||||||
if self.rootpath:
|
|
||||||
path = f'{self.rootpath}.{path}'
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
class SynDescr(Syn):
|
|
||||||
__slots__ = ('opt',
|
|
||||||
'rootpath',
|
|
||||||
'_current_suffixes',
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_child(self,
|
|
||||||
name: str,
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
*,
|
|
||||||
allow_dynoption: bool=False,
|
|
||||||
):
|
|
||||||
"""get children
|
|
||||||
"""
|
|
||||||
# if not dyn
|
|
||||||
option = self.get_child_not_dynamic(name,
|
|
||||||
allow_dynoption,
|
|
||||||
)
|
|
||||||
if option:
|
|
||||||
if allow_dynoption and option.impl_is_dynoptiondescription():
|
|
||||||
return option
|
|
||||||
return option.to_dynoption(self.impl_getpath(),
|
|
||||||
self._current_suffixes,
|
|
||||||
)
|
|
||||||
for child in self.opt._children[1]: # pylint: disable=no-member
|
|
||||||
if not child.impl_is_dynoptiondescription():
|
|
||||||
continue
|
|
||||||
for suffix in child.get_suffixes(config_bag):
|
|
||||||
if name != child.impl_getname(suffix):
|
|
||||||
continue
|
|
||||||
return child.to_dynoption(self.impl_getpath(),
|
|
||||||
self._current_suffixes + [suffix],
|
|
||||||
)
|
|
||||||
raise AttributeError(_(f'unknown option "{name}" '
|
|
||||||
f'in optiondescription "{self.impl_get_display_name()}"'
|
|
||||||
))
|
|
||||||
|
|
||||||
def get_children(self,
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
):
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
"""get children
|
|
||||||
"""
|
|
||||||
for child in self.opt._children[1]:
|
|
||||||
if child.impl_is_dynoptiondescription():
|
|
||||||
dynchild = self.get_child(child.impl_getname(),
|
|
||||||
config_bag,
|
|
||||||
allow_dynoption=True,
|
|
||||||
)
|
|
||||||
for d in dynchild.get_sub_children(dynchild,
|
|
||||||
config_bag,
|
|
||||||
):
|
|
||||||
yield d.option
|
|
||||||
# yield from dynchild.get_sub_children(dynchild,
|
|
||||||
# config_bag,
|
|
||||||
# )
|
|
||||||
#for suffix in dynchild.get_suffixes(config_bag):
|
|
||||||
# yield child.to_dynoption(self.impl_getpath(),
|
|
||||||
# self._suffixes + [suffix],
|
|
||||||
# )
|
|
||||||
else:
|
|
||||||
yield child.to_dynoption(self.impl_getpath(),
|
|
||||||
self._current_suffixes,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_children_recursively(self,
|
|
||||||
bytype: Optional[BaseOption],
|
|
||||||
byname: Optional[str],
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
self_opt: BaseOption=None,
|
|
||||||
) -> BaseOption:
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
"""get children recursively
|
|
||||||
"""
|
|
||||||
for option in self.opt.get_children_recursively(bytype,
|
|
||||||
byname,
|
|
||||||
config_bag,
|
|
||||||
self,
|
|
||||||
):
|
|
||||||
yield option
|
|
||||||
|
|
||||||
def get_child_not_dynamic(self,
|
|
||||||
name,
|
|
||||||
allow_dynoption,
|
|
||||||
):
|
|
||||||
children = self.opt._children
|
|
||||||
if name in children[0]: # pylint: disable=no-member
|
|
||||||
option = children[1][children[0].index(name)] # pylint: disable=no-member
|
|
||||||
if option.impl_is_dynoptiondescription() and not allow_dynoption:
|
|
||||||
raise AttributeError(_(f'unknown option "{name}" '
|
|
||||||
"in root optiondescription (it's a dynamic option)"
|
|
||||||
))
|
|
||||||
return SubDynOptionDescription(option,
|
|
||||||
self.impl_getpath(),
|
|
||||||
self._current_suffixes,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class SynDynOption(Syn):
|
|
||||||
"""SynDynOption is an Option include un DynOptionDescription with specified prefix
|
|
||||||
"""
|
|
||||||
__slots__ = ()
|
|
||||||
|
|
||||||
def impl_get_leadership(self): # pylint: disable=inconsistent-return-statements
|
|
||||||
"""is it a leadership?
|
|
||||||
"""
|
|
||||||
leadership = self.opt.impl_get_leadership()
|
|
||||||
if leadership:
|
|
||||||
rootpath = self.rootpath.rsplit('.', 1)[0]
|
|
||||||
return leadership.to_dynoption(rootpath,
|
|
||||||
self._current_suffixes,
|
|
||||||
)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#class SubDynOptionDescription(SynDescr, CommonDyn):
|
|
||||||
# def option_is_self(self,
|
|
||||||
# option,
|
|
||||||
# ) -> bool:
|
|
||||||
# return self.opt.option_is_self(option.opt)
|
|
||||||
#
|
|
||||||
# def get_sub_children(self,
|
|
||||||
# option,
|
|
||||||
# config_bag,
|
|
||||||
# *,
|
|
||||||
# index=None,
|
|
||||||
# properties=undefined,
|
|
||||||
# ):
|
|
||||||
# root_path, sub_path = self.split_path(option)
|
|
||||||
# for suffix in self.get_suffixes(config_bag):
|
|
||||||
# if self.option_is_self(option):
|
|
||||||
# parent_path = root_path
|
|
||||||
# elif root_path:
|
|
||||||
# parent_path = root_path + self.impl_getname(suffix) + sub_path
|
|
||||||
# else:
|
|
||||||
# parent_path = self.impl_getname(suffix) + sub_path
|
|
||||||
# yield OptionBag(option.to_dynoption(parent_path,
|
|
||||||
# [suffix],
|
|
||||||
# ),
|
|
||||||
# index,
|
|
||||||
# config_bag,
|
|
||||||
# properties=properties,
|
|
||||||
# ori_option=option
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#class SynDynOptionDescription(SynDescr):
|
|
||||||
# """SynDynOptionDescription internal option, it's an instanciate synoptiondescription
|
|
||||||
# """
|
|
||||||
# def impl_getname(self) -> str:
|
|
||||||
# """get name
|
|
||||||
# """
|
|
||||||
# if self.opt.impl_is_dynoptiondescription():
|
|
||||||
# return self.opt.impl_getname(self._current_suffixes[-1])
|
|
||||||
# return self.opt.impl_getname()
|
|
||||||
#
|
|
||||||
# def getsubdyn(self):
|
|
||||||
# return self.opt
|
|
||||||
#
|
|
||||||
#
|
|
||||||
#class SynDynLeadership(SynDynOptionDescription):
|
|
||||||
# """SynDynLeadership internal option, it's an instanciate synoptiondescription
|
|
||||||
# """
|
|
||||||
# def get_leader(self) -> SynDynOption:
|
|
||||||
# """get the leader
|
|
||||||
# """
|
|
||||||
# return self.opt.get_leader().to_dynoption(self.impl_getpath(),
|
|
||||||
# self._current_suffixes,
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# def get_followers(self) -> Iterator[SynDynOption]:
|
|
||||||
# """get followers
|
|
||||||
# """
|
|
||||||
# subpath = self.impl_getpath()
|
|
||||||
# for follower in self.opt.get_followers():
|
|
||||||
# yield follower.to_dynoption(subpath,
|
|
||||||
# self._current_suffixes,
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# def pop(self,
|
|
||||||
# *args,
|
|
||||||
# **kwargs,
|
|
||||||
# ) -> None:
|
|
||||||
# """pop value for a follower
|
|
||||||
# """
|
|
||||||
# self.opt.pop(*args,
|
|
||||||
# followers=self.get_followers(),
|
|
||||||
# **kwargs,
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# def follower_force_store_value(self,
|
|
||||||
# value,
|
|
||||||
# config_bag,
|
|
||||||
# owner,
|
|
||||||
# ) -> None:
|
|
||||||
# """force store value for a follower
|
|
||||||
# """
|
|
||||||
# self.opt.follower_force_store_value(value,
|
|
||||||
# config_bag,
|
|
||||||
# owner,
|
|
||||||
# dyn=self,
|
|
||||||
# )
|
|
|
@ -1,235 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright (C) 2017-2023 Team tiramisu (see AUTHORS for all contributors)
|
|
||||||
#
|
|
||||||
# This program is free software: you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU Lesser General Public License as published by the
|
|
||||||
# Free Software Foundation, either version 3 of the License, or (at your
|
|
||||||
# option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
||||||
# details.
|
|
||||||
#
|
|
||||||
# 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/>.
|
|
||||||
#
|
|
||||||
# The original `Config` design model is unproudly borrowed from
|
|
||||||
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
|
|
||||||
# the whole pypy projet is under MIT licence
|
|
||||||
# ____________________________________________________________
|
|
||||||
"""SynDynOptionDescription and SynDynLeadership internal option
|
|
||||||
it's an instanciate synoptiondescription
|
|
||||||
"""
|
|
||||||
from typing import Optional, Iterator, Any, List
|
|
||||||
|
|
||||||
|
|
||||||
from ..i18n import _
|
|
||||||
from ..setting import ConfigBag, undefined
|
|
||||||
from .baseoption import BaseOption
|
|
||||||
from .syndynoption import SynDynOption
|
|
||||||
|
|
||||||
|
|
||||||
class Syn:
|
|
||||||
__slots__ = ('opt',
|
|
||||||
'rootpath',
|
|
||||||
'_suffixes',
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
opt: BaseOption,
|
|
||||||
rootpath: str,
|
|
||||||
suffixes: list,
|
|
||||||
) -> None:
|
|
||||||
self.opt = opt
|
|
||||||
self.rootpath = rootpath
|
|
||||||
self._suffixes = suffixes
|
|
||||||
|
|
||||||
def impl_get_display_name(self) -> str:
|
|
||||||
return self.opt.impl_get_display_name(self)
|
|
||||||
|
|
||||||
def get_child(self,
|
|
||||||
name: str,
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
*,
|
|
||||||
allow_dynoption: bool=False,
|
|
||||||
):
|
|
||||||
"""get children
|
|
||||||
"""
|
|
||||||
# if not dyn
|
|
||||||
option = self.opt.get_child_not_dynamic(name,
|
|
||||||
allow_dynoption,
|
|
||||||
)
|
|
||||||
if option:
|
|
||||||
if allow_dynoption and option.impl_is_dynoptiondescription():
|
|
||||||
return option
|
|
||||||
return option.to_dynoption(self.impl_getpath(),
|
|
||||||
self._suffixes,
|
|
||||||
)
|
|
||||||
for child in self.opt._children[1]: # pylint: disable=no-member
|
|
||||||
if not child.impl_is_dynoptiondescription():
|
|
||||||
continue
|
|
||||||
for suffix in child.get_suffixes(config_bag,
|
|
||||||
dynoption=self,
|
|
||||||
):
|
|
||||||
if name != child.impl_getname(suffix):
|
|
||||||
continue
|
|
||||||
return child.to_dynoption(self.impl_getpath(),
|
|
||||||
self._suffixes + [suffix],
|
|
||||||
)
|
|
||||||
raise AttributeError(_(f'unknown option "{name}" '
|
|
||||||
f'in optiondescription "{self.impl_get_display_name()}"'
|
|
||||||
))
|
|
||||||
|
|
||||||
def get_children(self,
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
):
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
"""get children
|
|
||||||
"""
|
|
||||||
for child in self.opt._children[1]:
|
|
||||||
if child.impl_is_dynoptiondescription():
|
|
||||||
for suffix in child.get_suffixes(config_bag,
|
|
||||||
dynoption=self,
|
|
||||||
):
|
|
||||||
yield child.to_dynoption(self.impl_getpath(),
|
|
||||||
self._suffixes + [suffix],
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
yield child.to_dynoption(self.impl_getpath(),
|
|
||||||
self._suffixes,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_children_recursively(self,
|
|
||||||
bytype: Optional[BaseOption],
|
|
||||||
byname: Optional[str],
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
self_opt: BaseOption=None,
|
|
||||||
) -> BaseOption:
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
"""get children recursively
|
|
||||||
"""
|
|
||||||
for option in self.opt.get_children_recursively(bytype,
|
|
||||||
byname,
|
|
||||||
config_bag,
|
|
||||||
self,
|
|
||||||
):
|
|
||||||
yield option
|
|
||||||
|
|
||||||
def get_suffixes(self) -> str:
|
|
||||||
"""get suffixes
|
|
||||||
"""
|
|
||||||
return self._suffixes
|
|
||||||
|
|
||||||
def impl_is_dynsymlinkoption(self) -> bool:
|
|
||||||
"""it's a dynsymlinkoption
|
|
||||||
"""
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class SubDynOptionDescription(Syn):
|
|
||||||
|
|
||||||
def impl_getpath(self) -> str:
|
|
||||||
"""get path
|
|
||||||
"""
|
|
||||||
path = self.opt.impl_getname()
|
|
||||||
if self.rootpath:
|
|
||||||
path = f'{self.rootpath}.{path}'
|
|
||||||
return path
|
|
||||||
|
|
||||||
def getsubdyn(self):
|
|
||||||
return self.opt.getsubdyn()
|
|
||||||
|
|
||||||
def impl_is_optiondescription(self):
|
|
||||||
return True
|
|
||||||
|
|
||||||
def impl_is_symlinkoption(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def impl_is_leadership(self):
|
|
||||||
return False
|
|
||||||
|
|
||||||
def impl_is_dynoptiondescription(self) -> bool:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def impl_getproperties(self):
|
|
||||||
return self.opt.impl_getproperties()
|
|
||||||
|
|
||||||
|
|
||||||
class SynDynOptionDescription(Syn):
|
|
||||||
"""SynDynOptionDescription internal option, it's an instanciate synoptiondescription
|
|
||||||
"""
|
|
||||||
def __getattr__(self,
|
|
||||||
name: str,
|
|
||||||
) -> Any:
|
|
||||||
# if not in SynDynOptionDescription, get value in self.opt
|
|
||||||
return getattr(self.opt,
|
|
||||||
name,
|
|
||||||
)
|
|
||||||
|
|
||||||
def impl_getname(self) -> str:
|
|
||||||
"""get name
|
|
||||||
"""
|
|
||||||
if self.opt.impl_is_dynoptiondescription():
|
|
||||||
return self.opt.impl_getname(self._suffixes[-1])
|
|
||||||
return self.opt.impl_getname()
|
|
||||||
|
|
||||||
def impl_getpath(self) -> str:
|
|
||||||
"""get path
|
|
||||||
"""
|
|
||||||
path = self.impl_getname()
|
|
||||||
if self.rootpath:
|
|
||||||
path = f'{self.rootpath}.{path}'
|
|
||||||
return path
|
|
||||||
|
|
||||||
def getsubdyn(self):
|
|
||||||
return self.opt
|
|
||||||
|
|
||||||
|
|
||||||
class SynDynLeadership(SynDynOptionDescription):
|
|
||||||
"""SynDynLeadership internal option, it's an instanciate synoptiondescription
|
|
||||||
"""
|
|
||||||
def get_leader(self) -> SynDynOption:
|
|
||||||
"""get the leader
|
|
||||||
"""
|
|
||||||
return self.opt.get_leader().to_dynoption(self.impl_getpath(),
|
|
||||||
self._suffixes,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_followers(self) -> Iterator[SynDynOption]:
|
|
||||||
"""get followers
|
|
||||||
"""
|
|
||||||
subpath = self.impl_getpath()
|
|
||||||
for follower in self.opt.get_followers():
|
|
||||||
yield follower.to_dynoption(subpath,
|
|
||||||
self._suffixes,
|
|
||||||
)
|
|
||||||
|
|
||||||
def pop(self,
|
|
||||||
*args,
|
|
||||||
**kwargs,
|
|
||||||
) -> None:
|
|
||||||
"""pop value for a follower
|
|
||||||
"""
|
|
||||||
self.opt.pop(*args,
|
|
||||||
followers=self.get_followers(),
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
def follower_force_store_value(self,
|
|
||||||
value,
|
|
||||||
config_bag,
|
|
||||||
owner,
|
|
||||||
) -> None:
|
|
||||||
"""force store value for a follower
|
|
||||||
"""
|
|
||||||
self.opt.follower_force_store_value(value,
|
|
||||||
config_bag,
|
|
||||||
owner,
|
|
||||||
dyn=self,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_suffixes(self) -> str:
|
|
||||||
"""get suffix
|
|
||||||
"""
|
|
||||||
return self._suffixes
|
|
|
@ -17,7 +17,7 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
from typing import Union, Set
|
from typing import Union, Set
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from .error import PropertiesOptionError, ConstError, ConfigError, LeadershipError
|
from .error import PropertiesOptionError, ConstError, ConfigError, LeadershipError, display_list
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,63 +156,6 @@ class Undefined:
|
||||||
|
|
||||||
|
|
||||||
undefined = Undefined()
|
undefined = Undefined()
|
||||||
#
|
|
||||||
#
|
|
||||||
#class OptionBag:
|
|
||||||
# """Object to store information for an option
|
|
||||||
# """
|
|
||||||
# __slots__ = ('option', # current option
|
|
||||||
# 'path',
|
|
||||||
# 'index',
|
|
||||||
# 'config_bag',
|
|
||||||
# 'ori_option', # original option (for example useful for symlinkoption)
|
|
||||||
# 'properties', # properties of current option
|
|
||||||
# 'apply_requires', # apply requires or not for this option
|
|
||||||
# 'suffixes',
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# # pylint: disable=too-many-arguments
|
|
||||||
# def __init__(self,
|
|
||||||
# option,
|
|
||||||
# index,
|
|
||||||
# config_bag,
|
|
||||||
# *,
|
|
||||||
# path=None,
|
|
||||||
# properties=undefined,
|
|
||||||
# parent: 'SubConfig'=None,
|
|
||||||
# ori_option=None,
|
|
||||||
# apply_requires=True,
|
|
||||||
# suffixes=None
|
|
||||||
# ):
|
|
||||||
# self.index = index
|
|
||||||
# self.config_bag = config_bag
|
|
||||||
# self.option = option
|
|
||||||
# if ori_option is not None:
|
|
||||||
# self.ori_option = ori_option
|
|
||||||
# if config_bag is undefined:
|
|
||||||
# self.path = path
|
|
||||||
# elif option:
|
|
||||||
# if properties is not undefined:
|
|
||||||
# self.properties = properties
|
|
||||||
# self.suffixes = suffixes
|
|
||||||
#
|
|
||||||
# def __getattr__(self, key):
|
|
||||||
# if key == 'ori_option':
|
|
||||||
# return self.option
|
|
||||||
# if key == 'apply_requires':
|
|
||||||
# return True
|
|
||||||
# return None
|
|
||||||
#
|
|
||||||
# def copy(self):
|
|
||||||
# """copy OptionBag
|
|
||||||
# """
|
|
||||||
# option_bag = OptionBag(None,
|
|
||||||
# None,
|
|
||||||
# None,
|
|
||||||
# )
|
|
||||||
# for key in self.__slots__:
|
|
||||||
# setattr(option_bag, key, getattr(self, key))
|
|
||||||
# return option_bag
|
|
||||||
|
|
||||||
|
|
||||||
class ConfigBag:
|
class ConfigBag:
|
||||||
|
@ -390,7 +333,6 @@ class Settings:
|
||||||
'ro_remove',
|
'ro_remove',
|
||||||
'rw_append',
|
'rw_append',
|
||||||
'rw_remove',
|
'rw_remove',
|
||||||
'default_properties',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -401,9 +343,8 @@ class Settings:
|
||||||
:param storage: the storage type
|
:param storage: the storage type
|
||||||
"""
|
"""
|
||||||
# generic owner
|
# generic owner
|
||||||
self._properties = {}
|
self._properties = {None: {None: DEFAULT_PROPERTIES}}
|
||||||
self._permissives = {}
|
self._permissives = {}
|
||||||
self.default_properties = DEFAULT_PROPERTIES
|
|
||||||
self.ro_append = RO_APPEND
|
self.ro_append = RO_APPEND
|
||||||
self.ro_remove = RO_REMOVE
|
self.ro_remove = RO_REMOVE
|
||||||
self.rw_append = RW_APPEND
|
self.rw_append = RW_APPEND
|
||||||
|
@ -412,35 +353,19 @@ class Settings:
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# get properties and permissive methods
|
# get properties and permissive methods
|
||||||
|
|
||||||
def get_context_properties(self,
|
def get_context_properties(self):
|
||||||
cache,
|
|
||||||
):
|
|
||||||
"""get context properties
|
"""get context properties
|
||||||
"""
|
"""
|
||||||
is_cached, props, _ = cache.getcache(None,
|
return self.get_personalize_properties()
|
||||||
'context_props',
|
|
||||||
expiration=False,
|
|
||||||
)
|
|
||||||
if not is_cached:
|
|
||||||
props = self.get_stored_properties(None,
|
|
||||||
None,
|
|
||||||
self.default_properties,
|
|
||||||
)
|
|
||||||
cache.setcache(None,
|
|
||||||
props,
|
|
||||||
type_='properties',
|
|
||||||
)
|
|
||||||
return props
|
|
||||||
|
|
||||||
def get_stored_properties(self,
|
def get_personalize_properties(self,
|
||||||
path: Union[None, str],
|
path: Union[None, str]=None,
|
||||||
index: Union[None, int],
|
index: Union[None, int]=None,
|
||||||
default_properties: Set[str],
|
) -> Set[str]:
|
||||||
) -> Set[str]:
|
|
||||||
"""Get the properties modified by user for a path or index
|
"""Get the properties modified by user for a path or index
|
||||||
"""
|
"""
|
||||||
if path not in self._properties or index not in self._properties[path]:
|
if path not in self._properties or index not in self._properties[path]:
|
||||||
return frozenset(default_properties)
|
return frozenset()
|
||||||
return self._properties[path][index]
|
return self._properties[path][index]
|
||||||
|
|
||||||
def getproperties(self,
|
def getproperties(self,
|
||||||
|
@ -467,18 +392,17 @@ class Settings:
|
||||||
if not is_cached:
|
if not is_cached:
|
||||||
props = set()
|
props = set()
|
||||||
# if index, get option's properties (without index) too
|
# if index, get option's properties (without index) too
|
||||||
p_props = self.get_stored_properties(subconfig.path,
|
p_props = [option.impl_getproperties()]
|
||||||
None,
|
props_config = self.get_personalize_properties(subconfig.path)
|
||||||
option.impl_getproperties(),
|
if props_config:
|
||||||
)
|
p_props.append(props_config)
|
||||||
if subconfig.index is not None:
|
if subconfig.index is not None:
|
||||||
p_props = chain(p_props,
|
props_config = self.get_personalize_properties(subconfig.path,
|
||||||
self.get_stored_properties(subconfig.path,
|
subconfig.index,
|
||||||
subconfig.index,
|
)
|
||||||
option.impl_getproperties(),
|
if props_config:
|
||||||
)
|
p_props.append(props_config)
|
||||||
)
|
for prop in chain(*p_props):
|
||||||
for prop in p_props:
|
|
||||||
if uncalculated or isinstance(prop, str):
|
if uncalculated or isinstance(prop, str):
|
||||||
if not help_property:
|
if not help_property:
|
||||||
props.add(prop)
|
props.add(prop)
|
||||||
|
@ -520,6 +444,12 @@ class Settings:
|
||||||
props,
|
props,
|
||||||
type_='properties',
|
type_='properties',
|
||||||
)
|
)
|
||||||
|
if subconfig.parent and subconfig.parent.raises_properties:
|
||||||
|
parent_properties = subconfig.parent.raises_properties
|
||||||
|
parent_properties -= self.getpermissives(subconfig)
|
||||||
|
if help_property:
|
||||||
|
parent_properties = {(prop, prop) for prop in parent_properties}
|
||||||
|
return props | parent_properties
|
||||||
return props
|
return props
|
||||||
|
|
||||||
def get_context_permissives(self):
|
def get_context_permissives(self):
|
||||||
|
@ -566,7 +496,7 @@ class Settings:
|
||||||
def set_context_properties(self, properties, context):
|
def set_context_properties(self, properties, context):
|
||||||
"""set context properties
|
"""set context properties
|
||||||
"""
|
"""
|
||||||
self._properties.setdefault(None, {})[None] = properties
|
self._properties[None][None] = properties
|
||||||
context.reset_cache(None)
|
context.reset_cache(None)
|
||||||
|
|
||||||
def setproperties(self,
|
def setproperties(self,
|
||||||
|
@ -580,8 +510,8 @@ class Settings:
|
||||||
if not opt.impl_is_optiondescription() and opt.impl_is_leader():
|
if not opt.impl_is_optiondescription() and opt.impl_is_leader():
|
||||||
not_allowed_properties = properties - ALLOWED_LEADER_PROPERTIES
|
not_allowed_properties = properties - ALLOWED_LEADER_PROPERTIES
|
||||||
if not_allowed_properties:
|
if not_allowed_properties:
|
||||||
raise LeadershipError(_('leader cannot have "{list(not_allowed_properties)}" '
|
raise LeadershipError(_(f'leader cannot have "{display_list(not_allowed_properties)}" '
|
||||||
'property'))
|
'property'))
|
||||||
if ('force_default_on_freeze' in properties or \
|
if ('force_default_on_freeze' in properties or \
|
||||||
'force_metaconfig_on_freeze' in properties) and 'frozen' not in properties:
|
'force_metaconfig_on_freeze' in properties) and 'frozen' not in properties:
|
||||||
raise LeadershipError(_('a leader ({opt.impl_get_display_name()}) cannot have '
|
raise LeadershipError(_('a leader ({opt.impl_get_display_name()}) cannot have '
|
||||||
|
@ -682,9 +612,11 @@ class Settings:
|
||||||
# validate properties
|
# validate properties
|
||||||
def calc_raises_properties(self,
|
def calc_raises_properties(self,
|
||||||
subconfig,
|
subconfig,
|
||||||
|
*,
|
||||||
apply_requires=True,
|
apply_requires=True,
|
||||||
uncalculated=False,
|
uncalculated=False,
|
||||||
transitive_raise=True,
|
transitive_raise=True,
|
||||||
|
not_unrestraint=False,
|
||||||
):
|
):
|
||||||
"""raise if needed
|
"""raise if needed
|
||||||
"""
|
"""
|
||||||
|
@ -698,16 +630,23 @@ class Settings:
|
||||||
)
|
)
|
||||||
return self._calc_raises_properties(subconfig,
|
return self._calc_raises_properties(subconfig,
|
||||||
option_properties,
|
option_properties,
|
||||||
|
not_unrestraint,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _calc_raises_properties(self,
|
def _calc_raises_properties(self,
|
||||||
subconfig,
|
subconfig,
|
||||||
option_properties,
|
option_properties,
|
||||||
|
not_unrestraint,
|
||||||
):
|
):
|
||||||
raises_properties = subconfig.config_bag.properties - SPECIAL_PROPERTIES
|
config_bag =subconfig.config_bag
|
||||||
|
if not_unrestraint and config_bag.is_unrestraint:
|
||||||
|
context_properties = config_bag.true_properties
|
||||||
|
else:
|
||||||
|
context_properties = config_bag.properties
|
||||||
|
raises_properties = context_properties - SPECIAL_PROPERTIES
|
||||||
# remove global permissive properties
|
# remove global permissive properties
|
||||||
if raises_properties and 'permissive' in raises_properties:
|
if raises_properties and 'permissive' in raises_properties:
|
||||||
raises_properties -= subconfig.config_bag.permissives
|
raises_properties -= config_bag.permissives
|
||||||
properties = option_properties & raises_properties
|
properties = option_properties & raises_properties
|
||||||
# at this point it should not remain any property for the option
|
# at this point it should not remain any property for the option
|
||||||
return properties
|
return properties
|
||||||
|
@ -736,6 +675,7 @@ class Settings:
|
||||||
calc_properties = []
|
calc_properties = []
|
||||||
for property_ in self._calc_raises_properties(subconfig,
|
for property_ in self._calc_raises_properties(subconfig,
|
||||||
set(help_properties.keys()),
|
set(help_properties.keys()),
|
||||||
|
False,
|
||||||
):
|
):
|
||||||
calc_properties.append(help_properties[property_])
|
calc_properties.append(help_properties[property_])
|
||||||
calc_properties = frozenset(calc_properties)
|
calc_properties = frozenset(calc_properties)
|
||||||
|
@ -799,10 +739,7 @@ class Settings:
|
||||||
append,
|
append,
|
||||||
config_bag,
|
config_bag,
|
||||||
):
|
):
|
||||||
props = self.get_stored_properties(None,
|
props = self.get_personalize_properties()
|
||||||
None,
|
|
||||||
self.default_properties,
|
|
||||||
)
|
|
||||||
modified = False
|
modified = False
|
||||||
if remove & props:
|
if remove & props:
|
||||||
props = props - remove
|
props = props - remove
|
||||||
|
|
|
@ -6,7 +6,7 @@ from copy import copy
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from .error import ValueWarning, ValueErrorWarning, PropertiesOptionError, ConfigError
|
from .error import ValueWarning, ValueErrorWarning, PropertiesOptionError, ConfigError
|
||||||
from .setting import undefined
|
from .setting import undefined
|
||||||
from .option.syndynoption import SynDynOption
|
#from .option.syndynoption import SynDynOption
|
||||||
from . import RegexpOption, ChoiceOption, ParamOption
|
from . import RegexpOption, ChoiceOption, ParamOption
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
@ -233,8 +233,8 @@ class Requires(object):
|
||||||
def add(self, path, childapi, form):
|
def add(self, path, childapi, form):
|
||||||
#collect id of all options
|
#collect id of all options
|
||||||
child = childapi.get()
|
child = childapi.get()
|
||||||
if isinstance(child, SynDynOption):
|
# if isinstance(child, SynDynOption):
|
||||||
child = child.opt
|
# child = child.opt
|
||||||
self.options[child] = path
|
self.options[child] = path
|
||||||
current_action = None
|
current_action = None
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
from typing import Union, Optional, List, Any
|
from typing import Union, Optional, List, Any
|
||||||
from .error import ConfigError
|
from .error import ConfigError
|
||||||
from .setting import owners, undefined, forbidden_owners
|
from .setting import owners, undefined, forbidden_owners
|
||||||
from .autolib import Calculation
|
from .autolib import Calculation, get_calculated_value
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,9 +106,9 @@ class Values:
|
||||||
# the value is a default value
|
# the value is a default value
|
||||||
# get it
|
# get it
|
||||||
value = self.get_default_value(subconfig)
|
value = self.get_default_value(subconfig)
|
||||||
value, has_calculation = self.get_calculated_value(subconfig,
|
value, has_calculation = get_calculated_value(subconfig,
|
||||||
value,
|
value,
|
||||||
)
|
)
|
||||||
return value, has_calculation
|
return value, has_calculation
|
||||||
|
|
||||||
def get_default_value(self,
|
def get_default_value(self,
|
||||||
|
@ -125,9 +125,9 @@ class Values:
|
||||||
return msubconfig.config_bag.context.get_values().get_cached_value(msubconfig)
|
return msubconfig.config_bag.context.get_values().get_cached_value(msubconfig)
|
||||||
|
|
||||||
# now try to get calculated value:
|
# now try to get calculated value:
|
||||||
value, _has_calculation = self.get_calculated_value(subconfig,
|
value, _has_calculation = get_calculated_value(subconfig,
|
||||||
subconfig.option.impl_getdefault(),
|
subconfig.option.impl_getdefault(),
|
||||||
)
|
)
|
||||||
if subconfig.index is not None and isinstance(value, (list, tuple)) \
|
if subconfig.index is not None and isinstance(value, (list, tuple)) \
|
||||||
and (not subconfig.option.impl_is_submulti() or \
|
and (not subconfig.option.impl_is_submulti() or \
|
||||||
not value or isinstance(value[0], list)):
|
not value or isinstance(value[0], list)):
|
||||||
|
@ -139,38 +139,14 @@ class Values:
|
||||||
else:
|
else:
|
||||||
# no value for this index, retrieve default multi value
|
# no value for this index, retrieve default multi value
|
||||||
# default_multi is already a list for submulti
|
# default_multi is already a list for submulti
|
||||||
value, _has_calculation = self.get_calculated_value(subconfig,
|
value, _has_calculation = get_calculated_value(subconfig,
|
||||||
subconfig.option.impl_getdefault_multi(),
|
subconfig.option.impl_getdefault_multi(),
|
||||||
)
|
)
|
||||||
|
self.reset_cache_after_calculation(subconfig,
|
||||||
|
value,
|
||||||
|
)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def get_calculated_value(self,
|
|
||||||
subconfig: "SubConfig",
|
|
||||||
value: Any,
|
|
||||||
*,
|
|
||||||
reset_cache: bool=True,
|
|
||||||
) -> Any:
|
|
||||||
"""value could be a calculation, in this case do calculation
|
|
||||||
"""
|
|
||||||
has_calculation = False
|
|
||||||
if isinstance(value, Calculation):
|
|
||||||
value = value.execute(subconfig)
|
|
||||||
has_calculation = True
|
|
||||||
elif isinstance(value, list):
|
|
||||||
# if value is a list, do subcalculation
|
|
||||||
for idx, val in enumerate(value):
|
|
||||||
value[idx], _has_calculation = self.get_calculated_value(subconfig,
|
|
||||||
val,
|
|
||||||
reset_cache=False,
|
|
||||||
)
|
|
||||||
if _has_calculation:
|
|
||||||
has_calculation = True
|
|
||||||
if reset_cache:
|
|
||||||
self.reset_cache_after_calculation(subconfig,
|
|
||||||
value,
|
|
||||||
)
|
|
||||||
return value, has_calculation
|
|
||||||
|
|
||||||
#______________________________________________________________________
|
#______________________________________________________________________
|
||||||
def check_force_to_metaconfig(self,
|
def check_force_to_metaconfig(self,
|
||||||
subconfig: "OptionBag",
|
subconfig: "OptionBag",
|
||||||
|
@ -210,7 +186,9 @@ class Values:
|
||||||
# calculated value is a new value, so reset cache
|
# calculated value is a new value, so reset cache
|
||||||
subconfig.config_bag.context.reset_cache(subconfig)
|
subconfig.config_bag.context.reset_cache(subconfig)
|
||||||
# and manage force_store_value
|
# and manage force_store_value
|
||||||
# self._set_force_value_suffix(subconfig)
|
self._set_force_value_suffix(subconfig,
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
|
||||||
def isempty(self,
|
def isempty(self,
|
||||||
subconfig: "SubConfig",
|
subconfig: "SubConfig",
|
||||||
|
@ -279,12 +257,14 @@ class Values:
|
||||||
elif 'validator' in setting_properties and has_calculation:
|
elif 'validator' in setting_properties and has_calculation:
|
||||||
cache = subconfig.config_bag.context.get_values_cache()
|
cache = subconfig.config_bag.context.get_values_cache()
|
||||||
cache.delcache(subconfig.path)
|
cache.delcache(subconfig.path)
|
||||||
# if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader():
|
if 'force_store_value' in setting_properties and subconfig.option.impl_is_leader():
|
||||||
# leader = option_bag.option.impl_get_leadership()
|
leader = subconfig.option.impl_get_leadership()
|
||||||
# leader.follower_force_store_value(value,
|
parent = subconfig.parent
|
||||||
# option_bag.config_bag,
|
parent._length = len(value)
|
||||||
# owners.forced,
|
leader.follower_force_store_value(value,
|
||||||
# )
|
parent,
|
||||||
|
owners.forced,
|
||||||
|
)
|
||||||
|
|
||||||
def setvalue_validation(self,
|
def setvalue_validation(self,
|
||||||
subconfig: "SubConfig",
|
subconfig: "SubConfig",
|
||||||
|
@ -296,10 +276,9 @@ class Values:
|
||||||
# First validate properties with this value
|
# First validate properties with this value
|
||||||
opt = subconfig.option
|
opt = subconfig.option
|
||||||
settings.validate_frozen(subconfig)
|
settings.validate_frozen(subconfig)
|
||||||
val, has_calculation = self.get_calculated_value(subconfig,
|
val, has_calculation = get_calculated_value(subconfig,
|
||||||
value,
|
value,
|
||||||
reset_cache=False,
|
)
|
||||||
)
|
|
||||||
settings.validate_mandatory(subconfig,
|
settings.validate_mandatory(subconfig,
|
||||||
val,
|
val,
|
||||||
)
|
)
|
||||||
|
@ -327,7 +306,9 @@ class Values:
|
||||||
value,
|
value,
|
||||||
owner,
|
owner,
|
||||||
)
|
)
|
||||||
# self._set_force_value_suffix(option_bag)
|
self._set_force_value_suffix(subconfig,
|
||||||
|
value,
|
||||||
|
)
|
||||||
|
|
||||||
def set_storage_value(self,
|
def set_storage_value(self,
|
||||||
path,
|
path,
|
||||||
|
@ -339,47 +320,44 @@ class Values:
|
||||||
"""
|
"""
|
||||||
self._values.setdefault(path, {})[index] = [value, owner]
|
self._values.setdefault(path, {})[index] = [value, owner]
|
||||||
|
|
||||||
# def _set_force_value_suffix(self,
|
def _set_force_value_suffix(self,
|
||||||
# option_bag: OptionBag,
|
subconfig: 'SubConfig',
|
||||||
# ) -> None:
|
suffix_values,
|
||||||
# """ force store value for an option for suffixes
|
) -> None:
|
||||||
# """
|
""" force store value for an option for suffixes
|
||||||
# # pylint: disable=too-many-locals
|
"""
|
||||||
# if 'force_store_value' not in option_bag.config_bag.properties:
|
# pylint: disable=too-many-locals
|
||||||
# return
|
if 'force_store_value' not in subconfig.config_bag.properties:
|
||||||
#
|
return
|
||||||
# for woption in option_bag.option._get_suffixes_dependencies(): # pylint: disable=protected-access
|
|
||||||
# # options from dependencies are weakref
|
config_bag = subconfig.config_bag
|
||||||
# option = woption()
|
context = config_bag.context
|
||||||
# force_store_options = []
|
for woption in subconfig.option._get_suffixes_dependencies(): # pylint: disable=protected-access
|
||||||
# for coption in option.get_children_recursively(None,
|
options = subconfig.get_common_child(woption(),
|
||||||
# None,
|
true_path=subconfig.path,
|
||||||
# option_bag.config_bag,
|
validate_properties=False,
|
||||||
# option_suffixes=[],
|
)
|
||||||
# ):
|
if not isinstance(options, list):
|
||||||
# if 'force_store_value' in coption.impl_getproperties():
|
options = [options]
|
||||||
# force_store_options.append(coption)
|
for option in options:
|
||||||
# if not force_store_options:
|
parent = option.parent
|
||||||
# continue
|
for suffix in suffix_values:
|
||||||
# for coption in force_store_options:
|
name = option.option.impl_getname(suffix)
|
||||||
# if coption.impl_is_follower():
|
opt_subconfig = parent.get_child(option.option,
|
||||||
# leader = coption.impl_get_leadership().get_leader()
|
None,
|
||||||
# loption_bag = OptionBag(leader,
|
False,
|
||||||
# None,
|
suffix=suffix,
|
||||||
# option_bag.config_bag,
|
name=name,
|
||||||
# properties=frozenset(),
|
)
|
||||||
# )
|
|
||||||
# indexes = range(len(self.get_value(loption_bag)[0]))
|
for walk_subconfig in context.walk(opt_subconfig,
|
||||||
# else:
|
no_value=True,
|
||||||
# indexes = [None]
|
validate_properties=False,
|
||||||
# for index in indexes:
|
):
|
||||||
# for coption_bag in option.get_sub_children(coption,
|
if 'force_store_value' not in walk_subconfig.properties:
|
||||||
# option_bag.config_bag,
|
continue
|
||||||
# index=index,
|
default_value = [self.get_value(walk_subconfig)[0], owners.forced]
|
||||||
# properties=frozenset(),
|
self._values.setdefault(walk_subconfig.path, {})[walk_subconfig.index] = default_value
|
||||||
# ):
|
|
||||||
# default_value = [self.get_value(coption_bag)[0], owners.forced]
|
|
||||||
# self._values.setdefault(coption_bag.path, {})[index] = default_value
|
|
||||||
|
|
||||||
def _get_modified_parent(self,
|
def _get_modified_parent(self,
|
||||||
subconfig: "SubConfig",
|
subconfig: "SubConfig",
|
||||||
|
@ -462,9 +440,9 @@ class Values:
|
||||||
was present
|
was present
|
||||||
:returns: a `setting.owners.Owner` object
|
:returns: a `setting.owners.Owner` object
|
||||||
"""
|
"""
|
||||||
context = subconfig.config_bag.context
|
# context = subconfig.config_bag.context
|
||||||
settings = context.get_settings()
|
# settings = context.get_settings()
|
||||||
settings.validate_properties(subconfig)
|
# settings.validate_properties(subconfig)
|
||||||
if 'frozen' in subconfig.properties and \
|
if 'frozen' in subconfig.properties and \
|
||||||
'force_default_on_freeze' in subconfig.properties:
|
'force_default_on_freeze' in subconfig.properties:
|
||||||
return owners.default
|
return owners.default
|
||||||
|
@ -509,7 +487,7 @@ class Values:
|
||||||
if not self.hasvalue(subconfig.path,
|
if not self.hasvalue(subconfig.path,
|
||||||
index=subconfig.index,
|
index=subconfig.index,
|
||||||
):
|
):
|
||||||
raise ConfigError(_(f'no value for {subconfig.path} cannot change owner to {owner}'))
|
raise ConfigError(_(f'"{subconfig.path}" is a default value, so we cannot change owner to "{owner}"'))
|
||||||
subconfig.config_bag.context.get_settings().validate_frozen(subconfig)
|
subconfig.config_bag.context.get_settings().validate_frozen(subconfig)
|
||||||
self._values[subconfig.path][subconfig.index][1] = owner
|
self._values[subconfig.path][subconfig.index][1] = owner
|
||||||
#______________________________________________________________________
|
#______________________________________________________________________
|
||||||
|
@ -517,59 +495,58 @@ class Values:
|
||||||
|
|
||||||
def reset(self,
|
def reset(self,
|
||||||
subconfig: "SubConfig",
|
subconfig: "SubConfig",
|
||||||
|
*,
|
||||||
|
validate: bool=True,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""reset value for an option
|
"""reset value for an option
|
||||||
"""
|
"""
|
||||||
config_bag = subconfig.config_bag
|
config_bag = subconfig.config_bag
|
||||||
context = config_bag.context
|
|
||||||
hasvalue = self.hasvalue(subconfig.path)
|
hasvalue = self.hasvalue(subconfig.path)
|
||||||
|
context = config_bag.context
|
||||||
setting_properties = config_bag.properties
|
setting_properties = config_bag.properties
|
||||||
if hasvalue and 'validator' in config_bag.properties:
|
if validate:
|
||||||
fake_context = context.gen_fake_context()
|
if hasvalue and 'validator' in setting_properties:
|
||||||
fake_config_bag = config_bag.copy()
|
fake_context = context.gen_fake_context()
|
||||||
fake_config_bag.remove_validation()
|
fake_config_bag = config_bag.copy()
|
||||||
fake_config_bag.context = fake_context
|
fake_config_bag.remove_validation()
|
||||||
fake_subconfig = fake_context.get_sub_config(fake_config_bag,
|
fake_config_bag.context = fake_context
|
||||||
subconfig.path,
|
fake_subconfig = fake_context.get_sub_config(fake_config_bag,
|
||||||
subconfig.index,
|
subconfig.path,
|
||||||
validate_properties=False,
|
subconfig.index,
|
||||||
follower_not_apply_requires=False,
|
validate_properties=False,
|
||||||
)
|
)
|
||||||
fake_values = fake_context.get_values()
|
fake_values = fake_context.get_values()
|
||||||
fake_values.reset(fake_subconfig)
|
fake_values.reset(fake_subconfig)
|
||||||
fake_subconfig.config_bag.properties = setting_properties
|
fake_subconfig.config_bag.properties = setting_properties
|
||||||
value = fake_values.get_default_value(fake_subconfig)
|
value = fake_values.get_default_value(fake_subconfig)
|
||||||
fake_values.setvalue_validation(fake_subconfig,
|
fake_values.setvalue_validation(fake_subconfig,
|
||||||
value,
|
value,
|
||||||
)
|
)
|
||||||
|
# if hasvalue:
|
||||||
opt = subconfig.option
|
opt = subconfig.option
|
||||||
if opt.impl_is_leader():
|
if opt.impl_is_leader():
|
||||||
opt.impl_get_leadership().reset(subconfig.parent)
|
opt.impl_get_leadership().reset(subconfig.parent)
|
||||||
if hasvalue:
|
if 'force_store_value' in setting_properties and \
|
||||||
if 'force_store_value' in subconfig.config_bag.properties and \
|
'force_store_value' in subconfig.properties:
|
||||||
'force_store_value' in subconfig.properties:
|
value = self.get_default_value(subconfig)
|
||||||
value = self.get_default_value(subconfig)
|
|
||||||
|
|
||||||
self._setvalue(subconfig,
|
self._setvalue(subconfig,
|
||||||
value,
|
value,
|
||||||
owners.forced,
|
owners.forced,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# for leader only
|
value = None
|
||||||
value = None
|
if subconfig.path in self._values:
|
||||||
if subconfig.path in self._values:
|
del self._values[subconfig.path]
|
||||||
del self._values[subconfig.path]
|
if 'force_store_value' in setting_properties and subconfig.option.impl_is_leader():
|
||||||
context.reset_cache(subconfig)
|
if value is None:
|
||||||
# if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader():
|
value = self.get_default_value(subconfig)
|
||||||
# if value is None:
|
leader = subconfig.option.impl_get_leadership()
|
||||||
# value = self.get_default_value(option_bag,
|
leader.follower_force_store_value(value,
|
||||||
# parent,
|
subconfig.parent,
|
||||||
# )
|
owners.forced,
|
||||||
# leader = option_bag.option.impl_get_leadership()
|
)
|
||||||
# leader.follower_force_store_value(value,
|
context.reset_cache(subconfig)
|
||||||
# option_bag.config_bag,
|
|
||||||
# owners.forced,
|
|
||||||
# )
|
|
||||||
#______________________________________________________________________
|
#______________________________________________________________________
|
||||||
# Follower
|
# Follower
|
||||||
|
|
||||||
|
@ -602,7 +579,6 @@ class Values:
|
||||||
subconfig.path,
|
subconfig.path,
|
||||||
subconfig.index,
|
subconfig.index,
|
||||||
validate_properties=False,
|
validate_properties=False,
|
||||||
follower_not_apply_requires=False,
|
|
||||||
)
|
)
|
||||||
fake_values = fake_context.get_values()
|
fake_values = fake_context.get_values()
|
||||||
fake_values.reset_follower(fake_subconfig)
|
fake_values.reset_follower(fake_subconfig)
|
||||||
|
@ -611,19 +587,18 @@ class Values:
|
||||||
fake_values.setvalue_validation(fake_subconfig,
|
fake_values.setvalue_validation(fake_subconfig,
|
||||||
value,
|
value,
|
||||||
)
|
)
|
||||||
# if 'force_store_value' in setting_properties and \
|
if 'force_store_value' in setting_properties and \
|
||||||
# 'force_store_value' in option_bag.properties:
|
'force_store_value' in subconfig.properties:
|
||||||
# value = self.get_default_value(option_bag,
|
value = self.get_default_value(subconfig,
|
||||||
# parent,
|
)
|
||||||
# )
|
|
||||||
#
|
self._setvalue(subconfig,
|
||||||
# self._setvalue(option_bag,
|
value,
|
||||||
# value,
|
owners.forced,
|
||||||
# owners.forced,
|
)
|
||||||
# )
|
else:
|
||||||
# else:
|
self.resetvalue_index(subconfig)
|
||||||
self.resetvalue_index(subconfig)
|
context.reset_cache(subconfig)
|
||||||
context.reset_cache(subconfig)
|
|
||||||
|
|
||||||
def resetvalue_index(self,
|
def resetvalue_index(self,
|
||||||
subconfig: "SubConfig",
|
subconfig: "SubConfig",
|
||||||
|
@ -688,14 +663,26 @@ class Values:
|
||||||
config_bag = subconfig.config_bag
|
config_bag = subconfig.config_bag
|
||||||
context = config_bag.context
|
context = config_bag.context
|
||||||
for key, options in subconfig.option.get_dependencies_information().items():
|
for key, options in subconfig.option.get_dependencies_information().items():
|
||||||
for option in options:
|
if key is None:
|
||||||
option_subconfig = context.get_sub_config(config_bag,
|
continue
|
||||||
option.impl_getpath(),
|
for woption in options:
|
||||||
None,
|
if woption is None:
|
||||||
validate_properties=False,
|
continue
|
||||||
follower_not_apply_requires=False,
|
option = woption()
|
||||||
)
|
if option.issubdyn():
|
||||||
context.reset_cache(option_subconfig)
|
option_subconfigs = subconfig.get_common_child(option,
|
||||||
|
validate_properties=False,
|
||||||
|
)
|
||||||
|
if not isinstance(option_subconfigs, list):
|
||||||
|
option_subconfigs = [option_subconfigs]
|
||||||
|
else:
|
||||||
|
option_subconfigs = [context.get_sub_config(config_bag,
|
||||||
|
option.impl_getpath(),
|
||||||
|
None,
|
||||||
|
validate_properties=False,
|
||||||
|
)]
|
||||||
|
for option_subconfig in option_subconfigs:
|
||||||
|
context.reset_cache(option_subconfig)
|
||||||
|
|
||||||
def get_information(self,
|
def get_information(self,
|
||||||
subconfig,
|
subconfig,
|
||||||
|
@ -706,18 +693,25 @@ class Values:
|
||||||
|
|
||||||
:param name: the item string (ex: "help")
|
:param name: the item string (ex: "help")
|
||||||
"""
|
"""
|
||||||
if subconfig is None:
|
if subconfig.option.impl_is_symlinkoption():
|
||||||
path = None
|
option = subconfig.option.impl_getopt()
|
||||||
|
path = option.impl_getpath()
|
||||||
else:
|
else:
|
||||||
|
option = subconfig.option
|
||||||
path = subconfig.path
|
path = subconfig.path
|
||||||
try:
|
try:
|
||||||
return self._informations[path][name]
|
return self._informations[path][name]
|
||||||
except KeyError as err:
|
except KeyError as err:
|
||||||
if subconfig:
|
pass
|
||||||
return subconfig.option.impl_get_information(name, default)
|
if option is not None:
|
||||||
if default is not undefined:
|
return option._get_information(subconfig,
|
||||||
return default
|
name,
|
||||||
raise ValueError(_("information's item not found: {0}").format(name)) from err
|
default,
|
||||||
|
)
|
||||||
|
return subconfig.config_bag.context.get_description()._get_information(subconfig,
|
||||||
|
name,
|
||||||
|
default,
|
||||||
|
)
|
||||||
|
|
||||||
def del_information(self,
|
def del_information(self,
|
||||||
key: Any,
|
key: Any,
|
||||||
|
|
Loading…
Reference in a new issue