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():
|
||||
od1 = make_description()
|
||||
cfg = Config(od1)
|
||||
cfg.option('u2').permissive.set(frozenset(['prop']))
|
||||
cfg.option('u2').permissive.add('prop')
|
||||
export = cfg.permissive.exportation()
|
||||
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'}
|
||||
cfg.permissive.importation(export)
|
||||
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'][0][0] is None
|
||||
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.ip_admin_eth0'].keys()) == set([None])
|
||||
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'][1][0] is None
|
||||
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.ip_admin_eth0'].keys()) == set([None])
|
||||
assert set(cache['ip_admin_eth0.netmask_admin_eth0'].keys()) == set([0, 1])
|
||||
|
@ -376,8 +376,7 @@ def test_cache_leader_and_followers():
|
|||
idx_val2 = None
|
||||
values = cfg._config_bag.context._impl_values_cache
|
||||
settings = cfg._config_bag.context.properties_cache
|
||||
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
||||
'val1': {None: (val1_props, None)},
|
||||
compare(settings.get_cached(), {'val1': {None: (val1_props, None)},
|
||||
'val1.val1': {None: (val1_val1_props, None)},
|
||||
})
|
||||
# len is 0 so don't get any value
|
||||
|
@ -385,17 +384,14 @@ def test_cache_leader_and_followers():
|
|||
#
|
||||
cfg.option('val1.val1').value.set([None])
|
||||
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
|
||||
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
||||
# 'val1.val1': {None: (val1_val1_props, None)},
|
||||
})
|
||||
compare(settings.get_cached(), {'val1.val1': {None: ({'empty', 'unique'}, None, True)}})
|
||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||
cfg.value.get()
|
||||
#has value
|
||||
idx_val2 = 0
|
||||
val_val2 = None
|
||||
val_val2_props = {idx_val2: (val1_val2_props, None)}
|
||||
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
||||
'val1': {None: (val1_props, None)},
|
||||
compare(settings.get_cached(), {'val1': {None: (val1_props, None)},
|
||||
'val1.val1': {None: (val1_val1_props, None)},
|
||||
'val1.val2': val_val2_props})
|
||||
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.value.get()
|
||||
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)}})
|
||||
val1_val2_props = {0: (frozenset([]), None), 1: (frozenset([]), None)}
|
||||
# assert not list_sessions()
|
||||
|
@ -428,15 +424,12 @@ def test_cache_leader_callback():
|
|||
val1_val2_props = frozenset(val1_val2_props)
|
||||
values = cfg._config_bag.context._impl_values_cache
|
||||
settings = cfg._config_bag.context.properties_cache
|
||||
compare(settings.get_cached(), {None: {None: (global_props, None)},
|
||||
'val1': {None: (val1_props, None)},
|
||||
compare(settings.get_cached(), {'val1': {None: (val1_props, None)},
|
||||
'val1.val1': {None: (val1_val1_props, None)},
|
||||
})
|
||||
compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
|
||||
cfg.option('val1.val1').value.set([None])
|
||||
compare(settings.get_cached(), {None: {None: (set(global_props), None)},
|
||||
# 'val1.val1': {None: (val1_val1_props, None)},
|
||||
})
|
||||
compare(settings.get_cached(), {'val1.val1': {None: ({'unique', 'empty'}, None, True)}})
|
||||
|
||||
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
|
||||
cfg.value.get()
|
||||
|
@ -458,38 +451,33 @@ def test_cache_requires():
|
|||
settings = cfg._config_bag.context.properties_cache
|
||||
assert values.get_cached() == {}
|
||||
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)},
|
||||
'activate_service': {None: (set([]), None)},
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
cfg.value.get()
|
||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
||||
'activate_service': {None: (set([]), None)},
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
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)},
|
||||
'activate_service': {None: (set([]), None)}})
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}})
|
||||
cfg.value.get()
|
||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
||||
'activate_service': {None: (set([]), None)},
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
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)}})
|
||||
cfg.value.get()
|
||||
compare(settings.get_cached(), {None: {None: (set(['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']), None)},
|
||||
'activate_service': {None: (set([]), None)},
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set(['disabled']), None)}})
|
||||
|
||||
compare(values.get_cached(), {'activate_service': {None: (False, None)}})
|
||||
|
@ -511,21 +499,18 @@ def test_cache_global_properties():
|
|||
settings = cfg._config_bag.context.properties_cache
|
||||
assert values.get_cached() == {}
|
||||
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)},
|
||||
'activate_service': {None: (set([]), None)},
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
|
||||
compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
|
||||
'activate_service': {None: (True, None)}})
|
||||
cfg.property.remove('disabled')
|
||||
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)},
|
||||
'activate_service': {None: (set([]), None)},
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
cfg.property.add('test')
|
||||
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)},
|
||||
'activate_service': {None: (set([]), None)},
|
||||
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)},
|
||||
'ip_address_service': {None: (set([]), None)}})
|
||||
# assert not list_sessions()
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# coding: utf-8
|
||||
from py.test import raises
|
||||
|
||||
from .autopath import 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, \
|
||||
undefined, Params, ParamValue, ParamOption
|
||||
from tiramisu.error import ConfigError
|
||||
|
@ -76,6 +75,29 @@ def test_choiceoption_function(config_type):
|
|||
# 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():
|
||||
choice = ChoiceOption('choice', '', values=Calculation(return_error))
|
||||
od1 = OptionDescription('od', '', [choice])
|
||||
|
@ -262,3 +284,13 @@ def test_choiceoption_calc_not_list():
|
|||
with raises(ConfigError):
|
||||
cfg.option('choice').value.set(['val1'])
|
||||
# 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)
|
||||
stroption = StrOption('str', 'Test string option', default="abc", properties=('mandatory', ))
|
||||
boolop = BoolOption('boolop', 'Test boolean option op', default=True, properties=('hidden',))
|
||||
wantref_option = BoolOption('wantref', 'Test requires', default=False)
|
||||
wantref_option.impl_set_information('info', 'default value')
|
||||
wantref_option = BoolOption('wantref', 'Test requires', default=False, informations={'info': 'default value'})
|
||||
wantframework_option = BoolOption('wantframework', 'Test requires',
|
||||
default=False)
|
||||
|
||||
|
@ -143,11 +142,11 @@ def test_information_config():
|
|||
with pytest.raises(ValueError):
|
||||
cfg.information.get('noinfo')
|
||||
assert cfg.information.get('noinfo', 'default') == 'default'
|
||||
cfg.information.reset('info')
|
||||
cfg.information.remove('info')
|
||||
with pytest.raises(ValueError):
|
||||
cfg.information.get('info')
|
||||
cfg.information.remove('info')
|
||||
with pytest.raises(ValueError):
|
||||
cfg.information.reset('noinfo')
|
||||
cfg.information.remove('noinfo')
|
||||
assert list(cfg.information.list()) == ['doc']
|
||||
# assert not list_sessions()
|
||||
|
||||
|
@ -194,26 +193,23 @@ def test_information_option():
|
|||
with pytest.raises(ValueError):
|
||||
cfg.option('gc.name').information.get('noinfo')
|
||||
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):
|
||||
cfg.option('gc.name').information.get('info')
|
||||
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 cfg.option('wantref').information.get('info') == 'default value'
|
||||
cfg.option('wantref').information.set('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 not list_sessions()
|
||||
|
||||
|
||||
def test_information_option_2():
|
||||
i1 = IntOption('test1', '')
|
||||
i1.impl_set_information('info', 'value')
|
||||
# it's a dict
|
||||
assert set(i1.impl_list_information()) == {'info', 'doc'}
|
||||
i1 = IntOption('test1', '', informations={'info': 'value'})
|
||||
od1 = OptionDescription('test', '', [i1])
|
||||
cfg = Config(od1)
|
||||
# it's tuples
|
||||
|
@ -234,11 +230,11 @@ def test_information_optiondescription():
|
|||
with pytest.raises(ValueError):
|
||||
cfg.option('gc').information.get('noinfo')
|
||||
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):
|
||||
cfg.option('gc').information.get('info')
|
||||
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 not list_sessions()
|
||||
|
||||
|
|
|
@ -412,7 +412,6 @@ def test_help():
|
|||
cfg = Config(od2)
|
||||
cfg.help(_display=False)
|
||||
cfg.config.help(_display=False)
|
||||
cfg.option.help(_display=False)
|
||||
cfg.option('o').help(_display=False)
|
||||
cfg.option('o.s').help(_display=False)
|
||||
# assert not list_sessions()
|
||||
|
@ -430,7 +429,7 @@ def test_config_reset():
|
|||
#
|
||||
cfg.option('gc.gc2.bool').value.set(True)
|
||||
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')
|
||||
assert cfg.option('gc.gc2.bool').value.get()
|
||||
assert cfg.option('boolop').property.get()
|
||||
|
|
|
@ -59,27 +59,27 @@ def test_copy_information():
|
|||
ncfg = cfg.config.copy()
|
||||
assert ncfg.information.get('key') == 'value'
|
||||
# assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#def test_copy_force_store_value():
|
||||
# od1 = make_description()
|
||||
# conf = Config(od1)
|
||||
# conf2 = Config(od1)
|
||||
# assert conf.value.exportation() == {}
|
||||
# assert conf2.value.exportation() == {}
|
||||
# #
|
||||
# conf.property.read_write()
|
||||
# assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||
# assert conf2.value.exportation() == {}
|
||||
# #
|
||||
# conf2.property.read_only()
|
||||
# assert conf.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)
|
||||
# assert conf.value.exportation() == {'creole.general.wantref': {None: [True, 'user']}}
|
||||
# assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||
## assert not list_sessions()
|
||||
|
||||
|
||||
def test_copy_force_store_value():
|
||||
od1 = make_description()
|
||||
conf = Config(od1)
|
||||
conf2 = Config(od1)
|
||||
assert conf.value.exportation() == {}
|
||||
assert conf2.value.exportation() == {}
|
||||
#
|
||||
conf.property.read_write()
|
||||
assert conf.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||
assert conf2.value.exportation() == {}
|
||||
#
|
||||
conf2.property.read_only()
|
||||
assert conf.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)
|
||||
assert conf.value.exportation() == {'creole.general.wantref': {None: [True, 'user']}}
|
||||
assert conf2.value.exportation() == {'creole.general.wantref': {None: [False, 'forced']}}
|
||||
# assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#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()
|
||||
|
||||
|
||||
#def test_force_store_value():
|
||||
# od1 = make_description_freeze()
|
||||
# cfg = Config(od1)
|
||||
# compare(cfg.value.exportation(), {})
|
||||
# cfg.property.read_write()
|
||||
# compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||
# cfg.option('bool').value.set(False)
|
||||
# cfg.option('wantref').value.set(True)
|
||||
# cfg.option('bool').value.reset()
|
||||
# compare(cfg.value.exportation(), {'wantref': {None: [True, 'user']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||
# cfg.option('bool').value.set(False)
|
||||
# cfg.option('wantref').value.reset()
|
||||
# cfg.option('bool').value.reset()
|
||||
# compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#def test_force_store_value_leadership_sub():
|
||||
# b = IntOption('int', 'Test int option', multi=True, properties=('force_store_value',))
|
||||
# c = StrOption('str', 'Test string option', multi=True)
|
||||
# descr = Leadership("int", "", [b, c])
|
||||
# od1 = OptionDescription('odr', '', [descr])
|
||||
# cfg = Config(od1)
|
||||
# cfg.property.read_only()
|
||||
# compare(cfg.value.exportation(), {'int.int': {None: [[], 'forced']}})
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#def test_force_store_value_callback():
|
||||
# b = IntOption('int', 'Test int option', Calculation(return_val), properties=('force_store_value',))
|
||||
# od1 = OptionDescription("int", "", [b])
|
||||
# cfg = Config(od1)
|
||||
# cfg.property.read_only()
|
||||
# compare(cfg.value.exportation(), {'int': {None: [1, 'forced']}})
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#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',))
|
||||
# od1 = OptionDescription("int", "", [b])
|
||||
# cfg = Config(od1)
|
||||
# cfg.property.read_only()
|
||||
# compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#def test_force_store_value_callback_params_with_opt():
|
||||
# a = IntOption('val1', "", 2)
|
||||
# b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamOption(a)})), properties=('force_store_value',))
|
||||
# od1 = OptionDescription("int", "", [a, b])
|
||||
# cfg = Config(od1)
|
||||
# cfg.property.read_only()
|
||||
# compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
||||
## assert not list_sessions()
|
||||
def test_force_store_value():
|
||||
od1 = make_description_freeze()
|
||||
cfg = Config(od1)
|
||||
compare(cfg.value.exportation(), {})
|
||||
cfg.property.read_write()
|
||||
compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||
cfg.option('bool').value.set(False)
|
||||
cfg.option('wantref').value.set(True)
|
||||
cfg.option('bool').value.reset()
|
||||
compare(cfg.value.exportation(), {'wantref': {None: [True, 'user']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||
cfg.option('bool').value.set(False)
|
||||
cfg.option('wantref').value.reset()
|
||||
cfg.option('bool').value.reset()
|
||||
compare(cfg.value.exportation(), {'wantref': {None: [False, 'forced']}, 'wantref2': {None: [False, 'forced']}, 'wantref3': {None: [[False], 'forced']}})
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_force_store_value_leadership_sub():
|
||||
b = IntOption('int', 'Test int option', multi=True, properties=('force_store_value',))
|
||||
c = StrOption('str', 'Test string option', multi=True)
|
||||
descr = Leadership("int", "", [b, c])
|
||||
od1 = OptionDescription('odr', '', [descr])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_only()
|
||||
compare(cfg.value.exportation(), {'int.int': {None: [[], 'forced']}})
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_force_store_value_callback():
|
||||
b = IntOption('int', 'Test int option', Calculation(return_val), properties=('force_store_value',))
|
||||
od1 = OptionDescription("int", "", [b])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_only()
|
||||
compare(cfg.value.exportation(), {'int': {None: [1, 'forced']}})
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
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',))
|
||||
od1 = OptionDescription("int", "", [b])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_only()
|
||||
compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_force_store_value_callback_params_with_opt():
|
||||
a = IntOption('val1', "", 2)
|
||||
b = IntOption('int', 'Test int option', Calculation(return_val2, Params(kwargs={'value': ParamOption(a)})), properties=('force_store_value',))
|
||||
od1 = OptionDescription("int", "", [a, b])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_only()
|
||||
compare(cfg.value.exportation(), {'int': {None: [2, 'forced']}})
|
||||
# assert not list_sessions()
|
||||
|
|
|
@ -159,7 +159,7 @@ def test_iter_on_empty_group():
|
|||
od1 = OptionDescription("name", "descr", [])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
result = list(cfg.option.list())
|
||||
result = list(cfg.list())
|
||||
assert result == []
|
||||
# assert not list_sessions()
|
||||
|
||||
|
@ -207,7 +207,7 @@ def test_leader_list(config_type):
|
|||
od1 = OptionDescription('od', '', [interface1])
|
||||
cfg = Config(od1)
|
||||
cfg = get_config(cfg, config_type)
|
||||
ret = cfg.option.list()
|
||||
ret = cfg.list()
|
||||
assert len(ret) == 1
|
||||
assert ret[0].name() == 'leadership'
|
||||
#
|
||||
|
@ -983,65 +983,65 @@ def test_follower_not_multi():
|
|||
# assert not list_sessions()
|
||||
|
||||
|
||||
#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'])
|
||||
# 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])
|
||||
# od1 = OptionDescription('od', '', [interface0])
|
||||
# od2 = OptionDescription('toto', '', [od1])
|
||||
# cfg = Config(od2)
|
||||
# cfg.property.read_write()
|
||||
# assert cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#def test_follower_force_store_value():
|
||||
# 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',))
|
||||
# interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||
# od1 = OptionDescription('od', '', [interface0])
|
||||
# od2 = OptionDescription('toto', '', [od1])
|
||||
# cfg = Config(od2)
|
||||
# cfg.property.read_write()
|
||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#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'])
|
||||
# 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])
|
||||
# od1 = OptionDescription('od', '', [interface0])
|
||||
# od2 = OptionDescription('toto', '', [od1])
|
||||
# cfg = Config(od2)
|
||||
# cfg.property.read_only()
|
||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
#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'])
|
||||
# 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])
|
||||
# od1 = OptionDescription('od', '', [interface0])
|
||||
# od2 = OptionDescription('toto', '', [od1])
|
||||
# cfg = Config(od2)
|
||||
# cfg.property.read_write()
|
||||
# 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', 1).owner.isdefault()
|
||||
# #
|
||||
# cfg.option('od.interface0.netmask_admin_eth0', 1).value.reset()
|
||||
# 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)
|
||||
# assert cfg.option('od.interface0.ip_admin_eth0').value.get() == []
|
||||
# cfg.option('od.interface0.ip_admin_eth0').value.reset()
|
||||
# assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
## assert not list_sessions()
|
||||
#
|
||||
#
|
||||
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'])
|
||||
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])
|
||||
od1 = OptionDescription('od', '', [interface0])
|
||||
od2 = OptionDescription('toto', '', [od1])
|
||||
cfg = Config(od2)
|
||||
cfg.property.read_write()
|
||||
assert cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_follower_force_store_value():
|
||||
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',))
|
||||
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
|
||||
od1 = OptionDescription('od', '', [interface0])
|
||||
od2 = OptionDescription('toto', '', [od1])
|
||||
cfg = Config(od2)
|
||||
cfg.property.read_write()
|
||||
assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
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'])
|
||||
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])
|
||||
od1 = OptionDescription('od', '', [interface0])
|
||||
od2 = OptionDescription('toto', '', [od1])
|
||||
cfg = Config(od2)
|
||||
cfg.property.read_only()
|
||||
assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
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'])
|
||||
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])
|
||||
od1 = OptionDescription('od', '', [interface0])
|
||||
od2 = OptionDescription('toto', '', [od1])
|
||||
cfg = Config(od2)
|
||||
cfg.property.read_write()
|
||||
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', 1).owner.isdefault()
|
||||
#
|
||||
cfg.option('od.interface0.netmask_admin_eth0', 1).value.reset()
|
||||
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)
|
||||
assert cfg.option('od.interface0.ip_admin_eth0').value.get() == []
|
||||
cfg.option('od.interface0.ip_admin_eth0').value.reset()
|
||||
assert not cfg.option('od.interface0.netmask_admin_eth0', 0).owner.isdefault()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
#def test_follower_properties():
|
||||
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',))
|
||||
|
|
|
@ -34,20 +34,6 @@ def test_option_valid_name():
|
|||
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():
|
||||
description = "it's ok"
|
||||
string = 'some informations'
|
||||
|
@ -55,21 +41,16 @@ def test_option_get_information_config():
|
|||
od = OptionDescription('od', '', [i])
|
||||
cfg = Config(od)
|
||||
with pytest.raises(ValueError):
|
||||
i.impl_get_information('noinfo')
|
||||
with pytest.raises(AttributeError):
|
||||
i.impl_set_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
|
||||
cfg.option('test').information.get('noinfo')
|
||||
assert cfg.option('test').information.get('noinfo', 'default') == 'default'
|
||||
assert cfg.option('test').information.get('doc') == description
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_option_unknown():
|
||||
description = "it's ok"
|
||||
string = 'some informations'
|
||||
i = IntOption('test', description)
|
||||
i.impl_set_information('noinfo', 'optdefault')
|
||||
i = IntOption('test', description, informations={'noinfo': 'optdefault'})
|
||||
od = OptionDescription('od', '', [i])
|
||||
cfg = Config(od)
|
||||
#
|
||||
|
@ -93,8 +74,7 @@ def test_option_description():
|
|||
def test_option_get_information_default():
|
||||
description = "it's ok"
|
||||
string = 'some informations'
|
||||
i = IntOption('test', description)
|
||||
i.impl_set_information('noinfo', 'optdefault')
|
||||
i = IntOption('test', description, informations={'noinfo': 'optdefault'})
|
||||
od = OptionDescription('od', '', [i])
|
||||
cfg = Config(od)
|
||||
#
|
||||
|
@ -108,32 +88,30 @@ def test_option_get_information_default():
|
|||
def test_option_get_information_config2():
|
||||
description = "it's ok"
|
||||
string = 'some informations'
|
||||
i = IntOption('test', description)
|
||||
i.impl_set_information('info', string)
|
||||
i = IntOption('test', description, informations={'info': string})
|
||||
od = OptionDescription('od', '', [i])
|
||||
cfg = Config(od)
|
||||
with pytest.raises(ValueError):
|
||||
i.impl_get_information('noinfo')
|
||||
with pytest.raises(AttributeError):
|
||||
i.impl_set_information('info', 'hello')
|
||||
assert i.impl_get_information('info') == string
|
||||
cfg.option('test').information.get('noinfo')
|
||||
assert cfg.option('test').information.get('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
|
||||
cfg.option('test').information.get('noinfo')
|
||||
assert cfg.option('test').information.get('noinfo', 'default') == 'default'
|
||||
assert cfg.option('test').information.get('doc') == description
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
def test_optiondescription_get_information():
|
||||
description = "it's ok"
|
||||
string = 'some informations'
|
||||
o = OptionDescription('test', description, [])
|
||||
o.impl_set_information('info', string)
|
||||
assert o.impl_get_information('info') == string
|
||||
o = OptionDescription('test', description, [], informations={'info': string})
|
||||
od = OptionDescription('od', '', [o])
|
||||
cfg = Config(od)
|
||||
assert cfg.option('test').information.get('info') == string
|
||||
with pytest.raises(ValueError):
|
||||
o.impl_get_information('noinfo')
|
||||
assert o.impl_get_information('noinfo', 'default') == 'default'
|
||||
assert o.impl_get_information('doc') == description
|
||||
cfg.option('test').information.get('noinfo')
|
||||
assert cfg.option('test').information.get('noinfo', 'default') == 'default'
|
||||
assert cfg.option('test').information.get('doc') == description
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
@ -218,7 +196,7 @@ def test_optiondescription_group():
|
|||
od3.impl_set_group_type(groups.notfamily)
|
||||
od2 = OptionDescription('od', '', [od1, od3])
|
||||
cfg = Config(od2)
|
||||
assert len(list(cfg.option.list())) == 2
|
||||
assert len(list(cfg.list())) == 2
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
|
|
@ -415,8 +415,7 @@ def test_callback_information(config_type):
|
|||
|
||||
def test_callback_information2(config_type):
|
||||
val1 = StrOption('val1', "", Calculation(return_value, Params(ParamSelfInformation('information', 'no_value'))))
|
||||
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamSelfInformation('information'))))
|
||||
val2.impl_set_information('information', 'new_value')
|
||||
val2 = StrOption('val2', "", Calculation(return_value, Params(ParamSelfInformation('information'))), informations={'information': 'new_value'})
|
||||
val3 = StrOption('val3', "", Calculation(return_value, Params(ParamSelfInformation('information'))))
|
||||
od1 = OptionDescription('rootconfig', '', [val1, val2, val3])
|
||||
cfg = Config(od1)
|
||||
|
@ -432,9 +431,8 @@ def test_callback_information2(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))))
|
||||
val1.impl_set_information('information', 'new_value')
|
||||
od1 = OptionDescription('rootconfig', '', [val1, val2])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
|
@ -1691,3 +1689,38 @@ def test_calc_dependencies(config_type):
|
|||
def test_callback__kwargs_wrong(config_type):
|
||||
with pytest.raises(ValueError):
|
||||
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()
|
||||
|
||||
|
||||
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):
|
||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('notunique',))
|
||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
|
||||
|
|
|
@ -82,7 +82,7 @@ def test_mod_read_only_write():
|
|||
'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='remove', properties=frozenset(['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):
|
||||
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', 'remove') == {'hidden'}
|
||||
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([])
|
||||
#
|
||||
config.property.read_only()
|
||||
assert config.property.get() == {'cache', 'disabled'}
|
||||
assert config.property.get() == {'warnings', 'validator', 'cache', 'disabled'}
|
||||
config.property.read_write()
|
||||
assert config.property.get() == {'cache', 'disabled', 'hidden'}
|
||||
assert config.property.get() == {'warnings', 'validator', 'cache', 'disabled', 'hidden'}
|
||||
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('read_only', 'append') == {'frozen',
|
||||
|
@ -138,6 +138,19 @@ def test_mod_read_only_write():
|
|||
# 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):
|
||||
s = StrOption("string", "", default=["string", "sdfsdf"], default_multi="prout", multi=True)
|
||||
od1 = OptionDescription("options", "", [s])
|
||||
|
@ -365,8 +378,7 @@ def test_apply_requires_from_config():
|
|||
with pytest.raises(PropertiesOptionError):
|
||||
cfg.option('opt.str').value.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').properties(only_raises=True)
|
||||
assert 'hidden' not in cfg.forcepermissive.option('opt.str').property.get(only_raises=True)
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
@ -386,8 +398,7 @@ def test_apply_requires_with_disabled():
|
|||
cfg.option('int').value.set(1)
|
||||
with pytest.raises(PropertiesOptionError):
|
||||
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').properties(only_raises=True)
|
||||
assert 'disabled' not in cfg.unrestraint.option('opt.str').property.get(only_raises=True, apply_requires=False)
|
||||
assert 'disabled' in cfg.unrestraint.option('opt.str').property.get()
|
||||
# assert not list_sessions()
|
||||
|
||||
|
@ -607,7 +618,7 @@ def test_properties_get_add_reset():
|
|||
cfg.property.add('frozen')
|
||||
assert cfg.property.get() == {'validator', 'warnings', 'cache', 'frozen'}
|
||||
cfg.property.reset()
|
||||
assert cfg.property.get() == {'validator', 'warnings', 'cache'}
|
||||
assert cfg.property.get() == frozenset()
|
||||
|
||||
|
||||
def test_reset_properties_force_store_value():
|
||||
|
@ -615,28 +626,25 @@ def test_reset_properties_force_store_value():
|
|||
gcgroup = OptionDescription('gc', '', [gcdummy])
|
||||
od1 = OptionDescription('tiramisu', '', [gcgroup])
|
||||
cfg = Config(od1)
|
||||
assert cfg.property.exportation() == {}
|
||||
assert cfg.property.exportation() == {None: {None: frozenset({'validator', 'warnings', 'cache'})}}
|
||||
cfg.property.add('frozen')
|
||||
assert cfg.property.exportation() == \
|
||||
{None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}}
|
||||
cfg.property.reset()
|
||||
assert cfg.property.exportation() == {None: {}}
|
||||
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()
|
||||
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')
|
||||
assert cfg.property.exportation() == \
|
||||
{None: {None: set(('frozen', 'validator', 'cache', 'warnings'))},
|
||||
'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
||||
{None: {None: frozenset({'frozen'})}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||
cfg.property.add('frozen')
|
||||
assert cfg.property.exportation() == \
|
||||
{None: {None: set(('frozen', 'validator', 'cache', 'warnings'))},
|
||||
'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
||||
{None: {None: frozenset({'frozen'})}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||
cfg.option('gc.dummy').property.add('test')
|
||||
assert cfg.property.exportation() == \
|
||||
{None: {None: set(('frozen', 'validator', 'cache', 'warnings'))},
|
||||
'gc.dummy': {None: set(('test', 'force_store_value'))}}
|
||||
{None: {None: frozenset({'frozen'})}, 'gc.dummy': {None: frozenset({'test'})}}
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
@ -666,7 +674,7 @@ def test_set_modified_value():
|
|||
gcgroup = OptionDescription('gc', '', [gcdummy])
|
||||
od1 = OptionDescription('tiramisu', '', [gcgroup])
|
||||
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'))}})
|
||||
assert cfg.property.exportation() == \
|
||||
{None: {None: set(('frozen', 'cache', 'validator', 'warnings'))}}
|
||||
|
|
|
@ -64,7 +64,10 @@ def test_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.property.read_write()
|
||||
cfg_ori.option('gc').property.add('hidden')
|
||||
|
@ -73,14 +76,14 @@ def test_group_is_hidden(config_type):
|
|||
cfg.option('gc.dummy').value.get()
|
||||
if config_type == 'tiramisu-api':
|
||||
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)
|
||||
with pytest.raises(PropertiesOptionError):
|
||||
cfg.option('gc.float').value.get()
|
||||
# manually set the subconfigs to "show"
|
||||
if config_type == 'tiramisu-api':
|
||||
cfg.send()
|
||||
cfg_ori.forcepermissive.option('gc').property.remove('hidden')
|
||||
cfg_ori.option('gc').property.remove('hidden')
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
assert not 'hidden' in cfg.option('gc').property.get()
|
||||
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):
|
||||
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')
|
||||
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)
|
||||
with pytest.raises(ConfigError):
|
||||
cfg.option('opt1').value.get()
|
||||
with pytest.raises(ConfigError):
|
||||
cfg.option('opt3').value.get()
|
||||
cfg.option('opt1').information.set('key', 'val')
|
||||
assert cfg.option('opt1').value.get() == 'val'
|
||||
assert cfg.option('opt3').value.get() == 'val'
|
||||
cfg.option('opt1').information.set('key', 'val1')
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('opt1').value.get()
|
||||
with pytest.raises(ValueError):
|
||||
cfg.option('opt3').value.get()
|
||||
#
|
||||
with pytest.raises(ConfigError):
|
||||
assert cfg.option('opt2').value.get()
|
||||
cfg.option('opt2').value.get()
|
||||
cfg.information.set('key', 'val')
|
||||
assert cfg.option('opt2').value.get() == 'val'
|
||||
cfg.information.set('key', 'val1')
|
||||
|
|
|
@ -22,7 +22,7 @@ def test_forcepermissive_and_unrestraint(config_type):
|
|||
cfg_ori.property.read_write()
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
with pytest.raises(ConfigError):
|
||||
cfg_ori.unrestraint.forcepermissive.add('disabled')
|
||||
cfg_ori.forcepermissive.add('disabled')
|
||||
|
||||
|
||||
def test_permissive(config_type):
|
||||
|
@ -39,9 +39,9 @@ def test_permissive(config_type):
|
|||
assert set(props) == {'disabled'}
|
||||
if config_type == 'tiramisu-api':
|
||||
cfg.send()
|
||||
cfg_ori.unrestraint.permissive.add('disabled')
|
||||
cfg_ori.unrestraint.permissive.remove('hidden')
|
||||
assert cfg_ori.unrestraint.permissive.get() == frozenset(['disabled'])
|
||||
cfg_ori.permissive.add('disabled')
|
||||
cfg_ori.permissive.remove('hidden')
|
||||
assert cfg_ori.permissive.get() == frozenset(['disabled'])
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
props = frozenset()
|
||||
try:
|
||||
|
@ -81,8 +81,8 @@ def test_permissive_add(config_type):
|
|||
assert set(props) == {'disabled'}
|
||||
if config_type == 'tiramisu-api':
|
||||
cfg.send()
|
||||
cfg_ori.unrestraint.permissive.add('disabled')
|
||||
assert cfg_ori.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
|
||||
cfg_ori.permissive.add('disabled')
|
||||
assert cfg_ori.permissive.get() == frozenset(['hidden', 'disabled'])
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
props = frozenset()
|
||||
try:
|
||||
|
@ -119,10 +119,10 @@ def test_permissive_pop():
|
|||
except PropertiesOptionError as err:
|
||||
props = err.proptype
|
||||
assert set(props) == {'disabled'}
|
||||
cfg.unrestraint.permissive.add('disabled')
|
||||
assert cfg.unrestraint.permissive.get() == frozenset(['hidden', 'disabled'])
|
||||
cfg.permissive.add('disabled')
|
||||
assert cfg.permissive.get() == frozenset(['hidden', 'disabled'])
|
||||
cfg.forcepermissive.option('u1').value.get()
|
||||
cfg.unrestraint.permissive.remove('disabled')
|
||||
cfg.permissive.remove('disabled')
|
||||
props = frozenset()
|
||||
try:
|
||||
cfg.forcepermissive.option('u1').value.get()
|
||||
|
@ -136,14 +136,14 @@ def test_permissive_reset():
|
|||
od1 = make_description()
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
assert cfg.unrestraint.permissive.get() == frozenset(['hidden'])
|
||||
assert cfg.permissive.get() == frozenset(['hidden'])
|
||||
#
|
||||
cfg.unrestraint.permissive.add('disabled')
|
||||
cfg.unrestraint.permissive.remove('hidden')
|
||||
assert cfg.unrestraint.permissive.get() == frozenset(['disabled'])
|
||||
cfg.permissive.add('disabled')
|
||||
cfg.permissive.remove('hidden')
|
||||
assert cfg.permissive.get() == frozenset(['disabled'])
|
||||
#
|
||||
cfg.unrestraint.permissive.reset()
|
||||
assert cfg.unrestraint.permissive.get() == frozenset()
|
||||
cfg.permissive.reset()
|
||||
assert cfg.permissive.get() == frozenset(['hidden'])
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
@ -157,9 +157,9 @@ def test_permissive_mandatory():
|
|||
except PropertiesOptionError as err:
|
||||
props = err.proptype
|
||||
assert frozenset(props) == frozenset(['disabled'])
|
||||
cfg.unrestraint.permissive.add('mandatory')
|
||||
cfg.unrestraint.permissive.add('disabled')
|
||||
assert cfg.unrestraint.permissive.get() == frozenset(['mandatory', 'disabled'])
|
||||
cfg.permissive.add('mandatory')
|
||||
cfg.permissive.add('disabled')
|
||||
assert cfg.permissive.get() == frozenset(['hidden', 'mandatory', 'disabled'])
|
||||
cfg.property.add('permissive')
|
||||
cfg.option('u1').value.get()
|
||||
cfg.property.remove('permissive')
|
||||
|
@ -175,10 +175,10 @@ def test_permissive_frozen():
|
|||
od1 = make_description()
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
cfg.unrestraint.permissive.remove('hidden')
|
||||
cfg.unrestraint.permissive.add('frozen')
|
||||
cfg.unrestraint.permissive.add('disabled')
|
||||
assert cfg.unrestraint.permissive.get() == frozenset(['frozen', 'disabled'])
|
||||
cfg.permissive.remove('hidden')
|
||||
cfg.permissive.add('frozen')
|
||||
cfg.permissive.add('disabled')
|
||||
assert cfg.permissive.get() == frozenset(['frozen', 'disabled'])
|
||||
assert cfg.permissive.get() == frozenset(['frozen', 'disabled'])
|
||||
try:
|
||||
cfg.option('u1').value.set(1)
|
||||
|
@ -229,7 +229,7 @@ def test_permissive_option(config_type):
|
|||
|
||||
if config_type == 'tiramisu-api':
|
||||
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)
|
||||
props = frozenset()
|
||||
try:
|
||||
|
@ -293,7 +293,7 @@ def test_permissive_option_cache():
|
|||
props = err.proptype
|
||||
assert set(props) == {'disabled'}
|
||||
|
||||
cfg.unrestraint.option('u1').permissive.set(frozenset(['disabled']))
|
||||
cfg.option('u1').permissive.add('disabled')
|
||||
props = frozenset()
|
||||
try:
|
||||
cfg.option('u1').value.get()
|
||||
|
@ -342,8 +342,9 @@ def test_permissive_option_mandatory():
|
|||
except PropertiesOptionError as err:
|
||||
props = err.proptype
|
||||
assert frozenset(props) == frozenset(['disabled'])
|
||||
cfg.unrestraint.option('u1').permissive.set(frozenset(['mandatory', 'disabled']))
|
||||
assert cfg.unrestraint.option('u1').permissive.get() == frozenset(['mandatory', 'disabled'])
|
||||
cfg.option('u1').permissive.add('mandatory')
|
||||
cfg.option('u1').permissive.add('disabled')
|
||||
assert cfg.option('u1').permissive.get() == frozenset(['mandatory', 'disabled'])
|
||||
cfg.property.add('permissive')
|
||||
cfg.option('u1').value.get()
|
||||
cfg.property.remove('permissive')
|
||||
|
@ -359,7 +360,8 @@ def test_permissive_option_frozen():
|
|||
od1 = make_description()
|
||||
cfg = Config(od1)
|
||||
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)
|
||||
assert cfg.option('u1').value.get() == 1
|
||||
cfg.property.add('permissive')
|
||||
|
@ -369,15 +371,6 @@ def test_permissive_option_frozen():
|
|||
# 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):
|
||||
var1 = StrOption('var1', '', u'value', properties=('hidden',))
|
||||
od1 = OptionDescription('od1', '', [var1])
|
||||
|
@ -389,13 +382,13 @@ def test_remove_option_permissive(config_type):
|
|||
cfg.option('od1.var1').value.get()
|
||||
if config_type == 'tiramisu-api':
|
||||
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'])
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
assert cfg.option('od1.var1').value.get() == 'value'
|
||||
if config_type == 'tiramisu-api':
|
||||
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()
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
with pytest.raises(PropertiesOptionError):
|
||||
|
@ -414,7 +407,7 @@ def test_reset_option_permissive(config_type):
|
|||
cfg.option('od1.var1').value.get()
|
||||
if config_type == 'tiramisu-api':
|
||||
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'])
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
assert cfg.option('od1.var1').value.get() == 'value'
|
||||
|
|
|
@ -31,12 +31,12 @@ def test_properties(config_type):
|
|||
assert frozenset(props) == frozenset(['disabled'])
|
||||
if config_type == 'tiramisu-api':
|
||||
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.option('ip_address_service').value.get()
|
||||
if config_type == 'tiramisu-api':
|
||||
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)
|
||||
props = []
|
||||
try:
|
||||
|
@ -47,8 +47,8 @@ def test_properties(config_type):
|
|||
# pop twice
|
||||
if config_type == 'tiramisu-api':
|
||||
cfg.send()
|
||||
cfg_ori.unrestraint.option('ip_address_service').property.remove('disabled')
|
||||
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').permissive.remove('disabled')
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
@ -613,6 +613,7 @@ def test_requires_transitive_hidden_disabled_multiple(config_type):
|
|||
del req
|
||||
#
|
||||
cfg_ori.permissive.reset()
|
||||
cfg_ori.permissive.remove('hidden')
|
||||
if config_type == 'tiramisu-api':
|
||||
try:
|
||||
cfg = get_config(cfg_ori, config_type)
|
||||
|
|
|
@ -141,7 +141,7 @@ def test_symlink_getpermissive():
|
|||
od1 = OptionDescription('opt', '', [boolopt, linkopt])
|
||||
cfg = Config(od1)
|
||||
cfg.property.read_write()
|
||||
cfg.option('b').permissive.set(frozenset(['perm']))
|
||||
cfg.option('b').permissive.add('perm')
|
||||
cfg.option('c').permissive.get() == frozenset(['perm'])
|
||||
# assert not list_sessions()
|
||||
|
||||
|
@ -266,14 +266,26 @@ def test_symlink_owner(config_type):
|
|||
|
||||
|
||||
def test_symlink_get_information():
|
||||
boolopt = BoolOption("b", "", default=False)
|
||||
boolopt = BoolOption("b", "", default=False, informations={'test': 'test'})
|
||||
linkopt = SymLinkOption("c", boolopt)
|
||||
boolopt.impl_set_information('test', 'test')
|
||||
assert boolopt.impl_get_information('test') == 'test'
|
||||
assert linkopt.impl_get_information('test') == 'test'
|
||||
boolopt.impl_set_information('test', 'test2')
|
||||
assert boolopt.impl_get_information('test') == 'test2'
|
||||
assert linkopt.impl_get_information('test') == 'test2'
|
||||
od1 = OptionDescription('opt', '', [linkopt, boolopt])
|
||||
cfg = Config(od1)
|
||||
assert cfg.option('b').information.get('test') == 'test'
|
||||
assert cfg.option('c').information.get('test') == 'test'
|
||||
cfg.option('b').information.set('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():
|
||||
|
@ -359,9 +371,9 @@ def test_symlink_dependency():
|
|||
[linkopt, OptionDescription("s1", "", [boolopt])])
|
||||
cfg = Config(od1)
|
||||
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('c').has_dependency(False) is False
|
||||
assert cfg.option('c').has_dependency(False) is True
|
||||
# assert not list_sessions()
|
||||
|
||||
|
||||
|
@ -385,7 +397,7 @@ def test_symlink_list(config_type):
|
|||
[linkopt, OptionDescription("s1", "", [boolopt])])
|
||||
cfg = Config(od1)
|
||||
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 not list_sessions()
|
||||
|
|
639
tiramisu/api.py
639
tiramisu/api.py
|
@ -24,14 +24,15 @@ from copy import deepcopy
|
|||
from .error import ConfigError, LeadershipError, ValueErrorWarning
|
||||
from .i18n import _
|
||||
from .setting import ConfigBag, owners, groups, undefined, \
|
||||
FORBIDDEN_SET_PROPERTIES, SPECIAL_PROPERTIES
|
||||
FORBIDDEN_SET_PROPERTIES, SPECIAL_PROPERTIES, \
|
||||
DEFAULT_PROPERTIES
|
||||
from .config import KernelConfig, KernelGroupConfig, KernelMetaConfig, KernelMixConfig, SubConfig
|
||||
from .option import RegexpOption, OptionDescription, ChoiceOption, Leadership
|
||||
from .todict import TiramisuDict
|
||||
from .autolib import Calculation
|
||||
|
||||
|
||||
TIRAMISU_VERSION = 4
|
||||
TIRAMISU_VERSION = 5
|
||||
|
||||
|
||||
class TiramisuHelp:
|
||||
|
@ -70,10 +71,6 @@ class TiramisuHelp:
|
|||
_('Do not warnings during validation')
|
||||
).expandtabs(max_len + 10))
|
||||
display()
|
||||
if isinstance(self, TiramisuDispatcherOption):
|
||||
doc = _(getdoc(self.__call__))
|
||||
display(_('Call: {}').format(doc))
|
||||
display()
|
||||
display(_('Commands:'))
|
||||
for module_name in modules:
|
||||
module = getattr(self, module_name)
|
||||
|
@ -90,21 +87,6 @@ class TiramisuHelp:
|
|||
class CommonTiramisu(TiramisuHelp):
|
||||
_validate_properties = True
|
||||
|
||||
def _get_subconfig(self,
|
||||
follower_not_apply_requires: bool,
|
||||
) -> "OptionBag":
|
||||
try:
|
||||
return self._config_bag.context.get_sub_config(self._config_bag,
|
||||
self._path,
|
||||
self._index,
|
||||
validate_properties=self._validate_properties,
|
||||
follower_not_apply_requires=follower_not_apply_requires,
|
||||
)
|
||||
except AssertionError as err:
|
||||
raise ConfigError(str(err))
|
||||
except Exception as err:
|
||||
raise err
|
||||
|
||||
|
||||
def option_type(typ):
|
||||
if not isinstance(typ, list):
|
||||
|
@ -126,17 +108,39 @@ def option_type(typ):
|
|||
kwargs['is_group'] = True
|
||||
return func(self, options_bag, *args[1:], **kwargs)
|
||||
if not self._subconfig:
|
||||
self._subconfig = self._get_subconfig('with_index' not in types)
|
||||
self._subconfig = self._config_bag.context.get_sub_config(self._config_bag,
|
||||
self._path,
|
||||
self._index,
|
||||
validate_properties=False,
|
||||
)
|
||||
option = self._subconfig.option
|
||||
if option.impl_is_optiondescription() and 'optiondescription' in types or \
|
||||
option.impl_is_optiondescription() and option.impl_is_leadership() and 'leadership' in types or \
|
||||
not option.impl_is_optiondescription() and (
|
||||
option.impl_is_symlinkoption() and 'symlink' in types or \
|
||||
not option.impl_is_symlinkoption() and (
|
||||
'option' in types or \
|
||||
option.impl_is_leader() and 'leader' in types or \
|
||||
option.impl_is_follower() and 'follower' in types or \
|
||||
isinstance(option, ChoiceOption) and 'choice' in types)):
|
||||
error_type = None
|
||||
if 'dynamic' in types:
|
||||
if not self._subconfig.is_dynamic:
|
||||
error_type = 'only available for dynamic option'
|
||||
elif option.impl_is_optiondescription():
|
||||
if 'optiondescription' not in types:
|
||||
if option.impl_is_leadership():
|
||||
if 'leadership' not in types:
|
||||
error_type = 'not available for a Leadership'
|
||||
else:
|
||||
error_type = 'not available for an OptionDescription'
|
||||
elif option.impl_is_symlinkoption():
|
||||
if 'symlink' not in types:
|
||||
error_type = 'this function is not available for a SymLinkOption'
|
||||
elif 'option' not in types:
|
||||
if 'choice' in types:
|
||||
if not isinstance(option, ChoiceOption):
|
||||
error_type = 'only available for ChoiceOption'
|
||||
elif option.impl_is_leader():
|
||||
if 'leader' not in types:
|
||||
error_type = 'not available for a Leader'
|
||||
elif option.impl_is_follower():
|
||||
if 'follower' not in types:
|
||||
error_type = 'not available for a Follower'
|
||||
else:
|
||||
error_type = 'not available for an Option'
|
||||
if not error_type:
|
||||
if not option.impl_is_optiondescription() and \
|
||||
not option.impl_is_symlinkoption() and \
|
||||
option.impl_is_follower():
|
||||
|
@ -150,9 +154,23 @@ def option_type(typ):
|
|||
msg = _('please specify index with a follower option '
|
||||
f'({self.__class__.__name__}.{func.__name__})')
|
||||
raise ConfigError(msg)
|
||||
if self._validate_properties:
|
||||
settings = self._config_bag.context.get_settings()
|
||||
parent = self._subconfig.parent
|
||||
if parent and parent.raises_properties:
|
||||
while parent:
|
||||
if not parent.parent.raises_properties:
|
||||
settings.validate_properties(parent,
|
||||
need_help=True,
|
||||
)
|
||||
break
|
||||
parent = parent.parent
|
||||
settings.validate_properties(self._subconfig,
|
||||
need_help=True,
|
||||
)
|
||||
return func(self, *args[1:], **kwargs)
|
||||
msg = _('please specify a valid sub function '
|
||||
f'({self.__class__.__name__}.{func.__name__})')
|
||||
f'({self.__class__.__name__}.{func.__name__}): {error_type}')
|
||||
raise ConfigError(msg)
|
||||
wrapped.func = func
|
||||
return wrapped
|
||||
|
@ -201,20 +219,28 @@ class _TiramisuOptionOptionDescription:
|
|||
"""Get Tiramisu option"""
|
||||
return self._subconfig.option
|
||||
|
||||
@option_type(['optiondescription', 'option', 'with_or_without_index', 'symlink'])
|
||||
def isoptiondescription(self):
|
||||
"""Test if option is an optiondescription"""
|
||||
return self._subconfig.option.impl_is_optiondescription()
|
||||
|
||||
@option_type(['optiondescription'])
|
||||
def isleadership(self):
|
||||
"""Test if option is a leader or a follower"""
|
||||
return self._subconfig.option.impl_is_leadership()
|
||||
|
||||
@option_type(['optiondescription', 'option', 'with_or_without_index'])
|
||||
@option_type(['optiondescription', 'option', 'with_or_without_index', 'symlink'])
|
||||
def doc(self):
|
||||
"""Get option document"""
|
||||
return self._subconfig.option.impl_get_display_name()
|
||||
return self._subconfig.option.impl_get_display_name(self._subconfig)
|
||||
|
||||
@option_type(['optiondescription', 'option', 'with_or_without_index'])
|
||||
@option_type(['optiondescription', 'option', 'with_or_without_index', 'symlink'])
|
||||
def description(self):
|
||||
"""Get option description"""
|
||||
return self._subconfig.option.impl_get_information('doc', None)
|
||||
return self._subconfig.option._get_information(self._subconfig,
|
||||
'doc',
|
||||
None,
|
||||
)
|
||||
|
||||
@option_type(['optiondescription', 'option', 'symlink', 'with_or_without_index'])
|
||||
def name(self) -> str:
|
||||
|
@ -235,7 +261,7 @@ class _TiramisuOptionOptionDescription:
|
|||
"""Test if option has dependency"""
|
||||
return self._subconfig.option.impl_has_dependency(self_is_dep)
|
||||
|
||||
@option_type(['optiondescription', 'option'])
|
||||
@option_type(['optiondescription', 'option', 'symlink', 'with_or_without_index'])
|
||||
def dependencies(self):
|
||||
"""Get dependencies from this option"""
|
||||
options = []
|
||||
|
@ -246,31 +272,42 @@ class _TiramisuOptionOptionDescription:
|
|||
))
|
||||
return options
|
||||
|
||||
@option_type(['optiondescription', 'option', 'with_or_without_index', 'symlink'])
|
||||
def isoptiondescription(self):
|
||||
"""Test if option is an optiondescription"""
|
||||
return self._subconfig.option.impl_is_optiondescription()
|
||||
@option_type(['option', 'optiondescription', 'symlink', 'with_or_without_index'])
|
||||
def type(self):
|
||||
"""Get de option type"""
|
||||
option = self._subconfig.option
|
||||
if option.impl_is_optiondescription():
|
||||
return 'optiondescription'
|
||||
return option.get_type()
|
||||
|
||||
@option_type(['optiondescription', 'option', 'with_or_without_index', 'symlink'])
|
||||
def properties(self,
|
||||
only_raises=False,
|
||||
uncalculated=False,
|
||||
):
|
||||
"""Get properties for an option"""
|
||||
settings = self._config_bag.context.get_settings()
|
||||
if uncalculated:
|
||||
return settings.getproperties(self._subconfig,
|
||||
uncalculated=True,
|
||||
@option_type(['option', 'optiondescription', 'symlink', 'with_or_without_index'])
|
||||
def isdynamic(self):
|
||||
"""Test if option is a dynamic optiondescription"""
|
||||
return self._subconfig.is_dynamic
|
||||
|
||||
@option_type(['option', 'leadership'])
|
||||
def leader(self):
|
||||
"""Get the leader option for a follower option"""
|
||||
option = self._subconfig.option
|
||||
if isinstance(option, Leadership):
|
||||
leadership = self._subconfig
|
||||
else:
|
||||
leadership = self._subconfig.parent
|
||||
leader_subconfig = leadership.get_child(leadership.option.get_leader(),
|
||||
None,
|
||||
False,
|
||||
)
|
||||
if not only_raises:
|
||||
return settings.getproperties(self._subconfig,
|
||||
apply_requires=False,
|
||||
)
|
||||
return settings.calc_raises_properties(self._subconfig,
|
||||
apply_requires=False,
|
||||
uncalculated=uncalculated,
|
||||
return TiramisuOption(leader_subconfig.path,
|
||||
None,
|
||||
self._config_bag,
|
||||
subconfig=leader_subconfig,
|
||||
)
|
||||
|
||||
@option_type(['dynamic', 'with_or_without_index'])
|
||||
def suffixes(self):
|
||||
"""Get suffixes for dynamic option"""
|
||||
return self._subconfig.suffixes
|
||||
|
||||
|
||||
class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
||||
"""Manage option"""
|
||||
|
@ -284,7 +321,7 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
|||
"""Test if option could have submulti value"""
|
||||
return self._subconfig.option.impl_is_submulti()
|
||||
|
||||
@option_type(['option', 'with_or_without_index'])
|
||||
@option_type(['option', 'with_or_without_index', 'symlink'])
|
||||
def isleader(self):
|
||||
"""Test if option is a leader"""
|
||||
return self._subconfig.option.impl_is_leader()
|
||||
|
@ -294,11 +331,6 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
|||
"""Test if option is a follower"""
|
||||
return self._subconfig.option.impl_is_follower()
|
||||
|
||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||
def isdynamic(self):
|
||||
"""Test if option is a dynamic optiondescription"""
|
||||
return self._subconfig.is_dynamic
|
||||
|
||||
@option_type(['option', 'symlink', 'with_or_without_index'])
|
||||
def issymlinkoption(self) -> bool:
|
||||
"""Test if option is a symlink option"""
|
||||
|
@ -316,14 +348,6 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
|||
raise ConfigError(_('only multi value has defaultmulti'))
|
||||
return self._subconfig.option.impl_getdefault_multi()
|
||||
|
||||
@option_type(['option', 'optiondescription', 'symlink', 'with_or_without_index'])
|
||||
def type(self):
|
||||
"""Get de option type"""
|
||||
option = self._subconfig.option
|
||||
if option.impl_is_optiondescription():
|
||||
return 'optiondescription'
|
||||
return option.get_type()
|
||||
|
||||
@option_type(['option', 'with_or_without_index'])
|
||||
def pattern(self) -> str:
|
||||
"""Get the option pattern"""
|
||||
|
@ -340,46 +364,57 @@ class _TiramisuOptionOption(_TiramisuOptionOptionDescription):
|
|||
#FIXME only from 0.0.0.0 to 255.255.255.255
|
||||
return r'^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
|
||||
|
||||
@option_type(['option', 'leadership'])
|
||||
def leader(self):
|
||||
"""Get the leader option for a follower option"""
|
||||
option = self._subconfig.option
|
||||
if isinstance(option, Leadership):
|
||||
leadership = self._subconfig
|
||||
else:
|
||||
leadership = self._subconfig.parent
|
||||
leader_subconfig = leadership.get_child(leadership.option.get_leader(),
|
||||
None,
|
||||
True,
|
||||
)
|
||||
return TiramisuOption(leader_subconfig.path,
|
||||
None,
|
||||
self._config_bag,
|
||||
subconfig=leader_subconfig,
|
||||
)
|
||||
|
||||
@option_type(['option', 'with_or_without_index'])
|
||||
@option_type(['option', 'with_or_without_index', 'symlink'])
|
||||
def index(self):
|
||||
"""Get then index of option"""
|
||||
"""Get index of option"""
|
||||
return self._subconfig.index
|
||||
|
||||
@option_type(['symlink', 'optiondescription'])
|
||||
def option(self, *args, **kwargs):
|
||||
"""For OptionDescription get sub option, for symlinkoption get the linked option"""
|
||||
if self._subconfig.option.impl_is_optiondescription():
|
||||
return self._option_description(*args, **kwargs)
|
||||
return self._option_symlink(*args, **kwargs)
|
||||
|
||||
class TiramisuOptionOption(CommonTiramisuOption):
|
||||
"""Manage option"""
|
||||
def __call__(self,
|
||||
name: str,
|
||||
index: Optional[int]=None,
|
||||
) -> 'TiramisuOption':
|
||||
"""Select an option by path"""
|
||||
return TiramisuOption(self._path + '.' + name,
|
||||
def _option_description(self,
|
||||
path,
|
||||
index=None,
|
||||
):
|
||||
sub_path = self._path + '.' + path
|
||||
return TiramisuOption(sub_path,
|
||||
index,
|
||||
self._config_bag,
|
||||
)
|
||||
|
||||
def _option_symlink(self):
|
||||
subconfig = self._subconfig.config_bag.context._get(self._subconfig,
|
||||
need_help=True,
|
||||
validate_properties=self._validate_properties,
|
||||
)
|
||||
return TiramisuOption(subconfig.path,
|
||||
subconfig.index,
|
||||
self._config_bag,
|
||||
subconfig=subconfig,
|
||||
)
|
||||
#
|
||||
#
|
||||
#class TiramisuOptionOption(CommonTiramisuOption):
|
||||
# """Manage option"""
|
||||
# _validate_properties = False
|
||||
# def __call__(self,
|
||||
# name: str,
|
||||
# index: Optional[int]=None,
|
||||
# ) -> 'TiramisuOption':
|
||||
# """Select an option by path"""
|
||||
# return TiramisuOption(self._path + '.' + name,
|
||||
# index,
|
||||
# self._config_bag,
|
||||
# )
|
||||
|
||||
|
||||
class TiramisuOptionOwner(CommonTiramisuOption):
|
||||
#FIXME optiondescription must not have Owner!
|
||||
"""Manage option's owner"""
|
||||
_validate_properties=True
|
||||
|
||||
@option_type(['symlink', 'option', 'with_index'])
|
||||
def get(self):
|
||||
|
@ -410,17 +445,22 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
|||
"""Manage option's property"""
|
||||
_validate_properties = False
|
||||
|
||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||
@option_type(['option', 'optiondescription', 'with_index', 'symlink'])
|
||||
def get(self,
|
||||
only_raises=False,
|
||||
uncalculated=False,
|
||||
only_raises: bool=False,
|
||||
apply_requires: bool=True,
|
||||
uncalculated: bool=False,
|
||||
):
|
||||
"""Get properties for an option"""
|
||||
settings = self._config_bag.context.get_settings()
|
||||
if not only_raises:
|
||||
return settings.getproperties(self._subconfig)
|
||||
return settings.getproperties(self._subconfig,
|
||||
uncalculated=uncalculated,
|
||||
apply_requires=apply_requires,
|
||||
)
|
||||
return settings.calc_raises_properties(self._subconfig,
|
||||
uncalculated=uncalculated,
|
||||
apply_requires=apply_requires,
|
||||
)
|
||||
|
||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||
|
@ -430,9 +470,8 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
|||
raise ConfigError(_('cannot add this property: "{0}"').format(
|
||||
' '.join(prop)))
|
||||
settings = self._config_bag.context.get_settings()
|
||||
props = settings.get_stored_properties(self._path,
|
||||
props = settings.get_personalize_properties(self._path,
|
||||
self._index,
|
||||
self._subconfig.option.impl_getproperties(),
|
||||
)
|
||||
settings.setproperties(self._subconfig,
|
||||
props | {prop},
|
||||
|
@ -444,7 +483,19 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
|||
):
|
||||
"""Remove new property for an option"""
|
||||
settings = self._config_bag.context.get_settings()
|
||||
props = settings.getproperties(self._subconfig)
|
||||
props = settings.get_personalize_properties(self._path,
|
||||
self._index,
|
||||
)
|
||||
|
||||
if prop not in props:
|
||||
if prop in settings.getproperties(self._subconfig):
|
||||
msg = f'cannot remove option\'s property "{prop}", use permissive instead'
|
||||
else:
|
||||
msg = f'cannot find "{prop}"'
|
||||
msg += f' in option "{self._path}"'
|
||||
if self._index is not None:
|
||||
msg += f' at index "{self._index}"'
|
||||
raise ConfigError(msg)
|
||||
settings.setproperties(self._subconfig,
|
||||
props - {prop},
|
||||
)
|
||||
|
@ -457,6 +508,7 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
|||
|
||||
class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||
"""Manage option's permissive"""
|
||||
_validate_properties = False
|
||||
|
||||
@option_type(['option', 'optiondescription', 'symlink', 'with_or_without_index'])
|
||||
def get(self):
|
||||
|
@ -464,15 +516,27 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
|||
return self._config_bag.context.get_settings().getpermissives(self._subconfig)
|
||||
|
||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||
def set(self,
|
||||
permissives,
|
||||
def add(self,
|
||||
permissive,
|
||||
):
|
||||
"""Set permissives value"""
|
||||
permissives = self._config_bag.context.get_settings().getpermissives(self._subconfig)
|
||||
self._config_bag.context.get_settings().setpermissives(self._subconfig,
|
||||
permissives=permissives,
|
||||
frozenset(permissives | {permissive}),
|
||||
)
|
||||
|
||||
@option_type(['option', 'optiondescription', 'with_index'])
|
||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||
def remove(self, permissive):
|
||||
"""Remove a config property"""
|
||||
permissives = set(self.get())
|
||||
if permissive not in permissives:
|
||||
msg = f'cannot find "{permissive}"'
|
||||
raise ConfigError(msg)
|
||||
self._config_bag.context.get_settings().setpermissives(self._subconfig,
|
||||
frozenset(permissives - {permissive}),
|
||||
)
|
||||
|
||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||
def reset(self):
|
||||
"""Reset all personalised permissive"""
|
||||
self._config_bag.context.get_settings().reset_permissives(self._subconfig)
|
||||
|
@ -480,6 +544,7 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
|||
|
||||
class TiramisuOptionInformation(CommonTiramisuOption):
|
||||
"""Manage option's informations"""
|
||||
_validate_properties = False
|
||||
|
||||
@option_type(['option', 'optiondescription', 'with_or_without_index', 'symlink'])
|
||||
def get(self,
|
||||
|
@ -487,13 +552,10 @@ class TiramisuOptionInformation(CommonTiramisuOption):
|
|||
default=undefined,
|
||||
) -> Any:
|
||||
"""Get information"""
|
||||
try:
|
||||
return self._config_bag.context.get_values().get_information(self._subconfig,
|
||||
name,
|
||||
undefined,
|
||||
default,
|
||||
)
|
||||
except ValueError:
|
||||
return self._subconfig.option.impl_get_information(name, default)
|
||||
|
||||
@option_type(['option', 'optiondescription'])
|
||||
def set(self,
|
||||
|
@ -506,7 +568,7 @@ class TiramisuOptionInformation(CommonTiramisuOption):
|
|||
)
|
||||
|
||||
@option_type(['option', 'optiondescription'])
|
||||
def reset(self,
|
||||
def remove(self,
|
||||
key: str,
|
||||
) -> None:
|
||||
"""Remove information"""
|
||||
|
@ -517,7 +579,7 @@ class TiramisuOptionInformation(CommonTiramisuOption):
|
|||
@option_type(['option', 'optiondescription', 'with_or_without_index', 'symlink'])
|
||||
def list(self) -> list:
|
||||
"""List information's keys"""
|
||||
lst1 = set(self._subconfig.option.impl_list_information())
|
||||
lst1 = set(self._subconfig.option._list_information())
|
||||
lst2 = set(self._config_bag.context.get_values().list_information(self._path))
|
||||
return lst1 | lst2
|
||||
|
||||
|
@ -584,9 +646,10 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
|
|||
if not isinstance(value, Calculation) and option.impl_is_leader() and \
|
||||
len(value) < self._subconfig.parent.get_length_leadership():
|
||||
raise LeadershipError(_('cannot reduce length of the leader "{}"'
|
||||
'').format(option.impl_get_display_name()))
|
||||
return self._subconfig.config_bag.context.set_value(self._subconfig,
|
||||
value,
|
||||
'').format(option.impl_get_display_name(self._subconfig)))
|
||||
values = self._config_bag.context.get_values()
|
||||
return values.set_value(self._subconfig,
|
||||
value
|
||||
)
|
||||
|
||||
@option_type(['group', 'option', 'with_index'])
|
||||
|
@ -624,7 +687,7 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
|
|||
return False
|
||||
return True
|
||||
|
||||
@option_type(['choice', 'with_or_without_index'])
|
||||
@option_type(['choice', 'with_index'])
|
||||
def list(self):
|
||||
"""All values available for a ChoiceOption"""
|
||||
return self._subconfig.option.impl_get_values(self._subconfig)
|
||||
|
@ -640,7 +703,7 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
|
|||
|
||||
@option_type(['leader', 'follower', 'with_or_without_index'])
|
||||
def len(self):
|
||||
"""Length for a follower option"""
|
||||
"""Length for a leadership"""
|
||||
return self._subconfig.parent.get_length_leadership()
|
||||
|
||||
|
||||
|
@ -674,18 +737,6 @@ class TiramisuConfig(TiramisuHelp, _TiramisuOptionWalk):
|
|||
if isinstance(config, KernelGroupConfig):
|
||||
return GroupConfig(config)
|
||||
|
||||
def _reset_config_properties(self):
|
||||
config = self._config_bag.context
|
||||
settings = config.get_settings()
|
||||
properties = settings.get_context_properties(config.properties_cache)
|
||||
permissives = settings.get_context_permissives()
|
||||
self._config_bag.properties = properties
|
||||
self._config_bag.permissives = permissives
|
||||
if self._orig_config_bags:
|
||||
for config_bag in self._orig_config_bags:
|
||||
config_bag.properties = properties
|
||||
config_bag.permissives = permissives
|
||||
|
||||
def name(self):
|
||||
"""get the name"""
|
||||
return self._config_bag.context.impl_getname()
|
||||
|
@ -714,7 +765,7 @@ class TiramisuOption(CommonTiramisu,
|
|||
_registers(self._registers, 'TiramisuOption')
|
||||
|
||||
def __repr__(self):
|
||||
msg = f'<TiramisuOption path={self._path}'
|
||||
msg = f'<TiramisuOption path="{self._path}"'
|
||||
if self._index is not None:
|
||||
msg += f', index={self._index}'
|
||||
msg += '>'
|
||||
|
@ -726,7 +777,7 @@ class TiramisuOption(CommonTiramisu,
|
|||
self._index,
|
||||
self._config_bag,
|
||||
)
|
||||
raise ConfigError(_(f'please specify a valid sub function ({self.__class__.__name__}.{subfunc})'))
|
||||
raise ConfigError(_(f'please specify a valid sub function ({self.__class__.__name__}.{subfunc}) for {self._path}'))
|
||||
#
|
||||
# @option_type('optiondescription')
|
||||
# def find(self,
|
||||
|
@ -806,14 +857,13 @@ class TiramisuContextInformation(TiramisuConfig):
|
|||
default=undefined,
|
||||
):
|
||||
"""Get an information"""
|
||||
values = self._config_bag.context.get_values()
|
||||
try:
|
||||
return values.get_information(None,
|
||||
context = self._config_bag.context
|
||||
values = context.get_values()
|
||||
subconfig = context.get_root(self._config_bag)
|
||||
return values.get_information(subconfig,
|
||||
name,
|
||||
undefined,
|
||||
default,
|
||||
)
|
||||
except ValueError:
|
||||
return self._config_bag.context.get_description().impl_get_information(name, default)
|
||||
|
||||
def set(self,
|
||||
name,
|
||||
|
@ -825,7 +875,7 @@ class TiramisuContextInformation(TiramisuConfig):
|
|||
value,
|
||||
)
|
||||
|
||||
def reset(self,
|
||||
def remove(self,
|
||||
name,
|
||||
):
|
||||
"""Remove an information"""
|
||||
|
@ -833,7 +883,7 @@ class TiramisuContextInformation(TiramisuConfig):
|
|||
|
||||
def list(self):
|
||||
"""List information's keys"""
|
||||
lst1 = set(self._config_bag.context.get_description().impl_list_information())
|
||||
lst1 = set(self._config_bag.context.get_description()._list_information())
|
||||
lst2 = set(self._config_bag.context.impl_list_information())
|
||||
return lst1 | lst2
|
||||
|
||||
|
@ -946,30 +996,54 @@ class TiramisuContextOwner(TiramisuConfig):
|
|||
values.set_context_owner(obj_owner)
|
||||
|
||||
|
||||
class TiramisuContextProperty(TiramisuConfig):
|
||||
"""Manage config properties"""
|
||||
def read_only(self):
|
||||
"""Set config to read only mode"""
|
||||
old_props = self._config_bag.properties
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.read_only(self._config_bag)
|
||||
self._reset_config_properties()
|
||||
# if 'force_store_value' not in old_props and \
|
||||
# 'force_store_value' in self._config_bag.properties:
|
||||
# self._force_store_value()
|
||||
|
||||
def read_write(self):
|
||||
"""Set config to read and write mode"""
|
||||
old_props = self._config_bag.properties
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.read_write(self._config_bag)
|
||||
class PropertyPermissive:
|
||||
def _set_default_permissive(self,
|
||||
settings,
|
||||
):
|
||||
or_properties = settings.rw_append - settings.ro_append - SPECIAL_PROPERTIES
|
||||
permissives = frozenset(settings.get_context_permissives() | or_properties)
|
||||
settings.set_context_permissives(permissives)
|
||||
self._reset_config_properties()
|
||||
# if 'force_store_value' not in old_props and \
|
||||
# 'force_store_value' in self._config_bag.properties:
|
||||
# self._force_store_value()
|
||||
|
||||
def _reset_config_properties(self,
|
||||
settings,
|
||||
):
|
||||
properties = settings.get_context_properties()
|
||||
permissives = settings.get_context_permissives()
|
||||
self._config_bag.properties = properties
|
||||
self._config_bag.permissives = permissives
|
||||
if self._orig_config_bags:
|
||||
for config_bag in self._orig_config_bags:
|
||||
config_bag.properties = properties
|
||||
config_bag.permissives = permissives
|
||||
|
||||
|
||||
class TiramisuContextProperty(TiramisuConfig, PropertyPermissive):
|
||||
"""Manage config properties"""
|
||||
def read_only(self):
|
||||
"""Set config to read only mode"""
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context property in unrestraint mode')
|
||||
old_props = self._config_bag.properties
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.read_only(self._config_bag)
|
||||
self._set_default_permissive(settings)
|
||||
self._reset_config_properties(settings)
|
||||
if 'force_store_value' not in old_props and \
|
||||
'force_store_value' in self._config_bag.properties:
|
||||
self._force_store_value()
|
||||
|
||||
def read_write(self):
|
||||
"""Set config to read and write mode"""
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context property in unrestraint mode')
|
||||
old_props = self._config_bag.properties
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.read_write(self._config_bag)
|
||||
self._set_default_permissive(settings)
|
||||
self._reset_config_properties(settings)
|
||||
if 'force_store_value' not in old_props and \
|
||||
'force_store_value' in self._config_bag.properties:
|
||||
self._force_store_value()
|
||||
|
||||
def add(self, prop):
|
||||
"""Add a config property"""
|
||||
|
@ -981,35 +1055,47 @@ class TiramisuContextProperty(TiramisuConfig):
|
|||
def remove(self, prop):
|
||||
"""Remove a config property"""
|
||||
props = set(self.get())
|
||||
if prop in props:
|
||||
if prop not in props:
|
||||
msg = f'cannot find "{prop}"'
|
||||
raise ConfigError(msg)
|
||||
props.remove(prop)
|
||||
self._set(frozenset(props))
|
||||
|
||||
def get(self):
|
||||
def get(self,
|
||||
only_raises: bool=False,
|
||||
apply_requires: bool=True,
|
||||
uncalculated: bool=False,
|
||||
) -> Set:
|
||||
"""Get all config properties"""
|
||||
if only_raises:
|
||||
return set()
|
||||
return self._config_bag.properties
|
||||
|
||||
def _set(self,
|
||||
props,
|
||||
):
|
||||
"""Personalise config properties"""
|
||||
# if 'force_store_value' in props:
|
||||
# force_store_value = 'force_store_value' not in self._config_bag.properties
|
||||
# else:
|
||||
# force_store_value = False
|
||||
context = self._config_bag.context
|
||||
context.get_settings().set_context_properties(props,
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context property in unrestraint mode')
|
||||
if 'force_store_value' in props:
|
||||
force_store_value = 'force_store_value' not in self._config_bag.properties
|
||||
else:
|
||||
force_store_value = False
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.set_context_properties(props,
|
||||
self._config_bag.context,
|
||||
)
|
||||
self._reset_config_properties()
|
||||
# if force_store_value:
|
||||
# self._force_store_value()
|
||||
self._reset_config_properties(settings)
|
||||
if force_store_value:
|
||||
self._force_store_value()
|
||||
|
||||
def reset(self):
|
||||
"""Remove config properties"""
|
||||
context = self._config_bag.context
|
||||
context.get_settings().reset(self._config_bag)
|
||||
self._reset_config_properties()
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context property in unrestraint mode')
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.reset(self._config_bag)
|
||||
self._reset_config_properties(settings)
|
||||
|
||||
def exportation(self):
|
||||
"""Export config properties"""
|
||||
|
@ -1017,30 +1103,31 @@ class TiramisuContextProperty(TiramisuConfig):
|
|||
|
||||
def importation(self, properties):
|
||||
"""Import config properties"""
|
||||
# if 'force_store_value' in properties.get(None, {}).get(None, []):
|
||||
# force_store_value = 'force_store_value' not in self._config_bag.properties
|
||||
# else:
|
||||
# force_store_value = False
|
||||
self._config_bag.context.get_settings()._properties = deepcopy(properties)
|
||||
self._config_bag.context.reset_cache(None, None)
|
||||
self._reset_config_properties()
|
||||
# if force_store_value:
|
||||
# self._force_store_value()
|
||||
#
|
||||
# def _force_store_value(self):
|
||||
# descr = self._config_bag.context.get_description()
|
||||
# descr.impl_build_force_store_values(self._config_bag)
|
||||
if 'force_store_value' in properties.get(None, {}).get(None, []):
|
||||
force_store_value = 'force_store_value' not in self._config_bag.properties
|
||||
else:
|
||||
force_store_value = False
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context property in unrestraint mode')
|
||||
context = self._config_bag.context
|
||||
settings = context.get_settings()
|
||||
settings._properties = deepcopy(properties)
|
||||
context.reset_cache(None, None)
|
||||
self._reset_config_properties(settings)
|
||||
if force_store_value:
|
||||
self._force_store_value()
|
||||
|
||||
def _force_store_value(self):
|
||||
descr = self._config_bag.context.get_description()
|
||||
descr.impl_build_force_store_values(self._config_bag)
|
||||
|
||||
def setdefault(self,
|
||||
properties: Set[str],
|
||||
type: Optional[str]=None,
|
||||
type: Optional[str],
|
||||
when: Optional[str]=None) -> None:
|
||||
if not isinstance(properties, frozenset):
|
||||
raise TypeError(_('properties must be a frozenset'))
|
||||
setting = self._config_bag.context.get_settings()
|
||||
if type is None and when is None:
|
||||
setting.default_properties = properties
|
||||
else:
|
||||
if when not in ['append', 'remove']:
|
||||
raise ValueError(_('unknown when {} (must be in append or remove)').format(when))
|
||||
if type == 'read_only':
|
||||
|
@ -1062,7 +1149,7 @@ class TiramisuContextProperty(TiramisuConfig):
|
|||
) -> Set[str]:
|
||||
setting = self._config_bag.context.get_settings()
|
||||
if type is None and when is None:
|
||||
return setting.default_properties
|
||||
return DEFAULT_PROPERTIES
|
||||
if type == 'current':
|
||||
return setting.get_context_properties(self._config_bag.context.properties_cache)
|
||||
if when not in ['append', 'remove']:
|
||||
|
@ -1078,7 +1165,7 @@ class TiramisuContextProperty(TiramisuConfig):
|
|||
raise ValueError(_('unknown type {}').format(type))
|
||||
|
||||
|
||||
class TiramisuContextPermissive(TiramisuConfig):
|
||||
class TiramisuContextPermissive(TiramisuConfig, PropertyPermissive):
|
||||
"""Manage config permissives"""
|
||||
def get(self):
|
||||
"""Get config permissives"""
|
||||
|
@ -1091,8 +1178,11 @@ class TiramisuContextPermissive(TiramisuConfig):
|
|||
permissives,
|
||||
):
|
||||
"""Set config permissives"""
|
||||
self._config_bag.context.get_settings().set_context_permissives(permissives)
|
||||
self._reset_config_properties()
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context permissive in unrestraint mode')
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.set_context_permissives(permissives)
|
||||
self._reset_config_properties(settings)
|
||||
|
||||
def exportation(self):
|
||||
"""Export config permissives"""
|
||||
|
@ -1100,32 +1190,39 @@ class TiramisuContextPermissive(TiramisuConfig):
|
|||
|
||||
def importation(self, permissives):
|
||||
"""Import config permissives"""
|
||||
settings = self._config_bag.context.get_settings()
|
||||
self._config_bag.context.get_settings()._permissives = deepcopy(permissives)
|
||||
self._config_bag.context.reset_cache(None,
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context permissive in unrestraint mode')
|
||||
context = self._config_bag.context
|
||||
settings = context.get_settings()
|
||||
settings._permissives = deepcopy(permissives)
|
||||
context.reset_cache(None,
|
||||
None,
|
||||
)
|
||||
self._reset_config_properties()
|
||||
self._reset_config_properties(settings)
|
||||
|
||||
def reset(self):
|
||||
"""Remove config permissives"""
|
||||
context = self._config_bag.context
|
||||
settings = context.get_settings()
|
||||
if self._config_bag.is_unrestraint:
|
||||
raise ConfigError('cannot change context permissive in unrestraint mode')
|
||||
settings = self._config_bag.context.get_settings()
|
||||
settings.reset_permissives(self._config_bag)
|
||||
self._reset_config_properties()
|
||||
self._set_default_permissive(settings)
|
||||
self._reset_config_properties(settings)
|
||||
|
||||
def add(self, prop):
|
||||
def add(self, permissive):
|
||||
"""Add a config permissive"""
|
||||
props = set(self._get())
|
||||
props.add(prop)
|
||||
self._set(frozenset(props))
|
||||
permissives = set(self._get())
|
||||
permissives.add(permissive)
|
||||
self._set(frozenset(permissives))
|
||||
|
||||
def remove(self, prop):
|
||||
def remove(self, permissive):
|
||||
"""Remove a config permissive"""
|
||||
props = set(self._get())
|
||||
if prop in props:
|
||||
props.remove(prop)
|
||||
self._set(frozenset(props))
|
||||
permissives = set(self._get())
|
||||
if permissive not in permissives:
|
||||
msg = f'cannot find "{permissive}"'
|
||||
raise ConfigError(msg)
|
||||
permissives.remove(permissive)
|
||||
self._set(frozenset(permissives))
|
||||
|
||||
|
||||
class TiramisuContextOption(TiramisuConfig, _TiramisuOptionWalk):
|
||||
|
@ -1134,31 +1231,49 @@ class TiramisuContextOption(TiramisuConfig, _TiramisuOptionWalk):
|
|||
**kwargs) -> None:
|
||||
self._tiramisu_dict = None
|
||||
super().__init__(*args, **kwargs)
|
||||
#
|
||||
# def find(self,
|
||||
# name,
|
||||
# value=undefined,
|
||||
# type=None,
|
||||
# first=False):
|
||||
# """Find an or a list of options"""
|
||||
# options = []
|
||||
# option_bag = OptionBag(self._config_bag.context.get_description(),
|
||||
# None,
|
||||
# self._config_bag,
|
||||
# )
|
||||
# for path in self._config_bag.context.find(option_bag,
|
||||
# byname=name,
|
||||
# byvalue=value,
|
||||
# bytype=type,
|
||||
# ):
|
||||
# option = TiramisuOption(path,
|
||||
# None,
|
||||
# self._config_bag,
|
||||
# )
|
||||
# if first:
|
||||
# return option
|
||||
# options.append(option)
|
||||
# return options
|
||||
|
||||
def get(self):
|
||||
"""Get Tiramisu option"""
|
||||
return None
|
||||
|
||||
def isleadership(self):
|
||||
"""Test if option is a leader or a follower"""
|
||||
return False
|
||||
|
||||
def doc(self):
|
||||
"""Get option document"""
|
||||
return self._config_bag.context.get_description().impl_get_display_name(None)
|
||||
|
||||
def description(self):
|
||||
"""Get option description"""
|
||||
return self._config_bag.context.get_description()._get_information(None, 'doc', None)
|
||||
|
||||
def name(self):
|
||||
"""Get option name"""
|
||||
return None
|
||||
|
||||
def path(self,
|
||||
):
|
||||
"""Get option path"""
|
||||
return None
|
||||
|
||||
def has_dependency(self,
|
||||
self_is_dep=True,
|
||||
) -> bool:
|
||||
"""Test if option has dependency"""
|
||||
return False
|
||||
|
||||
def isoptiondescription(self):
|
||||
"""Test if option is an optiondescription"""
|
||||
return True
|
||||
|
||||
def isdynamic(self):
|
||||
"""Test if option is a dynamic optiondescription"""
|
||||
return False
|
||||
|
||||
def type(self):
|
||||
"""Get de option type"""
|
||||
return 'optiondescription'
|
||||
|
||||
def list(self,
|
||||
validate_properties: bool=True,
|
||||
|
@ -1362,12 +1477,17 @@ class TiramisuAPI(TiramisuHelp):
|
|||
if not self._registers:
|
||||
_registers(self._registers, 'TiramisuContext')
|
||||
|
||||
def __getattr__(self, subfunc: str) -> Any:
|
||||
if subfunc == 'option':
|
||||
config_bag = self._config_bag
|
||||
return TiramisuDispatcherOption(config_bag,
|
||||
self._orig_config_bags,
|
||||
def option(self,
|
||||
path: str,
|
||||
index: Optional[int]=None,
|
||||
) -> TiramisuOption:
|
||||
"""Select an option by path"""
|
||||
return TiramisuOption(path,
|
||||
index,
|
||||
self._config_bag,
|
||||
)
|
||||
|
||||
def __getattr__(self, subfunc: str) -> Any:
|
||||
if subfunc in ['forcepermissive', 'unrestraint', 'nowarnings']:
|
||||
if self._orig_config_bags:
|
||||
msg = _('do not use unrestraint, nowarnings or forcepermissive together')
|
||||
|
@ -1379,7 +1499,7 @@ class TiramisuAPI(TiramisuHelp):
|
|||
config_bag.nowarnings()
|
||||
else:
|
||||
config_bag.set_permissive()
|
||||
return TiramisuAPI(config_bag, [self._config_bag])
|
||||
return ConfigProp(config_bag, [self._config_bag])
|
||||
if subfunc == 'config':
|
||||
config_type = self._config_bag.context.impl_type
|
||||
if config_type == 'group':
|
||||
|
@ -1404,20 +1524,12 @@ class TiramisuAPI(TiramisuHelp):
|
|||
['unrestraint', 'forcepermissive', 'nowarnings', 'config']
|
||||
|
||||
|
||||
class TiramisuDispatcherOption(TiramisuContextOption):
|
||||
"""Select an option"""
|
||||
def __call__(self,
|
||||
path: str,
|
||||
index: Optional[int]=None,
|
||||
) -> TiramisuOption:
|
||||
"""Select an option by path"""
|
||||
return TiramisuOption(path,
|
||||
index,
|
||||
self._config_bag,
|
||||
)
|
||||
class ConfigProp(TiramisuAPI, TiramisuContextOption):
|
||||
def __repr__(self):
|
||||
return f'<Config path=None>'
|
||||
|
||||
|
||||
class Config(TiramisuAPI):
|
||||
class Config(TiramisuAPI, TiramisuContextOption):
|
||||
"""Root config object that enables us to handle the configuration options"""
|
||||
def __init__(self,
|
||||
descr: OptionDescription,
|
||||
|
@ -1432,7 +1544,7 @@ class Config(TiramisuAPI):
|
|||
display_name=display_name,
|
||||
)
|
||||
settings = config.get_settings()
|
||||
properties = settings.get_context_properties(config.properties_cache)
|
||||
properties = settings.get_context_properties()
|
||||
permissives = settings.get_context_permissives()
|
||||
config_bag = ConfigBag(config,
|
||||
properties=properties,
|
||||
|
@ -1448,6 +1560,9 @@ class Config(TiramisuAPI):
|
|||
except ConfigError:
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Config path=None>'
|
||||
|
||||
|
||||
class MetaConfig(TiramisuAPI):
|
||||
"""MetaConfig object that enables us to handle the sub configuration's options
|
||||
|
@ -1478,7 +1593,7 @@ class MetaConfig(TiramisuAPI):
|
|||
display_name=display_name,
|
||||
)
|
||||
settings = config.get_settings()
|
||||
properties = settings.get_context_properties(config.properties_cache)
|
||||
properties = settings.get_context_properties()
|
||||
permissives = settings.get_context_permissives()
|
||||
config_bag = ConfigBag(config,
|
||||
properties=properties,
|
||||
|
|
|
@ -19,16 +19,47 @@
|
|||
# ____________________________________________________________
|
||||
"enables us to carry out a calculation and return an option's value"
|
||||
from typing import Any, Optional, Union, Callable, Dict, List
|
||||
from os.path import commonprefix
|
||||
from itertools import chain
|
||||
import weakref
|
||||
|
||||
from .error import PropertiesOptionError, ConfigError, LeadershipError, ValueWarning
|
||||
from .i18n import _
|
||||
from .setting import undefined, ConfigBag, Undefined
|
||||
from .setting import undefined, ConfigBag
|
||||
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:
|
||||
__slots__ = ('args', 'kwargs')
|
||||
def __init__(self, args=None, kwargs=None, **kwgs):
|
||||
|
@ -85,13 +116,11 @@ class ParamOption(Param):
|
|||
|
||||
class ParamDynOption(ParamOption):
|
||||
__slots__ = ('suffixes',
|
||||
'dynoptiondescription',
|
||||
'optional',
|
||||
)
|
||||
def __init__(self,
|
||||
option: 'Option',
|
||||
suffixes: list[str],
|
||||
dynoptiondescription: 'DynOptionDescription'=None,
|
||||
notraisepropertyerror: bool=False,
|
||||
raisepropertyerror: bool=False,
|
||||
optional: bool=False,
|
||||
|
@ -101,7 +130,6 @@ class ParamDynOption(ParamOption):
|
|||
raisepropertyerror,
|
||||
)
|
||||
self.suffixes = suffixes
|
||||
self.dynoptiondescription = dynoptiondescription
|
||||
self.optional = optional
|
||||
|
||||
|
||||
|
@ -125,6 +153,7 @@ class ParamInformation(Param):
|
|||
__slots__ = ('information_name',
|
||||
'default_value',
|
||||
'option',
|
||||
'self_option',
|
||||
)
|
||||
def __init__(self,
|
||||
information_name: str,
|
||||
|
@ -133,7 +162,22 @@ class ParamInformation(Param):
|
|||
) -> None:
|
||||
self.information_name = information_name
|
||||
self.default_value = default_value
|
||||
self.self_option = None
|
||||
self.option = None
|
||||
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():
|
||||
raise ValueError(_('option in ParamInformation cannot be a symlinkoption'))
|
||||
if option.impl_is_follower():
|
||||
|
@ -141,10 +185,27 @@ class ParamInformation(Param):
|
|||
if option.impl_is_dynsymlinkoption():
|
||||
raise ValueError(_('option in ParamInformation cannot be a dynamic 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):
|
||||
__slots__ = tuple()
|
||||
def __init__(self,
|
||||
information_name: str,
|
||||
default_value: Any=undefined,
|
||||
) -> None:
|
||||
return super().__init__(information_name,
|
||||
default_value,
|
||||
)
|
||||
|
||||
|
||||
class ParamIndex(Param):
|
||||
|
@ -152,7 +213,11 @@ class ParamIndex(Param):
|
|||
|
||||
|
||||
class ParamSuffix(Param):
|
||||
__slots__ = tuple()
|
||||
__slots__ = ('suffix_index',)
|
||||
def __init__(self,
|
||||
suffix_index: int=-1,
|
||||
) -> None:
|
||||
self.suffix_index = suffix_index
|
||||
|
||||
|
||||
class Calculation:
|
||||
|
@ -190,6 +255,7 @@ class Calculation:
|
|||
allow_value_error: bool=False,
|
||||
force_value_warning: bool=False,
|
||||
for_settings: bool=False,
|
||||
validate_properties: bool=True,
|
||||
) -> Any:
|
||||
return carry_out_calculation(subconfig,
|
||||
callback=self.function,
|
||||
|
@ -200,6 +266,7 @@ class Calculation:
|
|||
allow_value_error=allow_value_error,
|
||||
force_value_warning=force_value_warning,
|
||||
for_settings=for_settings,
|
||||
validate_properties=validate_properties,
|
||||
)
|
||||
|
||||
def help(self,
|
||||
|
@ -229,6 +296,7 @@ def manager_callback(callback: Callable,
|
|||
orig_value,
|
||||
config_bag: ConfigBag,
|
||||
for_settings: bool,
|
||||
validate_properties: bool,
|
||||
) -> Any:
|
||||
"""replace Param by true value"""
|
||||
option = subconfig.option
|
||||
|
@ -297,18 +365,18 @@ def manager_callback(callback: Callable,
|
|||
return value
|
||||
|
||||
def _get_value(param: Params,
|
||||
subconfig: SubConfig,
|
||||
subconfig: 'SubConfig',
|
||||
) -> Any:
|
||||
try:
|
||||
# get value
|
||||
value = config_bag.context.get_value(subconfig)
|
||||
except PropertiesOptionError as err:
|
||||
# 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 ConfigError(_('unable to carry out a calculation for "{}", {}').format(display_name, err)) from 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
|
||||
except AttributeError as err:
|
||||
if isinstance(param, ParamDynOption) and param.optional:
|
||||
|
@ -317,7 +385,7 @@ def manager_callback(callback: Callable,
|
|||
['configerror'],
|
||||
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
|
||||
return value
|
||||
|
||||
|
@ -341,7 +409,7 @@ def manager_callback(callback: Callable,
|
|||
config_bag.remove_validation()
|
||||
# root = config_bag.context.get_root(config_bag)
|
||||
try:
|
||||
subconfig = config_bag.context.get_sub_config(config_bag,
|
||||
subsubconfig = config_bag.context.get_sub_config(config_bag,
|
||||
opt.impl_getpath(),
|
||||
index_,
|
||||
validate_properties=not self_calc,
|
||||
|
@ -351,10 +419,10 @@ def manager_callback(callback: Callable,
|
|||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||
if param.notraisepropertyerror or param.raisepropertyerror:
|
||||
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
|
||||
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:
|
||||
if isinstance(param, ParamDynOption) and param.optional:
|
||||
# cannot acces, simulate a propertyerror
|
||||
|
@ -362,19 +430,9 @@ def manager_callback(callback: Callable,
|
|||
['configerror'],
|
||||
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
|
||||
return subconfig
|
||||
|
||||
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
|
||||
return subsubconfig
|
||||
|
||||
if isinstance(param, ParamValue):
|
||||
return param.value
|
||||
|
@ -383,6 +441,14 @@ def manager_callback(callback: Callable,
|
|||
if isinstance(param, ParamSelfInformation):
|
||||
isubconfig = subconfig
|
||||
elif param.option:
|
||||
if param.option.issubdyn():
|
||||
search_option = param.option
|
||||
isubconfig = subconfig.get_common_child(search_option,
|
||||
true_path=subconfig.path,
|
||||
)
|
||||
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,
|
||||
|
@ -391,14 +457,14 @@ def manager_callback(callback: Callable,
|
|||
#properties=properties,
|
||||
)
|
||||
else:
|
||||
isubconfig = None
|
||||
isubconfig = config_bag.context.get_root(config_bag)
|
||||
try:
|
||||
return config_bag.context.get_values().get_information(isubconfig,
|
||||
param.information_name,
|
||||
param.default_value,
|
||||
)
|
||||
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
|
||||
|
||||
if isinstance(param, ParamIndex):
|
||||
|
@ -406,9 +472,9 @@ def manager_callback(callback: Callable,
|
|||
|
||||
if isinstance(param, ParamSuffix):
|
||||
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'))
|
||||
return subconfig.suffixes[-1]
|
||||
return subconfig.suffixes[param.suffix_index]
|
||||
|
||||
if isinstance(param, ParamSelfOption):
|
||||
value = calc_self(param,
|
||||
|
@ -418,45 +484,13 @@ def manager_callback(callback: Callable,
|
|||
)
|
||||
if callback.__name__ not in FUNCTION_WAITING_FOR_DICT:
|
||||
return value
|
||||
return {'name': option.impl_get_display_name(),
|
||||
return {'name': option.impl_get_display_name(subconfig),
|
||||
'value': value,
|
||||
}
|
||||
|
||||
if isinstance(param, ParamOption):
|
||||
callbk_option = param.option
|
||||
callbk_options = None
|
||||
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)
|
||||
config_bag = subconfig.config_bag
|
||||
if index is not None and callbk_option.impl_get_leadership() and \
|
||||
callbk_option.impl_get_leadership().in_same_leadership(option):
|
||||
if not callbk_option.impl_is_follower():
|
||||
|
@ -470,7 +504,69 @@ def manager_callback(callback: Callable,
|
|||
else:
|
||||
index_ = None
|
||||
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,
|
||||
callbk_option,
|
||||
param,
|
||||
|
@ -479,13 +575,7 @@ def manager_callback(callback: Callable,
|
|||
#properties=properties,
|
||||
)
|
||||
]
|
||||
# callbk_options = [callbk_option]
|
||||
values = None
|
||||
else:
|
||||
values = []
|
||||
#FIXME
|
||||
values = None
|
||||
# for callbk_option in callbk_options:
|
||||
for subconfig in subconfigs:
|
||||
callbk_option = subconfig.option
|
||||
value = get_value(config_bag,
|
||||
|
@ -501,7 +591,7 @@ def manager_callback(callback: Callable,
|
|||
value = values
|
||||
if callback.__name__ not in FUNCTION_WAITING_FOR_DICT:
|
||||
return value
|
||||
return {'name': callbk_option.impl_get_display_name(),
|
||||
return {'name': callbk_option.impl_get_display_name(subconfig),
|
||||
'value': value}
|
||||
|
||||
|
||||
|
@ -514,6 +604,8 @@ def carry_out_calculation(subconfig: 'SubConfig',
|
|||
allow_value_error: bool=False,
|
||||
force_value_warning: bool=False,
|
||||
for_settings: bool=False,
|
||||
*,
|
||||
validate_properties: bool=True,
|
||||
):
|
||||
"""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 ''."""
|
||||
option = subconfig.option
|
||||
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):
|
||||
return ((None, i) for i in iterator)
|
||||
args = []
|
||||
|
@ -548,20 +640,21 @@ def carry_out_calculation(subconfig: 'SubConfig',
|
|||
orig_value,
|
||||
config_bag,
|
||||
for_settings,
|
||||
validate_properties,
|
||||
)
|
||||
if key is None:
|
||||
args.append(value)
|
||||
else:
|
||||
kwargs[key] = value
|
||||
except PropertiesOptionError as err:
|
||||
if param.raisepropertyerror:
|
||||
if isinstance(param, ParamSelfOption) or param.raisepropertyerror:
|
||||
raise err
|
||||
if callback.__name__ in FUNCTION_WAITING_FOR_DICT:
|
||||
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:
|
||||
kwargs[key] = {'propertyerror': str(err), 'name': option.impl_get_display_name()}
|
||||
ret = calculate(option,
|
||||
kwargs[key] = {'propertyerror': str(err), 'name': option.impl_get_display_name(subconfig)}
|
||||
ret = calculate(subconfig,
|
||||
callback,
|
||||
allow_value_error,
|
||||
force_value_warning,
|
||||
|
@ -579,17 +672,17 @@ def carry_out_calculation(subconfig: 'SubConfig',
|
|||
args,
|
||||
kwargs,
|
||||
ret,
|
||||
option.impl_get_display_name()))
|
||||
option.impl_get_display_name(subconfig)))
|
||||
else:
|
||||
raise LeadershipError(_('the "{}" function must not return a list ("{}") '
|
||||
'for the follower option "{}"'
|
||||
'').format(callback.__name__,
|
||||
ret,
|
||||
option.impl_get_display_name()))
|
||||
option.impl_get_display_name(subconfig)))
|
||||
return ret
|
||||
|
||||
|
||||
def calculate(option,
|
||||
def calculate(subconfig,
|
||||
callback: Callable,
|
||||
allow_value_error: bool,
|
||||
force_value_warning: bool,
|
||||
|
@ -617,12 +710,12 @@ def calculate(option,
|
|||
msg = _('unexpected error "{0}" in function "{1}" with arguments "{3}" and "{4}" '
|
||||
'for option "{2}"').format(str(error),
|
||||
callback.__name__,
|
||||
option.impl_get_display_name(),
|
||||
subconfig.option.impl_get_display_name(subconfig),
|
||||
args,
|
||||
kwargs)
|
||||
else:
|
||||
msg = _('unexpected error "{0}" in function "{1}" for option "{2}"'
|
||||
'').format(str(error),
|
||||
callback.__name__,
|
||||
option.impl_get_display_name())
|
||||
subconfig.option.impl_get_display_name(subconfig))
|
||||
raise ConfigError(msg) from error
|
||||
|
|
|
@ -47,11 +47,6 @@ class Cache:
|
|||
if path not in self._cache or index not in self._cache[path]:
|
||||
return no_cache
|
||||
value, timestamp, validated = self._cache[path][index]
|
||||
if type_ == 'context_props':
|
||||
# cached value is settings properties so value is props
|
||||
props = value
|
||||
self_props = {}
|
||||
else:
|
||||
props = subconfig.config_bag.properties
|
||||
if type_ == 'self_props':
|
||||
# cached value is self_props
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
import weakref
|
||||
from copy import copy, deepcopy
|
||||
from typing import Optional, List, Any, Union
|
||||
from os.path import commonprefix
|
||||
|
||||
from .error import PropertiesOptionError, ConfigError, ConflictError, \
|
||||
LeadershipError
|
||||
|
@ -35,6 +36,17 @@ from .autolib import Calculation
|
|||
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:
|
||||
__slots__ = tuple()
|
||||
# =============================================================================
|
||||
|
@ -171,6 +183,7 @@ class SubConfig:
|
|||
'path',
|
||||
'true_path',
|
||||
'properties',
|
||||
'raises_properties',
|
||||
'is_dynamic',
|
||||
'suffixes',
|
||||
'_length',
|
||||
|
@ -187,8 +200,6 @@ class SubConfig:
|
|||
properties: Union[list[str], undefined]=undefined,
|
||||
validate_properties: bool=True,
|
||||
) -> None:
|
||||
if path and '.' in path and not parent:
|
||||
raise Exception('pff connard')
|
||||
self.index = index
|
||||
self.suffixes = suffixes
|
||||
self.option = option
|
||||
|
@ -198,12 +209,14 @@ class SubConfig:
|
|||
self.path = path
|
||||
if true_path is None:
|
||||
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
|
||||
settings = config_bag.context.get_settings()
|
||||
if properties is undefined:
|
||||
if path is None:
|
||||
self.properties = frozenset()
|
||||
else:
|
||||
settings = config_bag.context.get_settings()
|
||||
self.properties = frozenset()
|
||||
if validate_properties:
|
||||
self.properties = settings.getproperties(self,
|
||||
|
@ -211,7 +224,7 @@ class SubConfig:
|
|||
)
|
||||
self.config_bag.context.get_settings().validate_properties(self)
|
||||
self.properties = settings.getproperties(self,
|
||||
apply_requires=True,
|
||||
apply_requires=apply_requires,
|
||||
)
|
||||
else:
|
||||
self.properties = properties
|
||||
|
@ -221,6 +234,15 @@ class SubConfig:
|
|||
self.is_dynamic = False
|
||||
if validate_properties:
|
||||
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):
|
||||
return f'<SubConfig path={self.path}, index={self.index}>'
|
||||
|
@ -228,7 +250,8 @@ class SubConfig:
|
|||
def dyn_to_subconfig(self,
|
||||
child: Option,
|
||||
validate_properties: bool,
|
||||
follower_not_apply_requires: bool=False,
|
||||
*,
|
||||
true_path: Optional[str]=None,
|
||||
) -> List['SubConfig']:
|
||||
config_bag = self.config_bag
|
||||
for suffix in child.get_suffixes(self):
|
||||
|
@ -241,10 +264,10 @@ class SubConfig:
|
|||
yield self.get_child(child,
|
||||
None,
|
||||
validate_properties,
|
||||
follower_not_apply_requires=follower_not_apply_requires,
|
||||
suffix=suffix,
|
||||
name=name,
|
||||
properties=properties,
|
||||
true_path=true_path,
|
||||
)
|
||||
except PropertiesOptionError as err:
|
||||
if err.proptype in (['mandatory'], ['empty']):
|
||||
|
@ -298,7 +321,6 @@ class SubConfig:
|
|||
validate_properties: bool,
|
||||
*,
|
||||
properties=undefined,
|
||||
follower_not_apply_requires: bool=False,
|
||||
allow_dynoption: bool=False,
|
||||
suffix: Optional[str]=None,
|
||||
name: Optional[str]=None,
|
||||
|
@ -312,24 +334,6 @@ class SubConfig:
|
|||
|
||||
if not self.option.impl_is_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,
|
||||
option,
|
||||
)
|
||||
|
@ -340,7 +344,7 @@ class SubConfig:
|
|||
suffixes = self.suffixes + [suffix]
|
||||
else:
|
||||
suffixes = [suffix]
|
||||
return SubConfig(option,
|
||||
subsubconfig = SubConfig(option,
|
||||
index,
|
||||
path,
|
||||
self.config_bag,
|
||||
|
@ -350,6 +354,17 @@ class SubConfig:
|
|||
validate_properties=validate_properties,
|
||||
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,
|
||||
name: str,
|
||||
|
@ -379,10 +394,77 @@ class SubConfig:
|
|||
cconfig_bag,
|
||||
self,
|
||||
self.suffixes,
|
||||
validate_properties=False,
|
||||
)
|
||||
self._length = len(cconfig_bag.context.get_value(subconfig))
|
||||
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):
|
||||
|
@ -486,7 +568,6 @@ class _Config(CCache):
|
|||
path,
|
||||
None,
|
||||
validate_properties=True,
|
||||
follower_not_apply_requires=False,
|
||||
)
|
||||
except PropertiesOptionError:
|
||||
continue
|
||||
|
@ -541,7 +622,6 @@ class _Config(CCache):
|
|||
index,
|
||||
*,
|
||||
validate_properties: bool=True,
|
||||
follower_not_apply_requires: bool=False,
|
||||
properties=undefined,
|
||||
true_path: Optional[str]=None,
|
||||
):
|
||||
|
@ -577,7 +657,6 @@ class _Config(CCache):
|
|||
subconfig = subconfig.get_child(option,
|
||||
index_,
|
||||
validate_properties,
|
||||
follower_not_apply_requires=follower_not_apply_requires,
|
||||
properties=properties,
|
||||
name=name,
|
||||
suffix=suffix,
|
||||
|
@ -647,17 +726,6 @@ class _Config(CCache):
|
|||
|
||||
# =============================================================================
|
||||
# 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,
|
||||
subconfig,
|
||||
need_help=True,
|
||||
|
@ -672,8 +740,9 @@ class _Config(CCache):
|
|||
if isinstance(subconfig, list):
|
||||
value = []
|
||||
follower_subconfig = None
|
||||
is_follower = not subconfig or subconfig[0].option.impl_is_follower()
|
||||
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,
|
||||
sconfig.path,
|
||||
sconfig.index,
|
||||
|
@ -692,7 +761,7 @@ class _Config(CCache):
|
|||
length = subconfig.parent.get_length_leadership()
|
||||
follower_len = self.get_values().get_max_length(subconfig.path)
|
||||
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}" '
|
||||
f'has greater length ({follower_len}) than the leader '
|
||||
f'length ({length})'))
|
||||
|
@ -704,6 +773,7 @@ class _Config(CCache):
|
|||
def _get(self,
|
||||
subconfig: "SubConfig",
|
||||
need_help: bool,
|
||||
validate_properties: bool=True,
|
||||
) -> "OptionBag":
|
||||
# pylint: disable=too-many-locals
|
||||
option = subconfig.option
|
||||
|
@ -712,17 +782,15 @@ class _Config(CCache):
|
|||
suboption = option.impl_getopt()
|
||||
if suboption.issubdyn():
|
||||
dynopt = suboption.getsubdyn()
|
||||
return list(dynopt.get_sub_children(suboption,
|
||||
suboption.config_bag,
|
||||
index=suboption.index,
|
||||
return subconfig.get_common_child(suboption,
|
||||
true_path=subconfig.path,
|
||||
))
|
||||
validate_properties=validate_properties,
|
||||
)
|
||||
if suboption.impl_is_follower():
|
||||
subconfig = self.get_sub_config(subconfig.config_bag, # pylint: disable=no-member
|
||||
suboption.impl_getpath(),
|
||||
None,
|
||||
validate_properties=True,
|
||||
follower_not_apply_requires=False,
|
||||
validate_properties=validate_properties,
|
||||
true_path=subconfig.path,
|
||||
)
|
||||
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
|
||||
suboption.impl_getpath(),
|
||||
None,
|
||||
validate_properties=True,
|
||||
follower_not_apply_requires=False,
|
||||
validate_properties=validate_properties,
|
||||
true_path=subconfig.path,
|
||||
)
|
||||
return self._get(s_subconfig,
|
||||
|
@ -818,6 +885,7 @@ class _CommonConfig(_Config):
|
|||
self.reset_cache(option_bag)
|
||||
|
||||
def impl_get_information(self,
|
||||
subconfig,
|
||||
key,
|
||||
default,
|
||||
):
|
||||
|
@ -893,7 +961,7 @@ class _CommonConfig(_Config):
|
|||
duplicated_settings.rw_append = self.get_settings().rw_append
|
||||
duplicated_settings.ro_remove = self.get_settings().ro_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)
|
||||
if child is not None:
|
||||
duplicated_config._impl_children.append(child) # pylint: disable=protected-access
|
||||
|
@ -1412,7 +1480,7 @@ class KernelMixConfig(KernelGroupConfig):
|
|||
)
|
||||
# Copy context properties/permissives
|
||||
settings = config.get_settings()
|
||||
properties = settings.get_context_properties(config.properties_cache)
|
||||
properties = settings.get_context_properties()
|
||||
settings.set_context_properties(properties,
|
||||
config,
|
||||
)
|
||||
|
@ -1421,7 +1489,7 @@ class KernelMixConfig(KernelGroupConfig):
|
|||
settings.rw_append = settings.rw_append
|
||||
settings.ro_remove = settings.ro_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))
|
||||
self._impl_children.append(config)
|
||||
|
|
|
@ -70,8 +70,9 @@ class PropertiesOptionError(AttributeError):
|
|||
self._opt_type = 'optiondescription'
|
||||
else:
|
||||
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._subconfig = subconfig
|
||||
self.proptype = proptype
|
||||
self.help_properties = help_properties
|
||||
self._settings = settings
|
||||
|
@ -108,8 +109,9 @@ class PropertiesOptionError(AttributeError):
|
|||
else:
|
||||
msg = 'cannot access to {0} "{1}" because has {2} {3}'
|
||||
if self._orig_opt:
|
||||
# FIXME _orig_opt ?
|
||||
self.msg = _(msg).format(self._opt_type,
|
||||
self._orig_opt.impl_get_display_name(),
|
||||
self._orig_opt.impl_get_display_name(subconfig),
|
||||
self._name,
|
||||
prop_msg,
|
||||
properties_msg)
|
||||
|
@ -156,6 +158,7 @@ class ConstError(TypeError):
|
|||
|
||||
class _CommonError:
|
||||
def __init__(self,
|
||||
subconfig,
|
||||
val,
|
||||
display_type,
|
||||
opt,
|
||||
|
@ -164,7 +167,7 @@ class _CommonError:
|
|||
self.val = val
|
||||
self.display_type = display_type
|
||||
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.index = index
|
||||
super().__init__(self.err_msg)
|
||||
|
|
|
@ -944,7 +944,7 @@ msgstr "option \"{0}\" inconnue dans l'optiondescription \"{1}\""
|
|||
|
||||
#: tiramisu/option/optiondescription.py:279
|
||||
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
|
||||
msgid "duplicate option name: \"{0}\""
|
||||
|
|
|
@ -20,14 +20,14 @@
|
|||
# ____________________________________________________________
|
||||
"""base option
|
||||
"""
|
||||
from typing import FrozenSet, Set, Any, List
|
||||
from typing import FrozenSet, Set, Any, List, Optional, Dict
|
||||
import weakref
|
||||
from itertools import chain
|
||||
|
||||
|
||||
from ..i18n import _
|
||||
from ..setting import undefined
|
||||
from ..autolib import Calculation, ParamOption
|
||||
from ..autolib import Calculation, ParamOption, ParamInformation, ParamSelfInformation
|
||||
|
||||
STATIC_TUPLE = frozenset()
|
||||
|
||||
|
@ -57,6 +57,7 @@ class Base:
|
|||
'_properties',
|
||||
'_has_dependency',
|
||||
'_dependencies',
|
||||
'_dependencies_information',
|
||||
'_suffixes_dependencies',
|
||||
'__weakref__'
|
||||
)
|
||||
|
@ -64,8 +65,11 @@ class Base:
|
|||
def __init__(self,
|
||||
name: str,
|
||||
doc: str,
|
||||
informations: Optional[Dict],
|
||||
*,
|
||||
properties=None,
|
||||
is_multi: bool=False) -> None:
|
||||
is_multi: bool=False,
|
||||
) -> None:
|
||||
if not valid_name(name):
|
||||
raise ValueError(_('"{0}" is an invalid name for an option').format(name))
|
||||
if properties is None:
|
||||
|
@ -83,6 +87,9 @@ class Base:
|
|||
assert isinstance(properties, frozenset), _('invalid properties type {0} for {1},'
|
||||
' must be a frozenset').format(type(properties),
|
||||
name)
|
||||
_setattr = object.__setattr__
|
||||
_setattr(self, '_name', name)
|
||||
_setattr(self, '_informations', {'doc': doc})
|
||||
for prop in properties:
|
||||
if not isinstance(prop, str):
|
||||
if not isinstance(prop, Calculation):
|
||||
|
@ -91,11 +98,19 @@ class Base:
|
|||
for param in chain(prop.params.args, prop.params.kwargs.values()):
|
||||
if isinstance(param, ParamOption):
|
||||
param.option._add_dependency(self)
|
||||
_setattr = object.__setattr__
|
||||
_setattr(self, '_name', name)
|
||||
_setattr(self, '_informations', {'doc': doc})
|
||||
if 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,
|
||||
self_is_dep: bool=True,
|
||||
|
@ -196,7 +211,8 @@ class Base:
|
|||
|
||||
# ____________________________________________________________
|
||||
# information
|
||||
def impl_get_information(self,
|
||||
def _get_information(self,
|
||||
subconfig: "SubConfig",
|
||||
key: str,
|
||||
default: Any=undefined,
|
||||
) -> Any:
|
||||
|
@ -217,10 +233,10 @@ class Base:
|
|||
if default is not undefined:
|
||||
return default
|
||||
# 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}"'))
|
||||
|
||||
def impl_set_information(self,
|
||||
def _set_information(self,
|
||||
key: str,
|
||||
value: Any,
|
||||
) -> None:
|
||||
|
@ -237,13 +253,13 @@ class Base:
|
|||
key))
|
||||
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
|
||||
"""
|
||||
dico = self._informations # pylint: disable=no-member
|
||||
if isinstance(dico, tuple):
|
||||
return list(dico[0])
|
||||
if isinstance(dico, str):
|
||||
if not isinstance(dico, dict):
|
||||
return ['doc']
|
||||
# it's a dict
|
||||
return list(dico.keys())
|
||||
|
@ -272,7 +288,7 @@ class BaseOption(Base):
|
|||
if self.impl_is_readonly():
|
||||
raise AttributeError(_('"{}" ({}) object attribute "{}" is'
|
||||
' read-only').format(self.__class__.__name__,
|
||||
self.impl_get_display_name(),
|
||||
self.impl_get_display_name(None),
|
||||
name))
|
||||
super().__setattr__(name, value)
|
||||
|
||||
|
@ -282,21 +298,22 @@ class BaseOption(Base):
|
|||
try:
|
||||
return self._path
|
||||
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
|
||||
|
||||
def impl_get_display_name(self,
|
||||
dynopt=None,
|
||||
subconfig: "SubConfig",
|
||||
) -> str:
|
||||
"""get display name
|
||||
"""
|
||||
if dynopt is None:
|
||||
dynopt = self
|
||||
if hasattr(self, '_display_name_function'):
|
||||
return self._display_name_function(dynopt)
|
||||
name = self.impl_get_information('doc', None)
|
||||
return self._display_name_function(self, subconfig)
|
||||
name = self._get_information(subconfig, 'doc', None)
|
||||
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
|
||||
|
||||
def reset_cache(self,
|
||||
|
@ -322,33 +339,43 @@ class BaseOption(Base):
|
|||
"""
|
||||
return getattr(self, '_dependencies_information', {})
|
||||
|
||||
def to_sub_dyoption(self,
|
||||
suffixes: list[str],
|
||||
):
|
||||
sub_dyn = self
|
||||
# retrieve all subdyn options
|
||||
sub_dyns = []
|
||||
while True:
|
||||
sub_dyn = sub_dyn.getsubdyn()
|
||||
sub_dyns.append(sub_dyn)
|
||||
if not sub_dyn.issubdyn():
|
||||
break
|
||||
paths = []
|
||||
parent_path = self.impl_getpath().rsplit('.', 1)[0]
|
||||
suffix_idx = len(sub_dyns) - 1
|
||||
for sub_dyn in sub_dyns:
|
||||
dyn_path = sub_dyn.impl_getpath()
|
||||
if dyn_path.count('.') == parent_path.count('.'):
|
||||
*root_paths, dyn_path_ = parent_path.split('.', dyn_path.count('.') + 1)
|
||||
def value_dependencies(self,
|
||||
value: Any,
|
||||
is_suffix: bool=False,
|
||||
) -> Any:
|
||||
"""parse dependancies to add dependencies
|
||||
"""
|
||||
if isinstance(value, list):
|
||||
for val in value:
|
||||
if isinstance(value, list):
|
||||
self.value_dependencies(val, is_suffix)
|
||||
elif isinstance(value, Calculation):
|
||||
self.value_dependency(val, is_suffix)
|
||||
elif isinstance(value, Calculation):
|
||||
self.value_dependency(value, is_suffix)
|
||||
|
||||
def value_dependency(self,
|
||||
value: Any,
|
||||
is_suffix: bool=False,
|
||||
) -> 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, is_suffix=is_suffix)
|
||||
self._has_dependency = True
|
||||
elif isinstance(param, ParamInformation):
|
||||
dest = self
|
||||
if isinstance(param, ParamSelfInformation):
|
||||
opt = weakref.ref(self)
|
||||
elif param.option:
|
||||
dest = param.option
|
||||
opt = weakref.ref(self)
|
||||
else:
|
||||
*root_paths, dyn_path_, child_path = parent_path.split('.', dyn_path.count('.') + 1)
|
||||
paths.insert(0, child_path)
|
||||
paths.insert(0, sub_dyn.impl_getname(suffixes[suffix_idx]))
|
||||
suffix_idx -= 1
|
||||
parent_path = '.'.join(root_paths)
|
||||
if parent_path:
|
||||
paths.insert(0, parent_path)
|
||||
full_parent_path = '.'.join(paths)
|
||||
return self.to_dynoption(full_parent_path,
|
||||
suffixes,
|
||||
)
|
||||
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 ..i18n import _
|
||||
from .option import Option
|
||||
from ..autolib import Calculation
|
||||
from ..autolib import Calculation, get_calculated_value
|
||||
from ..error import ConfigError, display_list
|
||||
|
||||
|
||||
|
@ -61,13 +61,16 @@ class ChoiceOption(Option):
|
|||
):
|
||||
"""get values allowed by option
|
||||
"""
|
||||
if isinstance(self._choice_values, Calculation):
|
||||
values = self._choice_values.execute(subconfig)
|
||||
if values is not undefined and not isinstance(values, list):
|
||||
choices = self._choice_values
|
||||
if isinstance(choices, tuple):
|
||||
choices = list(choices)
|
||||
values = get_calculated_value(subconfig,
|
||||
choices,
|
||||
)[0]
|
||||
|
||||
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()))
|
||||
else:
|
||||
values = self._choice_values
|
||||
return values
|
||||
|
||||
def validate(self,
|
||||
|
|
|
@ -20,22 +20,23 @@
|
|||
# ____________________________________________________________
|
||||
"""DynOptionDescription
|
||||
"""
|
||||
import re
|
||||
import weakref
|
||||
from typing import List, Any, Optional
|
||||
from typing import List, Any, Optional, Dict
|
||||
from itertools import chain
|
||||
from ..autolib import ParamOption
|
||||
|
||||
|
||||
from ..i18n import _
|
||||
from .optiondescription import OptionDescription
|
||||
from .syndynoption import CommonDyn #, SynDynLeadership
|
||||
from .baseoption import BaseOption
|
||||
from ..setting import ConfigBag, undefined
|
||||
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
|
||||
"""
|
||||
__slots__ = ('_suffixes',
|
||||
|
@ -48,25 +49,28 @@ class DynOptionDescription(OptionDescription, CommonDyn):
|
|||
children: List[BaseOption],
|
||||
suffixes: Calculation,
|
||||
properties=None,
|
||||
informations: Optional[Dict]=None,
|
||||
) -> None:
|
||||
# pylint: disable=too-many-arguments
|
||||
super().__init__(name,
|
||||
doc,
|
||||
children,
|
||||
properties,
|
||||
informations=informations,
|
||||
)
|
||||
# check children + set relation to this dynoptiondescription
|
||||
wself = weakref.ref(self)
|
||||
for child in children:
|
||||
child._setsubdyn(wself)
|
||||
# add suffixes
|
||||
if __debug__ and not isinstance(suffixes, Calculation):
|
||||
raise ConfigError(_('suffixes in dynoptiondescription has to be a calculation'))
|
||||
for param in chain(suffixes.params.args, suffixes.params.kwargs.values()):
|
||||
if isinstance(param, ParamOption):
|
||||
param.option._add_dependency(self,
|
||||
is_suffix=True,
|
||||
)
|
||||
self.value_dependencies(suffixes, is_suffix=True)
|
||||
# if __debug__ and not isinstance(suffixes, Calculation):
|
||||
# raise ConfigError(_('suffixes in dynoptiondescription has to be a calculation'))
|
||||
# for param in chain(suffixes.params.args, suffixes.params.kwargs.values()):
|
||||
# if isinstance(param, ParamOption):
|
||||
# param.option._add_dependency(self,
|
||||
# is_suffix=True,
|
||||
# )
|
||||
self._suffixes = suffixes
|
||||
|
||||
def convert_suffix_to_path(self,
|
||||
|
@ -98,3 +102,42 @@ class DynOptionDescription(OptionDescription, CommonDyn):
|
|||
return name
|
||||
path_suffix = self.convert_suffix_to_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):
|
||||
if child.impl_is_symlinkoption():
|
||||
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):
|
||||
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():
|
||||
raise ValueError(_('only multi option allowed in leadership "{0}" but option '
|
||||
'"{1}" is not a multi'
|
||||
'').format(self.impl_get_display_name(),
|
||||
child.impl_get_display_name()))
|
||||
'').format(self.impl_get_display_name(None),
|
||||
child.impl_get_display_name(None)))
|
||||
|
||||
def _check_default_value(self, child: BaseOption):
|
||||
default = child.impl_getdefault()
|
||||
|
@ -100,8 +100,8 @@ class Leadership(OptionDescription):
|
|||
calculation = isinstance(default, Calculation)
|
||||
if not calculation:
|
||||
raise ValueError(_('not allowed default value for follower option '
|
||||
f'"{child.impl_get_display_name()}" in leadership '
|
||||
f'"{self.impl_get_display_name()}"'))
|
||||
f'"{child.impl_get_display_name(None)}" in leadership '
|
||||
f'"{self.impl_get_display_name(None)}"'))
|
||||
|
||||
def _setsubdyn(self,
|
||||
subdyn,
|
||||
|
@ -143,58 +143,54 @@ class Leadership(OptionDescription):
|
|||
def reset(self, parent: "SubConfig") -> None:
|
||||
"""reset follower value
|
||||
"""
|
||||
#config_bag = parent.option_bag.config_bag
|
||||
values = parent.config_bag.context.get_values()
|
||||
#config_bag = config_bag.copy()
|
||||
#config_bag.remove_validation()
|
||||
for follower in self.get_followers():
|
||||
subconfig_follower = parent.get_child(follower,
|
||||
None,
|
||||
False,
|
||||
)
|
||||
# OptionBag(follower,
|
||||
# None,
|
||||
# config_bag,
|
||||
# )
|
||||
values.reset(subconfig_follower)
|
||||
#
|
||||
# def follower_force_store_value(self,
|
||||
# value,
|
||||
# config_bag: 'ConfigBag',
|
||||
# owner,
|
||||
# dyn=None,
|
||||
# ) -> None:
|
||||
# """apply force_store_value to follower
|
||||
# """
|
||||
# if value:
|
||||
# if dyn is None:
|
||||
# dyn = self
|
||||
# values = config_bag.context.get_values()
|
||||
# for idx, follower in enumerate(dyn.get_children(config_bag)):
|
||||
# if not idx:
|
||||
# # it's a master
|
||||
# apply_requires = True
|
||||
# indexes = [None]
|
||||
# else:
|
||||
# apply_requires = False
|
||||
# indexes = range(len(value))
|
||||
# foption_bag = OptionBag(follower,
|
||||
# None,
|
||||
# config_bag,
|
||||
# apply_requires=apply_requires,
|
||||
# )
|
||||
# if 'force_store_value' not in foption_bag.properties:
|
||||
# continue
|
||||
# for index in indexes:
|
||||
# foption_bag_index = OptionBag(follower,
|
||||
# index,
|
||||
# config_bag,
|
||||
# )
|
||||
# values.set_storage_value(foption_bag_index.path,
|
||||
# index,
|
||||
# values.get_value(foption_bag_index)[0],
|
||||
# owner,
|
||||
# )
|
||||
values.reset(subconfig_follower,
|
||||
validate=False,
|
||||
)
|
||||
|
||||
def follower_force_store_value(self,
|
||||
value,
|
||||
subconfig: 'SubConfig',
|
||||
owner,
|
||||
) -> None:
|
||||
"""apply force_store_value to follower
|
||||
"""
|
||||
if not value:
|
||||
return
|
||||
config_bag = subconfig.config_bag
|
||||
values = config_bag.context.get_values()
|
||||
for idx, follower in enumerate(self.get_children()):
|
||||
sub_subconfig = subconfig.get_child(follower,
|
||||
None,
|
||||
False,
|
||||
config_bag=config_bag,
|
||||
)
|
||||
if 'force_store_value' not in sub_subconfig.properties:
|
||||
continue
|
||||
self_path = sub_subconfig.path
|
||||
if not idx:
|
||||
# it's a master
|
||||
apply_requires = True
|
||||
indexes = [None]
|
||||
else:
|
||||
apply_requires = False
|
||||
indexes = range(len(value))
|
||||
for index in indexes:
|
||||
i_sub_subconfig = subconfig.get_child(follower,
|
||||
index,
|
||||
False,
|
||||
config_bag=config_bag,
|
||||
)
|
||||
values.set_storage_value(self_path,
|
||||
index,
|
||||
values.get_value(i_sub_subconfig)[0],
|
||||
owner,
|
||||
)
|
||||
|
||||
def pop(self,
|
||||
subconfig: 'SubConfig',
|
||||
|
|
|
@ -26,9 +26,8 @@ from itertools import chain
|
|||
from .baseoption import BaseOption, submulti
|
||||
from ..i18n import _
|
||||
from ..setting import undefined
|
||||
from ..autolib import Calculation, ParamOption, ParamInformation, ParamSelfInformation
|
||||
from ..autolib import Calculation
|
||||
from ..error import ValueWarning, ValueErrorWarning, ValueOptionError
|
||||
from .syndynoption import SynDynOption
|
||||
|
||||
|
||||
class Option(BaseOption):
|
||||
|
@ -48,7 +47,6 @@ class Option(BaseOption):
|
|||
#
|
||||
'_validators',
|
||||
#
|
||||
'_dependencies_information',
|
||||
'_leadership',
|
||||
'_choice_values',
|
||||
'_choice_values_params',
|
||||
|
@ -63,7 +61,9 @@ class Option(BaseOption):
|
|||
validators: Optional[List[Calculation]]=None,
|
||||
properties: Optional[List[str]]=None,
|
||||
warnings_only: bool=False,
|
||||
extra: Optional[Dict]=None):
|
||||
extra: Optional[Dict]=None,
|
||||
informations: Optional[Dict]=None,
|
||||
):
|
||||
_setattr = object.__setattr__
|
||||
if not multi and default_multi is not None:
|
||||
raise ValueError(_("default_multi is set whereas multi is False"
|
||||
|
@ -92,8 +92,10 @@ class Option(BaseOption):
|
|||
default = []
|
||||
super().__init__(name,
|
||||
doc,
|
||||
informations,
|
||||
properties=properties,
|
||||
is_multi=is_multi)
|
||||
is_multi=is_multi,
|
||||
)
|
||||
if validators is not None:
|
||||
if __debug__ and not isinstance(validators, list):
|
||||
raise ValueError(_(f'validators must be a list of Calculation for "{name}"'))
|
||||
|
@ -126,10 +128,10 @@ class Option(BaseOption):
|
|||
if not str_err:
|
||||
raise ValueError(_('invalid default_multi value "{0}" '
|
||||
'for option "{1}"').format(str(value),
|
||||
self.impl_get_display_name())
|
||||
self.impl_get_display_name(None))
|
||||
) from err
|
||||
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
|
||||
if _multi is submulti:
|
||||
if not isinstance(default_multi, Calculation):
|
||||
|
@ -137,7 +139,7 @@ class Option(BaseOption):
|
|||
raise ValueError(_('invalid default_multi value "{0}" '
|
||||
'for option "{1}", must be a list for a submulti'
|
||||
'').format(str(default_multi),
|
||||
self.impl_get_display_name()))
|
||||
self.impl_get_display_name(None)))
|
||||
for value in default_multi:
|
||||
test_multi_value(value)
|
||||
else:
|
||||
|
@ -164,43 +166,6 @@ class Option(BaseOption):
|
|||
default = tuple(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
|
||||
|
||||
|
@ -326,7 +291,8 @@ class Option(BaseOption):
|
|||
**kwargs,
|
||||
)
|
||||
except ValueWarning as warn:
|
||||
warnings.warn_explicit(ValueWarning(val,
|
||||
warnings.warn_explicit(ValueWarning(subconfig,
|
||||
val,
|
||||
self.get_type(),
|
||||
self,
|
||||
str(warn),
|
||||
|
@ -343,7 +309,7 @@ class Option(BaseOption):
|
|||
return
|
||||
if isinstance(_value, list):
|
||||
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:
|
||||
return
|
||||
|
@ -361,7 +327,8 @@ class Option(BaseOption):
|
|||
is_warnings_only)
|
||||
except ValueError as err:
|
||||
if is_warnings_only:
|
||||
warnings.warn_explicit(ValueWarning(_value,
|
||||
warnings.warn_explicit(ValueWarning(subconfig,
|
||||
_value,
|
||||
self.get_type(),
|
||||
self,
|
||||
str(err),
|
||||
|
@ -420,12 +387,14 @@ class Option(BaseOption):
|
|||
except ValueError as err:
|
||||
if not subconfig or \
|
||||
'demoting_error_warning' not in subconfig.config_bag.properties:
|
||||
raise ValueOptionError(val,
|
||||
raise ValueOptionError(subconfig,
|
||||
val,
|
||||
self.get_type(),
|
||||
self,
|
||||
str(err),
|
||||
err_index) from err
|
||||
warnings.warn_explicit(ValueErrorWarning(val,
|
||||
warnings.warn_explicit(ValueErrorWarning(subconfig,
|
||||
val,
|
||||
self.get_type(),
|
||||
self,
|
||||
str(err),
|
||||
|
@ -476,16 +445,6 @@ class Option(BaseOption):
|
|||
#pylint: disable=not-callable
|
||||
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):
|
||||
"""option needs a validate function
|
||||
"""
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"""OptionDescription
|
||||
"""
|
||||
import weakref
|
||||
from typing import Optional, Iterator, Union, List
|
||||
from typing import Optional, Iterator, Union, List, Dict
|
||||
|
||||
|
||||
from ..i18n import _
|
||||
|
@ -87,6 +87,10 @@ class CacheOptionDescription(BaseOption):
|
|||
dependencies_information,
|
||||
)
|
||||
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():
|
||||
if None in options:
|
||||
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._path = None # pylint: disable=attribute-defined-outside-init,no-member
|
||||
self._set_readonly()
|
||||
#
|
||||
# def impl_build_force_store_values(self,
|
||||
# config_bag: ConfigBag,
|
||||
# ) -> None:
|
||||
# """set value to force_store_values option
|
||||
# """
|
||||
# # pylint: disable=too-many-branches
|
||||
# def do_option_bags(option):
|
||||
# if option.issubdyn():
|
||||
# dynopt = option.getsubdyn()
|
||||
# yield from dynopt.get_sub_children(option,
|
||||
# config_bag,
|
||||
# index=None,
|
||||
# )
|
||||
# else:
|
||||
# yield OptionBag(option,
|
||||
# None,
|
||||
# config_bag,
|
||||
# properties=None,
|
||||
# )
|
||||
# if 'force_store_value' not in config_bag.properties:
|
||||
# return
|
||||
# values = config_bag.context.get_values()
|
||||
# for option in self._cache_force_store_values:
|
||||
# if option.impl_is_follower():
|
||||
# leader = option.impl_get_leadership().get_leader()
|
||||
# for leader_option_bag in do_option_bags(leader):
|
||||
# leader_option_bag.properties = frozenset()
|
||||
# follower_len = len(values.get_value(leader_option_bag)[0])
|
||||
# if option.issubdyn():
|
||||
# doption = option.to_dynoption(leader_option_bag.option.rootpath,
|
||||
# leader_option_bag.option.get_current_suffixes(),
|
||||
# )
|
||||
# else:
|
||||
# doption = option
|
||||
# subpath = doption.impl_getpath()
|
||||
# for index in range(follower_len):
|
||||
# option_bag = OptionBag(doption,
|
||||
# index,
|
||||
# config_bag,
|
||||
# properties=frozenset(),
|
||||
# )
|
||||
# if values.hasvalue(subpath, index=index):
|
||||
# continue
|
||||
# value = values.get_value(option_bag)[0]
|
||||
# if value is None:
|
||||
# continue
|
||||
# values.set_storage_value(subpath,
|
||||
# index,
|
||||
# value,
|
||||
# owners.forced,
|
||||
# )
|
||||
# else:
|
||||
# for option_bag in do_option_bags(option):
|
||||
# option_bag.properties = frozenset()
|
||||
# value = values.get_value(option_bag)[0]
|
||||
# if value is None:
|
||||
# continue
|
||||
# if values.hasvalue(option_bag.path):
|
||||
# continue
|
||||
# values.set_storage_value(option_bag.path,
|
||||
# None,
|
||||
# value,
|
||||
# owners.forced,
|
||||
# )
|
||||
|
||||
def impl_build_force_store_values(self,
|
||||
config_bag: ConfigBag,
|
||||
) -> None:
|
||||
"""set value to force_store_values option
|
||||
"""
|
||||
# pylint: disable=too-many-branches
|
||||
context = config_bag.context
|
||||
if 'force_store_value' not in config_bag.properties:
|
||||
return
|
||||
|
||||
values = config_bag.context.get_values()
|
||||
for option in self._cache_force_store_values:
|
||||
if option.issubdyn():
|
||||
paths = option.impl_getpath().split('.')
|
||||
parents = [config_bag.context.get_root(config_bag)]
|
||||
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():
|
||||
new_parents.extend(parent.dyn_to_subconfig(doption,
|
||||
True,
|
||||
)
|
||||
)
|
||||
else:
|
||||
new_parents.append(parent.get_child(doption,
|
||||
None,
|
||||
True,
|
||||
name=name,
|
||||
))
|
||||
parents = new_parents
|
||||
subconfigs = new_parents
|
||||
else:
|
||||
subconfigs = [context.get_sub_config(config_bag,
|
||||
option.impl_getpath(),
|
||||
None,
|
||||
properties=None,
|
||||
validate_properties=False,
|
||||
)]
|
||||
|
||||
if option.impl_is_follower():
|
||||
for follower_subconfig in subconfigs:
|
||||
parent = follower_subconfig.parent
|
||||
follower_len = parent.get_length_leadership()
|
||||
for index in range(follower_len):
|
||||
if values.hasvalue(follower_subconfig.path,
|
||||
index=index,
|
||||
):
|
||||
continue
|
||||
idx_follower_subconfig = parent.get_child(follower_subconfig.option,
|
||||
index,
|
||||
validate_properties=False,
|
||||
)
|
||||
|
||||
value = values.get_value(idx_follower_subconfig)[0]
|
||||
if value is None:
|
||||
continue
|
||||
values.set_storage_value(follower_subconfig.path,
|
||||
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):
|
||||
|
@ -228,7 +247,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
|||
'in root optiondescription'
|
||||
))
|
||||
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]:
|
||||
|
@ -278,7 +297,9 @@ class OptionDescription(OptionDescriptionWalk):
|
|||
name: str,
|
||||
doc: str,
|
||||
children: List[BaseOption],
|
||||
properties=None) -> None:
|
||||
properties=None,
|
||||
informations: Optional[Dict]=None,
|
||||
) -> None:
|
||||
"""
|
||||
:param children: a list of options (including optiondescriptions)
|
||||
|
||||
|
@ -286,8 +307,10 @@ class OptionDescription(OptionDescriptionWalk):
|
|||
assert isinstance(children, list), _('children in optiondescription "{}" '
|
||||
'must be a list').format(name)
|
||||
super().__init__(name,
|
||||
doc=doc,
|
||||
properties=properties)
|
||||
doc,
|
||||
informations,
|
||||
properties=properties,
|
||||
)
|
||||
child_names = []
|
||||
if __debug__:
|
||||
dynopt_names = []
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
# ____________________________________________________________
|
||||
"""SymLinkOption link to an other option
|
||||
"""
|
||||
from typing import Any
|
||||
from typing import Any, Optional, Dict
|
||||
from .baseoption import BaseOption, valid_name
|
||||
from ..error import ConfigError
|
||||
from ..i18n import _
|
||||
|
@ -41,55 +41,46 @@ class SymLinkOption(BaseOption):
|
|||
if not isinstance(opt, BaseOption) or \
|
||||
opt.impl_is_optiondescription() or \
|
||||
opt.impl_is_symlinkoption():
|
||||
raise ValueError(_('malformed symlinkoption must be an option for symlink {0}'
|
||||
'').format(name))
|
||||
_setattr = object.__setattr__
|
||||
_setattr(self, '_name', name)
|
||||
_setattr(self, '_opt', opt)
|
||||
raise ValueError(_(f'malformed symlink second parameters must be an option for "{name}", not {opt}'))
|
||||
self._name = name
|
||||
self._opt = opt
|
||||
opt._add_dependency(self)
|
||||
|
||||
def __getattr__(self,
|
||||
name: str,
|
||||
) -> Any:
|
||||
if name == '_subdyns':
|
||||
return None
|
||||
if name == '_path':
|
||||
raise AttributeError()
|
||||
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:
|
||||
"""it's a symlinkoption
|
||||
"""
|
||||
return True
|
||||
|
||||
def impl_is_leader(self) -> bool:
|
||||
return False
|
||||
|
||||
def impl_is_follower(self) -> bool:
|
||||
return False
|
||||
|
||||
def impl_getopt(self) -> BaseOption:
|
||||
"""get to linked option
|
||||
"""
|
||||
return self._opt
|
||||
|
||||
def issubdyn(self) -> bool:
|
||||
"""it's not a sub dyn option
|
||||
"""
|
||||
return False
|
||||
|
||||
def impl_is_multi(self) -> bool:
|
||||
"""is it a multi?
|
||||
"""
|
||||
if self._opt.issubdyn():
|
||||
if self._opt.impl_is_multi():
|
||||
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:
|
||||
"""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 itertools import chain
|
||||
from .error import PropertiesOptionError, ConstError, ConfigError, LeadershipError
|
||||
from .error import PropertiesOptionError, ConstError, ConfigError, LeadershipError, display_list
|
||||
from .i18n import _
|
||||
|
||||
|
||||
|
@ -156,63 +156,6 @@ class 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:
|
||||
|
@ -390,7 +333,6 @@ class Settings:
|
|||
'ro_remove',
|
||||
'rw_append',
|
||||
'rw_remove',
|
||||
'default_properties',
|
||||
)
|
||||
|
||||
def __init__(self):
|
||||
|
@ -401,9 +343,8 @@ class Settings:
|
|||
:param storage: the storage type
|
||||
"""
|
||||
# generic owner
|
||||
self._properties = {}
|
||||
self._properties = {None: {None: DEFAULT_PROPERTIES}}
|
||||
self._permissives = {}
|
||||
self.default_properties = DEFAULT_PROPERTIES
|
||||
self.ro_append = RO_APPEND
|
||||
self.ro_remove = RO_REMOVE
|
||||
self.rw_append = RW_APPEND
|
||||
|
@ -412,35 +353,19 @@ class Settings:
|
|||
# ____________________________________________________________
|
||||
# get properties and permissive methods
|
||||
|
||||
def get_context_properties(self,
|
||||
cache,
|
||||
):
|
||||
def get_context_properties(self):
|
||||
"""get context properties
|
||||
"""
|
||||
is_cached, props, _ = cache.getcache(None,
|
||||
'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
|
||||
return self.get_personalize_properties()
|
||||
|
||||
def get_stored_properties(self,
|
||||
path: Union[None, str],
|
||||
index: Union[None, int],
|
||||
default_properties: Set[str],
|
||||
def get_personalize_properties(self,
|
||||
path: Union[None, str]=None,
|
||||
index: Union[None, int]=None,
|
||||
) -> Set[str]:
|
||||
"""Get the properties modified by user for a path or index
|
||||
"""
|
||||
if path not in self._properties or index not in self._properties[path]:
|
||||
return frozenset(default_properties)
|
||||
return frozenset()
|
||||
return self._properties[path][index]
|
||||
|
||||
def getproperties(self,
|
||||
|
@ -467,18 +392,17 @@ class Settings:
|
|||
if not is_cached:
|
||||
props = set()
|
||||
# if index, get option's properties (without index) too
|
||||
p_props = self.get_stored_properties(subconfig.path,
|
||||
None,
|
||||
option.impl_getproperties(),
|
||||
)
|
||||
p_props = [option.impl_getproperties()]
|
||||
props_config = self.get_personalize_properties(subconfig.path)
|
||||
if props_config:
|
||||
p_props.append(props_config)
|
||||
if subconfig.index is not None:
|
||||
p_props = chain(p_props,
|
||||
self.get_stored_properties(subconfig.path,
|
||||
props_config = self.get_personalize_properties(subconfig.path,
|
||||
subconfig.index,
|
||||
option.impl_getproperties(),
|
||||
)
|
||||
)
|
||||
for prop in p_props:
|
||||
if props_config:
|
||||
p_props.append(props_config)
|
||||
for prop in chain(*p_props):
|
||||
if uncalculated or isinstance(prop, str):
|
||||
if not help_property:
|
||||
props.add(prop)
|
||||
|
@ -520,6 +444,12 @@ class Settings:
|
|||
props,
|
||||
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
|
||||
|
||||
def get_context_permissives(self):
|
||||
|
@ -566,7 +496,7 @@ class Settings:
|
|||
def set_context_properties(self, properties, context):
|
||||
"""set context properties
|
||||
"""
|
||||
self._properties.setdefault(None, {})[None] = properties
|
||||
self._properties[None][None] = properties
|
||||
context.reset_cache(None)
|
||||
|
||||
def setproperties(self,
|
||||
|
@ -580,7 +510,7 @@ class Settings:
|
|||
if not opt.impl_is_optiondescription() and opt.impl_is_leader():
|
||||
not_allowed_properties = properties - ALLOWED_LEADER_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'))
|
||||
if ('force_default_on_freeze' in properties or \
|
||||
'force_metaconfig_on_freeze' in properties) and 'frozen' not in properties:
|
||||
|
@ -682,9 +612,11 @@ class Settings:
|
|||
# validate properties
|
||||
def calc_raises_properties(self,
|
||||
subconfig,
|
||||
*,
|
||||
apply_requires=True,
|
||||
uncalculated=False,
|
||||
transitive_raise=True,
|
||||
not_unrestraint=False,
|
||||
):
|
||||
"""raise if needed
|
||||
"""
|
||||
|
@ -698,16 +630,23 @@ class Settings:
|
|||
)
|
||||
return self._calc_raises_properties(subconfig,
|
||||
option_properties,
|
||||
not_unrestraint,
|
||||
)
|
||||
|
||||
def _calc_raises_properties(self,
|
||||
subconfig,
|
||||
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
|
||||
if raises_properties and 'permissive' in raises_properties:
|
||||
raises_properties -= subconfig.config_bag.permissives
|
||||
raises_properties -= config_bag.permissives
|
||||
properties = option_properties & raises_properties
|
||||
# at this point it should not remain any property for the option
|
||||
return properties
|
||||
|
@ -736,6 +675,7 @@ class Settings:
|
|||
calc_properties = []
|
||||
for property_ in self._calc_raises_properties(subconfig,
|
||||
set(help_properties.keys()),
|
||||
False,
|
||||
):
|
||||
calc_properties.append(help_properties[property_])
|
||||
calc_properties = frozenset(calc_properties)
|
||||
|
@ -799,10 +739,7 @@ class Settings:
|
|||
append,
|
||||
config_bag,
|
||||
):
|
||||
props = self.get_stored_properties(None,
|
||||
None,
|
||||
self.default_properties,
|
||||
)
|
||||
props = self.get_personalize_properties()
|
||||
modified = False
|
||||
if remove & props:
|
||||
props = props - remove
|
||||
|
|
|
@ -6,7 +6,7 @@ from copy import copy
|
|||
from itertools import chain
|
||||
from .error import ValueWarning, ValueErrorWarning, PropertiesOptionError, ConfigError
|
||||
from .setting import undefined
|
||||
from .option.syndynoption import SynDynOption
|
||||
#from .option.syndynoption import SynDynOption
|
||||
from . import RegexpOption, ChoiceOption, ParamOption
|
||||
from .i18n import _
|
||||
|
||||
|
@ -233,8 +233,8 @@ class Requires(object):
|
|||
def add(self, path, childapi, form):
|
||||
#collect id of all options
|
||||
child = childapi.get()
|
||||
if isinstance(child, SynDynOption):
|
||||
child = child.opt
|
||||
# if isinstance(child, SynDynOption):
|
||||
# child = child.opt
|
||||
self.options[child] = path
|
||||
current_action = None
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
from typing import Union, Optional, List, Any
|
||||
from .error import ConfigError
|
||||
from .setting import owners, undefined, forbidden_owners
|
||||
from .autolib import Calculation
|
||||
from .autolib import Calculation, get_calculated_value
|
||||
from .i18n import _
|
||||
|
||||
|
||||
|
@ -106,7 +106,7 @@ class Values:
|
|||
# the value is a default value
|
||||
# get it
|
||||
value = self.get_default_value(subconfig)
|
||||
value, has_calculation = self.get_calculated_value(subconfig,
|
||||
value, has_calculation = get_calculated_value(subconfig,
|
||||
value,
|
||||
)
|
||||
return value, has_calculation
|
||||
|
@ -125,7 +125,7 @@ class Values:
|
|||
return msubconfig.config_bag.context.get_values().get_cached_value(msubconfig)
|
||||
|
||||
# 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(),
|
||||
)
|
||||
if subconfig.index is not None and isinstance(value, (list, tuple)) \
|
||||
|
@ -139,37 +139,13 @@ class Values:
|
|||
else:
|
||||
# no value for this index, retrieve default multi value
|
||||
# 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(),
|
||||
)
|
||||
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
|
||||
return value
|
||||
|
||||
#______________________________________________________________________
|
||||
def check_force_to_metaconfig(self,
|
||||
|
@ -210,7 +186,9 @@ class Values:
|
|||
# calculated value is a new value, so reset cache
|
||||
subconfig.config_bag.context.reset_cache(subconfig)
|
||||
# and manage force_store_value
|
||||
# self._set_force_value_suffix(subconfig)
|
||||
self._set_force_value_suffix(subconfig,
|
||||
value,
|
||||
)
|
||||
|
||||
def isempty(self,
|
||||
subconfig: "SubConfig",
|
||||
|
@ -279,12 +257,14 @@ class Values:
|
|||
elif 'validator' in setting_properties and has_calculation:
|
||||
cache = subconfig.config_bag.context.get_values_cache()
|
||||
cache.delcache(subconfig.path)
|
||||
# if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader():
|
||||
# leader = option_bag.option.impl_get_leadership()
|
||||
# leader.follower_force_store_value(value,
|
||||
# option_bag.config_bag,
|
||||
# owners.forced,
|
||||
# )
|
||||
if 'force_store_value' in setting_properties and subconfig.option.impl_is_leader():
|
||||
leader = subconfig.option.impl_get_leadership()
|
||||
parent = subconfig.parent
|
||||
parent._length = len(value)
|
||||
leader.follower_force_store_value(value,
|
||||
parent,
|
||||
owners.forced,
|
||||
)
|
||||
|
||||
def setvalue_validation(self,
|
||||
subconfig: "SubConfig",
|
||||
|
@ -296,9 +276,8 @@ class Values:
|
|||
# First validate properties with this value
|
||||
opt = subconfig.option
|
||||
settings.validate_frozen(subconfig)
|
||||
val, has_calculation = self.get_calculated_value(subconfig,
|
||||
val, has_calculation = get_calculated_value(subconfig,
|
||||
value,
|
||||
reset_cache=False,
|
||||
)
|
||||
settings.validate_mandatory(subconfig,
|
||||
val,
|
||||
|
@ -327,7 +306,9 @@ class Values:
|
|||
value,
|
||||
owner,
|
||||
)
|
||||
# self._set_force_value_suffix(option_bag)
|
||||
self._set_force_value_suffix(subconfig,
|
||||
value,
|
||||
)
|
||||
|
||||
def set_storage_value(self,
|
||||
path,
|
||||
|
@ -339,47 +320,44 @@ class Values:
|
|||
"""
|
||||
self._values.setdefault(path, {})[index] = [value, owner]
|
||||
|
||||
# def _set_force_value_suffix(self,
|
||||
# option_bag: OptionBag,
|
||||
# ) -> 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:
|
||||
# return
|
||||
#
|
||||
# for woption in option_bag.option._get_suffixes_dependencies(): # pylint: disable=protected-access
|
||||
# # options from dependencies are weakref
|
||||
# option = woption()
|
||||
# force_store_options = []
|
||||
# for coption in option.get_children_recursively(None,
|
||||
# None,
|
||||
# option_bag.config_bag,
|
||||
# option_suffixes=[],
|
||||
# ):
|
||||
# if 'force_store_value' in coption.impl_getproperties():
|
||||
# force_store_options.append(coption)
|
||||
# if not force_store_options:
|
||||
# continue
|
||||
# for coption in force_store_options:
|
||||
# if coption.impl_is_follower():
|
||||
# leader = coption.impl_get_leadership().get_leader()
|
||||
# loption_bag = OptionBag(leader,
|
||||
# None,
|
||||
# option_bag.config_bag,
|
||||
# properties=frozenset(),
|
||||
# )
|
||||
# indexes = range(len(self.get_value(loption_bag)[0]))
|
||||
# else:
|
||||
# indexes = [None]
|
||||
# for index in indexes:
|
||||
# for coption_bag in option.get_sub_children(coption,
|
||||
# option_bag.config_bag,
|
||||
# index=index,
|
||||
# properties=frozenset(),
|
||||
# ):
|
||||
# default_value = [self.get_value(coption_bag)[0], owners.forced]
|
||||
# self._values.setdefault(coption_bag.path, {})[index] = default_value
|
||||
def _set_force_value_suffix(self,
|
||||
subconfig: 'SubConfig',
|
||||
suffix_values,
|
||||
) -> None:
|
||||
""" force store value for an option for suffixes
|
||||
"""
|
||||
# pylint: disable=too-many-locals
|
||||
if 'force_store_value' not in subconfig.config_bag.properties:
|
||||
return
|
||||
|
||||
config_bag = subconfig.config_bag
|
||||
context = config_bag.context
|
||||
for woption in subconfig.option._get_suffixes_dependencies(): # pylint: disable=protected-access
|
||||
options = subconfig.get_common_child(woption(),
|
||||
true_path=subconfig.path,
|
||||
validate_properties=False,
|
||||
)
|
||||
if not isinstance(options, list):
|
||||
options = [options]
|
||||
for option in options:
|
||||
parent = option.parent
|
||||
for suffix in suffix_values:
|
||||
name = option.option.impl_getname(suffix)
|
||||
opt_subconfig = parent.get_child(option.option,
|
||||
None,
|
||||
False,
|
||||
suffix=suffix,
|
||||
name=name,
|
||||
)
|
||||
|
||||
for walk_subconfig in context.walk(opt_subconfig,
|
||||
no_value=True,
|
||||
validate_properties=False,
|
||||
):
|
||||
if 'force_store_value' not in walk_subconfig.properties:
|
||||
continue
|
||||
default_value = [self.get_value(walk_subconfig)[0], owners.forced]
|
||||
self._values.setdefault(walk_subconfig.path, {})[walk_subconfig.index] = default_value
|
||||
|
||||
def _get_modified_parent(self,
|
||||
subconfig: "SubConfig",
|
||||
|
@ -462,9 +440,9 @@ class Values:
|
|||
was present
|
||||
:returns: a `setting.owners.Owner` object
|
||||
"""
|
||||
context = subconfig.config_bag.context
|
||||
settings = context.get_settings()
|
||||
settings.validate_properties(subconfig)
|
||||
# context = subconfig.config_bag.context
|
||||
# settings = context.get_settings()
|
||||
# settings.validate_properties(subconfig)
|
||||
if 'frozen' in subconfig.properties and \
|
||||
'force_default_on_freeze' in subconfig.properties:
|
||||
return owners.default
|
||||
|
@ -509,7 +487,7 @@ class Values:
|
|||
if not self.hasvalue(subconfig.path,
|
||||
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)
|
||||
self._values[subconfig.path][subconfig.index][1] = owner
|
||||
#______________________________________________________________________
|
||||
|
@ -517,14 +495,17 @@ class Values:
|
|||
|
||||
def reset(self,
|
||||
subconfig: "SubConfig",
|
||||
*,
|
||||
validate: bool=True,
|
||||
) -> None:
|
||||
"""reset value for an option
|
||||
"""
|
||||
config_bag = subconfig.config_bag
|
||||
context = config_bag.context
|
||||
hasvalue = self.hasvalue(subconfig.path)
|
||||
context = config_bag.context
|
||||
setting_properties = config_bag.properties
|
||||
if hasvalue and 'validator' in config_bag.properties:
|
||||
if validate:
|
||||
if hasvalue and 'validator' in setting_properties:
|
||||
fake_context = context.gen_fake_context()
|
||||
fake_config_bag = config_bag.copy()
|
||||
fake_config_bag.remove_validation()
|
||||
|
@ -533,7 +514,6 @@ class Values:
|
|||
subconfig.path,
|
||||
subconfig.index,
|
||||
validate_properties=False,
|
||||
follower_not_apply_requires=False,
|
||||
)
|
||||
fake_values = fake_context.get_values()
|
||||
fake_values.reset(fake_subconfig)
|
||||
|
@ -542,11 +522,11 @@ class Values:
|
|||
fake_values.setvalue_validation(fake_subconfig,
|
||||
value,
|
||||
)
|
||||
# if hasvalue:
|
||||
opt = subconfig.option
|
||||
if opt.impl_is_leader():
|
||||
opt.impl_get_leadership().reset(subconfig.parent)
|
||||
if hasvalue:
|
||||
if 'force_store_value' in subconfig.config_bag.properties and \
|
||||
if 'force_store_value' in setting_properties and \
|
||||
'force_store_value' in subconfig.properties:
|
||||
value = self.get_default_value(subconfig)
|
||||
|
||||
|
@ -555,21 +535,18 @@ class Values:
|
|||
owners.forced,
|
||||
)
|
||||
else:
|
||||
# for leader only
|
||||
value = None
|
||||
if subconfig.path in self._values:
|
||||
del self._values[subconfig.path]
|
||||
if 'force_store_value' in setting_properties and subconfig.option.impl_is_leader():
|
||||
if value is None:
|
||||
value = self.get_default_value(subconfig)
|
||||
leader = subconfig.option.impl_get_leadership()
|
||||
leader.follower_force_store_value(value,
|
||||
subconfig.parent,
|
||||
owners.forced,
|
||||
)
|
||||
context.reset_cache(subconfig)
|
||||
# if 'force_store_value' in setting_properties and option_bag.option.impl_is_leader():
|
||||
# if value is None:
|
||||
# value = self.get_default_value(option_bag,
|
||||
# parent,
|
||||
# )
|
||||
# leader = option_bag.option.impl_get_leadership()
|
||||
# leader.follower_force_store_value(value,
|
||||
# option_bag.config_bag,
|
||||
# owners.forced,
|
||||
# )
|
||||
#______________________________________________________________________
|
||||
# Follower
|
||||
|
||||
|
@ -602,7 +579,6 @@ class Values:
|
|||
subconfig.path,
|
||||
subconfig.index,
|
||||
validate_properties=False,
|
||||
follower_not_apply_requires=False,
|
||||
)
|
||||
fake_values = fake_context.get_values()
|
||||
fake_values.reset_follower(fake_subconfig)
|
||||
|
@ -611,17 +587,16 @@ class Values:
|
|||
fake_values.setvalue_validation(fake_subconfig,
|
||||
value,
|
||||
)
|
||||
# if 'force_store_value' in setting_properties and \
|
||||
# 'force_store_value' in option_bag.properties:
|
||||
# value = self.get_default_value(option_bag,
|
||||
# parent,
|
||||
# )
|
||||
#
|
||||
# self._setvalue(option_bag,
|
||||
# value,
|
||||
# owners.forced,
|
||||
# )
|
||||
# else:
|
||||
if 'force_store_value' in setting_properties and \
|
||||
'force_store_value' in subconfig.properties:
|
||||
value = self.get_default_value(subconfig,
|
||||
)
|
||||
|
||||
self._setvalue(subconfig,
|
||||
value,
|
||||
owners.forced,
|
||||
)
|
||||
else:
|
||||
self.resetvalue_index(subconfig)
|
||||
context.reset_cache(subconfig)
|
||||
|
||||
|
@ -688,13 +663,25 @@ class Values:
|
|||
config_bag = subconfig.config_bag
|
||||
context = config_bag.context
|
||||
for key, options in subconfig.option.get_dependencies_information().items():
|
||||
for option in options:
|
||||
option_subconfig = context.get_sub_config(config_bag,
|
||||
if key is None:
|
||||
continue
|
||||
for woption in options:
|
||||
if woption is None:
|
||||
continue
|
||||
option = woption()
|
||||
if option.issubdyn():
|
||||
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,
|
||||
follower_not_apply_requires=False,
|
||||
)
|
||||
)]
|
||||
for option_subconfig in option_subconfigs:
|
||||
context.reset_cache(option_subconfig)
|
||||
|
||||
def get_information(self,
|
||||
|
@ -706,18 +693,25 @@ class Values:
|
|||
|
||||
:param name: the item string (ex: "help")
|
||||
"""
|
||||
if subconfig is None:
|
||||
path = None
|
||||
if subconfig.option.impl_is_symlinkoption():
|
||||
option = subconfig.option.impl_getopt()
|
||||
path = option.impl_getpath()
|
||||
else:
|
||||
option = subconfig.option
|
||||
path = subconfig.path
|
||||
try:
|
||||
return self._informations[path][name]
|
||||
except KeyError as err:
|
||||
if subconfig:
|
||||
return subconfig.option.impl_get_information(name, default)
|
||||
if default is not undefined:
|
||||
return default
|
||||
raise ValueError(_("information's item not found: {0}").format(name)) from err
|
||||
pass
|
||||
if option is not None:
|
||||
return option._get_information(subconfig,
|
||||
name,
|
||||
default,
|
||||
)
|
||||
return subconfig.config_bag.context.get_description()._get_information(subconfig,
|
||||
name,
|
||||
default,
|
||||
)
|
||||
|
||||
def del_information(self,
|
||||
key: Any,
|
||||
|
|
Loading…
Reference in a new issue