dynoptiondescription inside dynoptiondescription
This commit is contained in:
parent
6b473e63f2
commit
90564d4983
13 changed files with 937 additions and 824 deletions
|
@ -38,8 +38,7 @@ def return_list2(suffix):
|
||||||
def return_list(val=None, suffix=None):
|
def return_list(val=None, suffix=None):
|
||||||
if val:
|
if val:
|
||||||
return val
|
return val
|
||||||
else:
|
return ['val1', 'val2']
|
||||||
return ['val1', 'val2']
|
|
||||||
|
|
||||||
|
|
||||||
def return_list_dot(val=None, suffix=None):
|
def return_list_dot(val=None, suffix=None):
|
||||||
|
@ -335,7 +334,7 @@ def test_callback_dyndescription_outside1():
|
||||||
lst = StrOption('lst', '', ['val1', 'val2'], multi=True)
|
lst = StrOption('lst', '', ['val1', 'val2'], multi=True)
|
||||||
st = StrOption('st', '', Calculation(return_dynval))
|
st = StrOption('st', '', Calculation(return_dynval))
|
||||||
dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list, Params(ParamOption(lst))))
|
dod = DynOptionDescription('dod', '', [st], suffixes=Calculation(return_list, Params(ParamOption(lst))))
|
||||||
out = StrOption('out', '', Calculation(return_dynval, Params(ParamDynOption(st, 'val1', dod))))
|
out = StrOption('out', '', Calculation(return_dynval, Params(ParamDynOption(st, 'dodval1.st', dod))))
|
||||||
od = OptionDescription('od', '', [dod, out])
|
od = OptionDescription('od', '', [dod, out])
|
||||||
od2 = OptionDescription('od', '', [od, lst])
|
od2 = OptionDescription('od', '', [od, lst])
|
||||||
cfg = Config(od2)
|
cfg = Config(od2)
|
||||||
|
@ -1628,15 +1627,6 @@ def test_invalid_conflict_dyndescription():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
#def test_invalid_subod_dyndescription():
|
|
||||||
# st2 = StrOption('st2', '')
|
|
||||||
# od1 = OptionDescription('od1', '', [st2])
|
|
||||||
# od1
|
|
||||||
# with pytest.raises(ConfigError):
|
|
||||||
# DynOptionDescription('dod', '', [od1], suffixes=Calculation(return_list))
|
|
||||||
## assert not list_sessions()
|
|
||||||
#
|
|
||||||
#
|
|
||||||
def test_leadership_default_multi_dyndescription():
|
def test_leadership_default_multi_dyndescription():
|
||||||
st1 = StrOption('st1', "", multi=True)
|
st1 = StrOption('st1', "", multi=True)
|
||||||
st2 = StrOption('st2', "", multi=True, default_multi='no')
|
st2 = StrOption('st2', "", multi=True, default_multi='no')
|
||||||
|
@ -1671,15 +1661,223 @@ def test_leadership_default_multi_dyndescription():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_subdynod_dyndescription():
|
def test_subdynod_dyndescription_root():
|
||||||
st2 = StrOption('st2', '')
|
st2 = StrOption('st2', '')
|
||||||
od1 = DynOptionDescription('od1', '', [st2], suffixes=Calculation(return_list))
|
dod1 = DynOptionDescription('dod1', '', [st2], suffixes=Calculation(return_list, Params(ParamValue(['a', 'b']))))
|
||||||
od1
|
dod = DynOptionDescription('dod', '', [dod1], suffixes=Calculation(return_list))
|
||||||
with pytest.raises(ConfigError):
|
st3 = StrOption('st3', '', Calculation(return_dynval, Params(ParamDynOption(st2, 'dodval1.dod1a.st2', dod))))
|
||||||
DynOptionDescription('dod', '', [od1], suffixes=Calculation(return_list))
|
# FIXME st4 = StrOption('st4', '', Calculation(return_dynval, Params(ParamOption(st2))), multi=True)
|
||||||
|
od1 = OptionDescription('od', '', [dod, st3]) #, st4])
|
||||||
|
cfg = Config(od1)
|
||||||
|
assert cfg.value.get() == {'dodval1.dod1a.st2': None,
|
||||||
|
'dodval1.dod1b.st2': None,
|
||||||
|
'dodval2.dod1a.st2': None,
|
||||||
|
'dodval2.dod1b.st2': None,
|
||||||
|
'st3': None,
|
||||||
|
}
|
||||||
|
assert cfg.option('dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('dodval1.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() is None
|
||||||
|
#
|
||||||
|
cfg.option('dodval1.dod1a.st2').value.set('val')
|
||||||
|
assert cfg.value.get() == {'dodval1.dod1a.st2': 'val',
|
||||||
|
'dodval1.dod1b.st2': None,
|
||||||
|
'dodval2.dod1a.st2': None,
|
||||||
|
'dodval2.dod1b.st2': None,
|
||||||
|
'st3': 'val',
|
||||||
|
}
|
||||||
|
assert not cfg.option('dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('dodval1.dod1a.st2').value.get() == 'val'
|
||||||
|
assert cfg.option('dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() == 'val'
|
||||||
|
#
|
||||||
|
cfg.option('dodval2.dod1a.st2').value.reset()
|
||||||
|
assert cfg.value.get() == {'dodval1.dod1a.st2': 'val',
|
||||||
|
'dodval1.dod1b.st2': None,
|
||||||
|
'dodval2.dod1a.st2': None,
|
||||||
|
'dodval2.dod1b.st2': None,
|
||||||
|
'st3': 'val',
|
||||||
|
}
|
||||||
|
assert not cfg.option('dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('dodval1.dod1a.st2').value.get() == 'val'
|
||||||
|
assert cfg.option('dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() == 'val'
|
||||||
|
#
|
||||||
|
cfg.option('dodval1.dod1a.st2').value.reset()
|
||||||
|
assert cfg.value.get() == {'dodval1.dod1a.st2': None,
|
||||||
|
'dodval1.dod1b.st2': None,
|
||||||
|
'dodval2.dod1a.st2': None,
|
||||||
|
'dodval2.dod1b.st2': None,
|
||||||
|
'st3': None,
|
||||||
|
}
|
||||||
|
assert cfg.option('dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('dodval1.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() is None
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
def test_subdynod_dyndescription():
|
||||||
|
st2 = StrOption('st2', '')
|
||||||
|
dod1 = DynOptionDescription('dod1', '', [st2], suffixes=Calculation(return_list, Params(ParamValue(['a', 'b']))))
|
||||||
|
dod = DynOptionDescription('dod', '', [dod1], suffixes=Calculation(return_list))
|
||||||
|
od1 = OptionDescription('od', '', [dod])
|
||||||
|
st3 = StrOption('st3', '', Calculation(return_dynval, Params(ParamDynOption(st2, 'dodval1.dod1a.st2', dod))))
|
||||||
|
od = OptionDescription('od', '', [od1, st3]) #, st4])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.get() == {'od.dodval1.dod1a.st2': None,
|
||||||
|
'od.dodval1.dod1b.st2': None,
|
||||||
|
'od.dodval2.dod1a.st2': None,
|
||||||
|
'od.dodval2.dod1b.st2': None,
|
||||||
|
'st3': None,
|
||||||
|
}
|
||||||
|
assert cfg.option('od.dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('od.dodval1.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() is None
|
||||||
|
#
|
||||||
|
cfg.option('od.dodval1.dod1a.st2').value.set('val')
|
||||||
|
assert cfg.value.get() == {'od.dodval1.dod1a.st2': 'val',
|
||||||
|
'od.dodval1.dod1b.st2': None,
|
||||||
|
'od.dodval2.dod1a.st2': None,
|
||||||
|
'od.dodval2.dod1b.st2': None,
|
||||||
|
'st3': 'val',
|
||||||
|
}
|
||||||
|
assert not cfg.option('od.dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('od.dodval1.dod1a.st2').value.get() == 'val'
|
||||||
|
assert cfg.option('od.dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() == 'val'
|
||||||
|
#
|
||||||
|
cfg.option('od.dodval2.dod1a.st2').value.reset()
|
||||||
|
assert cfg.value.get() == {'od.dodval1.dod1a.st2': 'val',
|
||||||
|
'od.dodval1.dod1b.st2': None,
|
||||||
|
'od.dodval2.dod1a.st2': None,
|
||||||
|
'od.dodval2.dod1b.st2': None,
|
||||||
|
'st3': 'val',
|
||||||
|
}
|
||||||
|
assert not cfg.option('od.dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('od.dodval1.dod1a.st2').value.get() == 'val'
|
||||||
|
assert cfg.option('od.dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() == 'val'
|
||||||
|
#
|
||||||
|
cfg.option('od.dodval1.dod1a.st2').value.reset()
|
||||||
|
assert cfg.value.get() == {'od.dodval1.dod1a.st2': None,
|
||||||
|
'od.dodval1.dod1b.st2': None,
|
||||||
|
'od.dodval2.dod1a.st2': None,
|
||||||
|
'od.dodval2.dod1b.st2': None,
|
||||||
|
'st3': None,
|
||||||
|
}
|
||||||
|
assert cfg.option('od.dodval1.dod1a.st2').owner.isdefault()
|
||||||
|
assert cfg.option('od.dodval1.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('st3').value.get() is None
|
||||||
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
#FIXME une option dans une dyn qui est utilisé pour calculé dans une subdyn DOIT être dans le meme répertoire pour le moment !
|
||||||
|
def test_subdynod_dyndescription_2():
|
||||||
|
st2 = StrOption('st2', '')
|
||||||
|
st1 = StrOption('st1', '', default=['a', 'b'], multi=True)
|
||||||
|
dod1 = DynOptionDescription('dod1', '', [st2], suffixes=Calculation(return_list, Params(ParamOption(st1))))
|
||||||
|
dod = DynOptionDescription('dod', '', [dod1, st1], suffixes=Calculation(return_list))
|
||||||
|
od1 = OptionDescription('od', '', [dod])
|
||||||
|
st3 = StrOption('st3', '', Calculation(return_dynval, Params(ParamDynOption(st2, 'dodval1.dod1a.st2', dod))))
|
||||||
|
od = OptionDescription('od', '', [od1, st3]) #, st4])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.get() == {'od.dodval1.dod1a.st2': None,
|
||||||
|
'od.dodval1.dod1b.st2': None,
|
||||||
|
'od.dodval1.st1': ['a', 'b'],
|
||||||
|
'od.dodval2.dod1a.st2': None,
|
||||||
|
'od.dodval2.dod1b.st2': None,
|
||||||
|
'od.dodval2.st1': ['a', 'b'],
|
||||||
|
'st3': None,
|
||||||
|
}
|
||||||
|
cfg.cache.reset()
|
||||||
|
assert cfg.option('od.dodval1.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval1.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval1.st1').value.get() == ['a', 'b']
|
||||||
|
assert cfg.option('od.dodval2.dod1a.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.dod1b.st2').value.get() is None
|
||||||
|
assert cfg.option('od.dodval2.st1').value.get() == ['a', 'b']
|
||||||
|
assert cfg.option('st3').value.get() is None
|
||||||
|
#
|
||||||
|
cfg.option('od.dodval1.st1').value.set(['a'])
|
||||||
|
cfg.option('od.dodval2.st1').value.set(['b', 'c'])
|
||||||
|
assert cfg.value.get() == {'od.dodval1.st1': ['a'],
|
||||||
|
'od.dodval1.dod1a.st2': None,
|
||||||
|
'od.dodval2.st1': ['b', 'c'],
|
||||||
|
'od.dodval2.dod1b.st2': None,
|
||||||
|
'od.dodval2.dod1c.st2': None,
|
||||||
|
'st3': None,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_subdynod_dyndescription_leadership():
|
||||||
|
st1 = StrOption('st1', '', multi=True)
|
||||||
|
st2 = StrOption('st2', '', multi=True)
|
||||||
|
stm = Leadership('stm', '', [st1, st2])
|
||||||
|
dod1 = DynOptionDescription('dod1', '', [stm], suffixes=Calculation(return_list, Params(ParamValue(['a', 'b']))))
|
||||||
|
dod = DynOptionDescription('dod', '', [dod1], suffixes=Calculation(return_list))
|
||||||
|
od1 = OptionDescription('od', '', [dod])
|
||||||
|
st3 = StrOption('st3', '', Calculation(return_dynval, Params(ParamDynOption(st1, 'dodval1.dod1a.stm.st1', dod))), multi=True)
|
||||||
|
# FIXME st4 = StrOption('st4', '', Calculation(return_dynval, Params(ParamOption(st2))), multi=True)
|
||||||
|
st5 = StrOption('st5', '', Calculation(return_dynval, Params(ParamDynOption(st2, 'dodval1.dod1a.stm.st2', dod))), multi=True)
|
||||||
|
#cfg = Config(od1)
|
||||||
|
#FIXME
|
||||||
|
od = OptionDescription('od', '', [od1, st3 , st5]) #, st4])
|
||||||
|
cfg = Config(od)
|
||||||
|
assert cfg.value.get() == {'od.dodval1.dod1a.stm.st1': [],
|
||||||
|
'od.dodval1.dod1b.stm.st1': [],
|
||||||
|
'od.dodval2.dod1a.stm.st1': [],
|
||||||
|
'od.dodval2.dod1b.stm.st1': [],
|
||||||
|
'st3': [],
|
||||||
|
'st5': [],
|
||||||
|
}
|
||||||
|
assert cfg.option('od.dodval1.dod1a.stm.st1').owner.isdefault()
|
||||||
|
assert cfg.option('od.dodval1.dod1a.stm.st1').value.get() == []
|
||||||
|
assert cfg.option('od.dodval1.dod1b.stm.st1').value.get() == []
|
||||||
|
assert cfg.option('od.dodval2.dod1a.stm.st1').value.get() == []
|
||||||
|
assert cfg.option('od.dodval2.dod1b.stm.st1').value.get() == []
|
||||||
|
assert cfg.option('od.dodval2.dod1b.stm.st1').value.get() == []
|
||||||
|
assert cfg.option('st3').value.get() == []
|
||||||
|
assert cfg.option('st5').value.get() == []
|
||||||
|
#
|
||||||
|
cfg.option('od.dodval1.dod1a.stm.st1').value.set(['val'])
|
||||||
|
assert cfg.option('st3').value.get() == ['val']
|
||||||
|
assert cfg.value.get() == {'od.dodval1.dod1a.stm.st1': [{'od.dodval1.dod1a.stm.st1': 'val',
|
||||||
|
'od.dodval1.dod1a.stm.st2': None}],
|
||||||
|
'od.dodval1.dod1b.stm.st1': [],
|
||||||
|
'od.dodval2.dod1a.stm.st1': [],
|
||||||
|
'od.dodval2.dod1b.stm.st1': [],
|
||||||
|
'st3': ['val'],
|
||||||
|
'st5': [],
|
||||||
|
}
|
||||||
|
assert not cfg.option('od.dodval1.dod1a.stm.st1').owner.isdefault()
|
||||||
|
assert cfg.option('od.dodval1.dod1a.stm.st1').value.get() == ['val']
|
||||||
|
assert cfg.option('od.dodval1.dod1b.stm.st1').value.get() == []
|
||||||
|
assert cfg.option('od.dodval2.dod1a.stm.st1').value.get() == []
|
||||||
|
assert cfg.option('od.dodval2.dod1b.stm.st1').value.get() == []
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_symlink_dyndescription():
|
def test_invalid_symlink_dyndescription():
|
||||||
st = StrOption('st', '')
|
st = StrOption('st', '')
|
||||||
st2 = SymLinkOption('st2', st)
|
st2 = SymLinkOption('st2', st)
|
||||||
|
|
|
@ -270,7 +270,7 @@ class _TiramisuOptionOptionDescription:
|
||||||
"""Get dependencies from this option"""
|
"""Get dependencies from this option"""
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
options = []
|
options = []
|
||||||
for option in option_bag.option._get_dependencies(self._config_bag.context):
|
for option in option_bag.option.get_dependencies(self._config_bag.context):
|
||||||
options.append(TiramisuOption(option().impl_getpath(),
|
options.append(TiramisuOption(option().impl_getpath(),
|
||||||
None,
|
None,
|
||||||
self._config_bag,
|
self._config_bag,
|
||||||
|
@ -1039,8 +1039,8 @@ class TiramisuContextProperty(TiramisuConfig):
|
||||||
return self._config_bag.properties
|
return self._config_bag.properties
|
||||||
|
|
||||||
def _set(self,
|
def _set(self,
|
||||||
props,
|
props,
|
||||||
):
|
):
|
||||||
"""Personalise config properties"""
|
"""Personalise config properties"""
|
||||||
if 'force_store_value' in props:
|
if 'force_store_value' in props:
|
||||||
force_store_value = 'force_store_value' not in self._config_bag.properties
|
force_store_value = 'force_store_value' not in self._config_bag.properties
|
||||||
|
|
|
@ -82,10 +82,10 @@ class ParamOption(Param):
|
||||||
|
|
||||||
|
|
||||||
class ParamDynOption(ParamOption):
|
class ParamDynOption(ParamOption):
|
||||||
__slots__ = ('suffix',)
|
__slots__ = ('subpath',)
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
option: 'Option',
|
option: 'Option',
|
||||||
suffix: str,
|
subpath: str,
|
||||||
dynoptiondescription: 'DynOptionDescription',
|
dynoptiondescription: 'DynOptionDescription',
|
||||||
notraisepropertyerror: bool=False,
|
notraisepropertyerror: bool=False,
|
||||||
raisepropertyerror: bool=False,
|
raisepropertyerror: bool=False,
|
||||||
|
@ -95,7 +95,7 @@ class ParamDynOption(ParamOption):
|
||||||
notraisepropertyerror,
|
notraisepropertyerror,
|
||||||
raisepropertyerror,
|
raisepropertyerror,
|
||||||
)
|
)
|
||||||
self.suffix = suffix
|
self.subpath = subpath
|
||||||
self.dynoptiondescription = dynoptiondescription
|
self.dynoptiondescription = dynoptiondescription
|
||||||
self.optional = optional
|
self.optional = optional
|
||||||
|
|
||||||
|
@ -430,22 +430,65 @@ def manager_callback(callback: Callable,
|
||||||
if callbk_option.issubdyn():
|
if callbk_option.issubdyn():
|
||||||
found = False
|
found = False
|
||||||
if isinstance(param, ParamDynOption):
|
if isinstance(param, ParamDynOption):
|
||||||
soption_bag = param.dynoptiondescription.get_sub_child(callbk_option,
|
od_path = param.dynoptiondescription.impl_getpath()
|
||||||
param.suffix,
|
if "." in od_path:
|
||||||
config_bag,
|
rootpath = od_path.rsplit('.', 1)[0] + '.'
|
||||||
)
|
else:
|
||||||
callbk_option = soption_bag.option
|
rootpath = ''
|
||||||
|
full_path = rootpath + param.subpath
|
||||||
|
root_option_bag = OptionBag(config_bag.context.get_description(),
|
||||||
|
None,
|
||||||
|
config_bag,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
soptions_bag = config_bag.context.get_sub_option_bag(root_option_bag,
|
||||||
|
full_path,
|
||||||
|
#FIXME index?
|
||||||
|
index=None,
|
||||||
|
validate_properties=True,
|
||||||
|
properties=None,
|
||||||
|
)
|
||||||
|
except AttributeError as err:
|
||||||
|
raise ConfigError(_(f'option "{option.impl_get_display_name()}" is not in a dynoptiondescription: {err}'))
|
||||||
|
callbk_option = soptions_bag[-1].option
|
||||||
found = True
|
found = True
|
||||||
|
elif option.impl_is_sub_dyn_optiondescription():
|
||||||
|
if option.getsubdyn() == callbk_option.getsubdyn():
|
||||||
|
root_path = option.impl_getpath().rsplit('.', 1)[0]
|
||||||
|
len_path = root_path.count('.')
|
||||||
|
full_path = root_path + '.' + callbk_option.impl_getpath().split('.', len_path + 1)[-1]
|
||||||
|
root_option_bag = OptionBag(config_bag.context.get_description(),
|
||||||
|
None,
|
||||||
|
config_bag,
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
soptions_bag = config_bag.context.get_sub_option_bag(root_option_bag,
|
||||||
|
full_path,
|
||||||
|
#FIXME index?
|
||||||
|
index=None,
|
||||||
|
validate_properties=True,
|
||||||
|
properties=None,
|
||||||
|
)
|
||||||
|
except AttributeError as err:
|
||||||
|
raise ConfigError(_(f'option "{option.impl_get_display_name()}" is not in a dynoptiondescription: {err}'))
|
||||||
|
callbk_option = soptions_bag[-1].option
|
||||||
|
found = True
|
||||||
elif option.impl_is_dynsymlinkoption():
|
elif option.impl_is_dynsymlinkoption():
|
||||||
rootpath = option.rootpath
|
rootpath = option.rootpath
|
||||||
call_path = callbk_option.impl_getpath()
|
call_path = callbk_option.impl_getpath()
|
||||||
if call_path.startswith(option.opt.impl_getpath().rsplit('.', 1)[0]):
|
if option.opt.issubdyn() and callbk_option.getsubdyn() == option.getsubdyn() or \
|
||||||
|
not option.opt.issubdyn() and callbk_option.getsubdyn() == option.opt:
|
||||||
# in same dynoption
|
# in same dynoption
|
||||||
if len(callbk_option.impl_getpath().split('.')) == len(rootpath.split('.')):
|
|
||||||
rootpath = rootpath.rsplit('.', 1)[0]
|
|
||||||
suffix = option.impl_getsuffix()
|
suffix = option.impl_getsuffix()
|
||||||
subdyn = callbk_option.getsubdyn()
|
subdyn = callbk_option.getsubdyn()
|
||||||
callbk_option = callbk_option.to_dynoption(rootpath,
|
root_path, sub_path = subdyn.split_path(subdyn,
|
||||||
|
option,
|
||||||
|
)
|
||||||
|
if root_path:
|
||||||
|
parent_path = root_path + subdyn.impl_getname(suffix) + sub_path
|
||||||
|
else:
|
||||||
|
parent_path = subdyn.impl_getname(suffix) + sub_path
|
||||||
|
callbk_option = callbk_option.to_dynoption(parent_path,
|
||||||
suffix,
|
suffix,
|
||||||
subdyn,
|
subdyn,
|
||||||
)
|
)
|
||||||
|
@ -454,7 +497,7 @@ def manager_callback(callback: Callable,
|
||||||
callbk_options = []
|
callbk_options = []
|
||||||
for doption_bag in callbk_option.getsubdyn().get_sub_children(callbk_option,
|
for doption_bag in callbk_option.getsubdyn().get_sub_children(callbk_option,
|
||||||
config_bag,
|
config_bag,
|
||||||
None,
|
index=None,
|
||||||
):
|
):
|
||||||
callbk_options.append(doption_bag.option)
|
callbk_options.append(doption_bag.option)
|
||||||
if callbk_options is None:
|
if callbk_options is None:
|
||||||
|
@ -476,6 +519,8 @@ def manager_callback(callback: Callable,
|
||||||
else:
|
else:
|
||||||
index_ = None
|
index_ = None
|
||||||
with_index = False
|
with_index = False
|
||||||
|
if callbk_option.impl_getpath() == 'od.dodval1.st.boolean':
|
||||||
|
raise Exception('pfff')
|
||||||
value = get_value(config_bag,
|
value = get_value(config_bag,
|
||||||
callbk_option,
|
callbk_option,
|
||||||
param,
|
param,
|
||||||
|
|
|
@ -27,6 +27,7 @@ from typing import Optional, List, Any, Union
|
||||||
from .error import PropertiesOptionError, ConfigError, ConflictError, \
|
from .error import PropertiesOptionError, ConfigError, ConflictError, \
|
||||||
LeadershipError
|
LeadershipError
|
||||||
from .option import DynOptionDescription, Leadership, Option
|
from .option import DynOptionDescription, Leadership, Option
|
||||||
|
from .option.syndynoptiondescription import SubDynOptionDescription
|
||||||
from .setting import OptionBag, ConfigBag, Settings, undefined, groups
|
from .setting import OptionBag, ConfigBag, Settings, undefined, groups
|
||||||
from .value import Values, owners
|
from .value import Values, owners
|
||||||
from .i18n import _
|
from .i18n import _
|
||||||
|
@ -130,26 +131,74 @@ class _SubConfig:
|
||||||
if option_bag.path in resetted_opts:
|
if option_bag.path in resetted_opts:
|
||||||
return
|
return
|
||||||
resetted_opts.append(option_bag.path)
|
resetted_opts.append(option_bag.path)
|
||||||
for woption in option_bag.option._get_dependencies(option_bag.option): # pylint: disable=protected-access
|
for woption in option_bag.option.get_dependencies(option_bag.option):
|
||||||
option = woption()
|
option = woption()
|
||||||
soption_bag = OptionBag(option,
|
if woption in option_bag.option._get_suffixes_dependencies() and \
|
||||||
option_bag.index,
|
option_bag.option.issubdyn() and \
|
||||||
option_bag.config_bag,
|
option.impl_is_dynoptiondescription():
|
||||||
properties=None,
|
paths = [subdyn().impl_getpath() for subdyn in option.get_sub_dyns()]
|
||||||
)
|
for weak_subdyn in option_bag.option.get_sub_dyns():
|
||||||
if option.impl_is_dynoptiondescription():
|
subdyn = weak_subdyn()
|
||||||
self._reset_cache_dyn_optiondescription(soption_bag,
|
if subdyn.impl_getpath() in paths:
|
||||||
resetted_opts,
|
root_path = option_bag.option.impl_getpath()
|
||||||
)
|
if '.' in root_path:
|
||||||
elif option.issubdyn():
|
root_path = root_path.rsplit('.', 1)[0]
|
||||||
# it's an option in dynoptiondescription, remove cache for all generated option
|
nb_elt = root_path.count('.') + 1
|
||||||
self._reset_cache_dyn_option(soption_bag,
|
else:
|
||||||
resetted_opts,
|
root_path = ''
|
||||||
)
|
nb_elt = 1
|
||||||
|
config_bag = option_bag.config_bag
|
||||||
|
root_option_bag = OptionBag(config_bag.context.get_description(),
|
||||||
|
None,
|
||||||
|
config_bag,
|
||||||
|
)
|
||||||
|
full_path = root_path + '.' + option.impl_getpath().split('.', nb_elt)[-1]
|
||||||
|
try:
|
||||||
|
options_bag = config_bag.context.get_sub_option_bag(root_option_bag,
|
||||||
|
full_path,
|
||||||
|
#FIXME index?
|
||||||
|
None,
|
||||||
|
validate_properties=False,
|
||||||
|
properties=None,
|
||||||
|
allow_dynoption=True,
|
||||||
|
)
|
||||||
|
except AttributeError as err:
|
||||||
|
raise ConfigError(_(f'option "{option.impl_get_display_name()}" is not in a dynoptiondescription: {err}'))
|
||||||
|
self._reset_cache_dyn_optiondescription(options_bag[-1],
|
||||||
|
resetted_opts,
|
||||||
|
)
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
self.reset_one_option_cache(resetted_opts,
|
soption_bag = OptionBag(option,
|
||||||
soption_bag,
|
option_bag.index,
|
||||||
)
|
option_bag.config_bag,
|
||||||
|
properties=None,
|
||||||
|
)
|
||||||
|
if option.impl_is_dynoptiondescription():
|
||||||
|
self._reset_cache_dyn_optiondescription(soption_bag,
|
||||||
|
resetted_opts,
|
||||||
|
)
|
||||||
|
elif option.issubdyn():
|
||||||
|
# it's an option in dynoptiondescription, remove cache for all generated option
|
||||||
|
config_bag = option_bag.config_bag
|
||||||
|
options = [soption_bag]
|
||||||
|
for wdynopt in reversed(option.get_sub_dyns()):
|
||||||
|
dynopt = wdynopt()
|
||||||
|
sub_options = []
|
||||||
|
for sub_option in options:
|
||||||
|
sub_options.extend(dynopt.get_sub_children(sub_option.option,
|
||||||
|
config_bag,
|
||||||
|
properties=None,
|
||||||
|
))
|
||||||
|
options = sub_options
|
||||||
|
for doption_bag in options:
|
||||||
|
self.reset_one_option_cache(resetted_opts,
|
||||||
|
doption_bag,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.reset_one_option_cache(resetted_opts,
|
||||||
|
soption_bag,
|
||||||
|
)
|
||||||
del option
|
del option
|
||||||
option_bag.option.reset_cache(option_bag.path,
|
option_bag.option.reset_cache(option_bag.path,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
|
@ -163,7 +212,7 @@ class _SubConfig:
|
||||||
# reset cache for all chidren
|
# reset cache for all chidren
|
||||||
for doption_bag in option_bag.option.get_sub_children(option_bag.option,
|
for doption_bag in option_bag.option.get_sub_children(option_bag.option,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
option_bag.index,
|
index=option_bag.index,
|
||||||
properties=None,
|
properties=None,
|
||||||
):
|
):
|
||||||
for coption in doption_bag.option.get_children_recursively(None,
|
for coption in doption_bag.option.get_children_recursively(None,
|
||||||
|
@ -187,13 +236,13 @@ class _SubConfig:
|
||||||
resetted_opts,
|
resetted_opts,
|
||||||
):
|
):
|
||||||
option = option_bag.option
|
option = option_bag.option
|
||||||
if isinstance(option, DynOptionDescription):
|
if isinstance(option, (DynOptionDescription, SubDynOptionDescription)):
|
||||||
dynoption = option
|
dynoption = option
|
||||||
else:
|
else:
|
||||||
dynoption = option.getsubdyn()
|
dynoption = option.getsubdyn()
|
||||||
for doption_bag in dynoption.get_sub_children(option,
|
for doption_bag in dynoption.get_sub_children(option,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
option_bag.index,
|
index=option_bag.index,
|
||||||
properties=None
|
properties=None
|
||||||
):
|
):
|
||||||
self.reset_one_option_cache(resetted_opts,
|
self.reset_one_option_cache(resetted_opts,
|
||||||
|
@ -467,7 +516,7 @@ class _SubConfig:
|
||||||
dynopt = suboption.getsubdyn()
|
dynopt = suboption.getsubdyn()
|
||||||
return list(dynopt.get_sub_children(suboption,
|
return list(dynopt.get_sub_children(suboption,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
option_bag.index,
|
index=option_bag.index,
|
||||||
))
|
))
|
||||||
if suboption.impl_is_follower():
|
if suboption.impl_is_follower():
|
||||||
options_bag = self.get_sub_option_bag(option_bag.config_bag, # pylint: disable=no-member
|
options_bag = self.get_sub_option_bag(option_bag.config_bag, # pylint: disable=no-member
|
||||||
|
@ -679,11 +728,14 @@ class _CommonConfig(_SubConfig):
|
||||||
index: Optional[int],
|
index: Optional[int],
|
||||||
validate_properties: bool,
|
validate_properties: bool,
|
||||||
leadership_length: int=None,
|
leadership_length: int=None,
|
||||||
|
*,
|
||||||
properties=undefined,
|
properties=undefined,
|
||||||
follower_not_apply_requires: bool=False,
|
follower_not_apply_requires: bool=False,
|
||||||
|
allow_dynoption: bool=False,
|
||||||
) -> List[OptionBag]:
|
) -> List[OptionBag]:
|
||||||
"""Get the suboption for path and the name of the option
|
"""Get the suboption for path and the name of the option
|
||||||
:returns: tuple (config, name)"""
|
:returns: option_bag
|
||||||
|
"""
|
||||||
# pylint: disable=too-many-branches,too-many-locals,too-many-arguments
|
# pylint: disable=too-many-branches,too-many-locals,too-many-arguments
|
||||||
if isinstance(bag, ConfigBag):
|
if isinstance(bag, ConfigBag):
|
||||||
option_bag = OptionBag(self.get_description(),
|
option_bag = OptionBag(self.get_description(),
|
||||||
|
@ -710,6 +762,7 @@ class _CommonConfig(_SubConfig):
|
||||||
option = suboption.get_child(step,
|
option = suboption.get_child(step,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
subpath,
|
subpath,
|
||||||
|
allow_dynoption=allow_dynoption,
|
||||||
)
|
)
|
||||||
if idx == last_idx:
|
if idx == last_idx:
|
||||||
option_index = index
|
option_index = index
|
||||||
|
|
|
@ -551,7 +551,7 @@ msgstr "ne doit pas être une IP"
|
||||||
|
|
||||||
#: tiramisu/option/domainnameoption.py:139
|
#: tiramisu/option/domainnameoption.py:139
|
||||||
msgid "must have dot"
|
msgid "must have dot"
|
||||||
msgstr "doit avec un point"
|
msgstr "doit avoir un point"
|
||||||
|
|
||||||
#: tiramisu/option/domainnameoption.py:141
|
#: tiramisu/option/domainnameoption.py:141
|
||||||
msgid "invalid length (max 255)"
|
msgid "invalid length (max 255)"
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -53,7 +53,7 @@ class Base:
|
||||||
__slots__ = ('_name',
|
__slots__ = ('_name',
|
||||||
'_path',
|
'_path',
|
||||||
'_informations',
|
'_informations',
|
||||||
'_subdyn',
|
'_subdyns',
|
||||||
'_properties',
|
'_properties',
|
||||||
'_has_dependency',
|
'_has_dependency',
|
||||||
'_dependencies',
|
'_dependencies',
|
||||||
|
@ -106,9 +106,9 @@ class Base:
|
||||||
return getattr(self, '_has_dependency', False)
|
return getattr(self, '_has_dependency', False)
|
||||||
return hasattr(self, '_dependencies')
|
return hasattr(self, '_dependencies')
|
||||||
|
|
||||||
def _get_dependencies(self,
|
def get_dependencies(self,
|
||||||
context_od,
|
context_od,
|
||||||
) -> Set[str]:
|
) -> Set[str]:
|
||||||
ret = set(getattr(self, '_dependencies', STATIC_TUPLE))
|
ret = set(getattr(self, '_dependencies', STATIC_TUPLE))
|
||||||
if context_od and hasattr(context_od, '_dependencies'):
|
if context_od and hasattr(context_od, '_dependencies'):
|
||||||
# add options that have context is set in calculation
|
# add options that have context is set in calculation
|
||||||
|
@ -123,7 +123,7 @@ class Base:
|
||||||
is_suffix: bool=False,
|
is_suffix: bool=False,
|
||||||
) -> None:
|
) -> None:
|
||||||
woption = weakref.ref(option)
|
woption = weakref.ref(option)
|
||||||
options = self._get_dependencies(None)
|
options = self.get_dependencies(None)
|
||||||
options.add(woption)
|
options.add(woption)
|
||||||
self._dependencies = tuple(options) # pylint: disable=attribute-defined-outside-init
|
self._dependencies = tuple(options) # pylint: disable=attribute-defined-outside-init
|
||||||
if is_suffix:
|
if is_suffix:
|
||||||
|
@ -141,6 +141,9 @@ class Base:
|
||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def impl_is_sub_dyn_optiondescription(self):
|
||||||
|
return False
|
||||||
|
|
||||||
def impl_getname(self) -> str:
|
def impl_getname(self) -> str:
|
||||||
"""get name
|
"""get name
|
||||||
"""
|
"""
|
||||||
|
@ -175,17 +178,22 @@ class Base:
|
||||||
subdyn,
|
subdyn,
|
||||||
) -> None:
|
) -> None:
|
||||||
# pylint: disable=attribute-defined-outside-init
|
# pylint: disable=attribute-defined-outside-init
|
||||||
self._subdyn = subdyn
|
if getattr(self, '_subdyns', None) is None:
|
||||||
|
self._subdyns = []
|
||||||
|
self._subdyns.append(subdyn)
|
||||||
|
|
||||||
def issubdyn(self) -> bool:
|
def issubdyn(self) -> bool:
|
||||||
"""is sub dynoption
|
"""is sub dynoption
|
||||||
"""
|
"""
|
||||||
return getattr(self, '_subdyn', None) is not None
|
return getattr(self, '_subdyns', None) is not None
|
||||||
|
|
||||||
def getsubdyn(self):
|
def getsubdyn(self):
|
||||||
"""get sub dynoption
|
"""get sub dynoption
|
||||||
"""
|
"""
|
||||||
return self._subdyn()
|
return self._subdyns[0]()
|
||||||
|
|
||||||
|
def get_sub_dyns(self):
|
||||||
|
return self._subdyns
|
||||||
|
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
# information
|
# information
|
||||||
|
@ -251,7 +259,8 @@ class BaseOption(Base):
|
||||||
|
|
||||||
def __setattr__(self,
|
def __setattr__(self,
|
||||||
name: str,
|
name: str,
|
||||||
value: Any) -> Any:
|
value: Any,
|
||||||
|
) -> Any:
|
||||||
"""set once and only once some attributes in the option,
|
"""set once and only once some attributes in the option,
|
||||||
like `_name`. `_name` cannot be changed once the option is
|
like `_name`. `_name` cannot be changed once the option is
|
||||||
pushed in the :class:`tiramisu.option.OptionDescription`.
|
pushed in the :class:`tiramisu.option.OptionDescription`.
|
||||||
|
|
|
@ -22,13 +22,14 @@
|
||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
import weakref
|
import weakref
|
||||||
from typing import List, Any, Optional
|
from typing import List, Any, Optional, Tuple
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from ..autolib import ParamOption
|
from ..autolib import ParamOption
|
||||||
|
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from .optiondescription import OptionDescription
|
from .optiondescription import OptionDescription
|
||||||
|
from .syndynoptiondescription import SynDynLeadership
|
||||||
from .baseoption import BaseOption
|
from .baseoption import BaseOption
|
||||||
from ..setting import OptionBag, ConfigBag, undefined
|
from ..setting import OptionBag, ConfigBag, undefined
|
||||||
from ..error import ConfigError
|
from ..error import ConfigError
|
||||||
|
@ -41,7 +42,9 @@ NAME_REGEXP = re.compile(r'^[a-zA-Z\d\-_]*$')
|
||||||
class DynOptionDescription(OptionDescription):
|
class DynOptionDescription(OptionDescription):
|
||||||
"""dyn option description
|
"""dyn option description
|
||||||
"""
|
"""
|
||||||
__slots__ = ('_suffixes',)
|
__slots__ = ('_suffixes',
|
||||||
|
'_subdyns',
|
||||||
|
)
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
name: str,
|
||||||
|
@ -85,10 +88,15 @@ class DynOptionDescription(OptionDescription):
|
||||||
|
|
||||||
def get_suffixes(self,
|
def get_suffixes(self,
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
|
dynoption=None,
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
"""get dynamic suffixes
|
"""get dynamic suffixes
|
||||||
"""
|
"""
|
||||||
option_bag = OptionBag(self,
|
if dynoption:
|
||||||
|
self_opt = dynoption
|
||||||
|
else:
|
||||||
|
self_opt = self
|
||||||
|
option_bag = OptionBag(self_opt,
|
||||||
None,
|
None,
|
||||||
config_bag,
|
config_bag,
|
||||||
properties=None,
|
properties=None,
|
||||||
|
@ -119,70 +127,69 @@ class DynOptionDescription(OptionDescription):
|
||||||
def impl_is_dynoptiondescription(self) -> bool:
|
def impl_is_dynoptiondescription(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def option_is_self(self,
|
||||||
|
option,
|
||||||
|
) -> bool:
|
||||||
|
return option == self or \
|
||||||
|
(option.impl_is_sub_dyn_optiondescription() and option.opt == self)
|
||||||
|
|
||||||
|
def split_path(self,
|
||||||
|
dynoption,
|
||||||
|
option,
|
||||||
|
) -> 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
|
||||||
|
|
||||||
def get_sub_children(self,
|
def get_sub_children(self,
|
||||||
option,
|
option,
|
||||||
config_bag,
|
config_bag,
|
||||||
|
*,
|
||||||
index=None,
|
index=None,
|
||||||
properties=undefined,
|
properties=undefined,
|
||||||
|
dynoption=None,
|
||||||
):
|
):
|
||||||
rootpath = self.get_root_path(option)
|
root_path, sub_path = self.split_path(dynoption,
|
||||||
subpath = self.get_sub_path(option)
|
option,
|
||||||
for suffix in self.get_suffixes(config_bag):
|
)
|
||||||
yield self.get_sub_child(option,
|
for suffix in self.get_suffixes(config_bag,
|
||||||
suffix,
|
dynoption=dynoption,
|
||||||
config_bag,
|
):
|
||||||
index=index,
|
if self.option_is_self(option):
|
||||||
rootpath=rootpath,
|
parent_path = root_path
|
||||||
subpath=subpath,
|
elif root_path:
|
||||||
properties=properties,
|
parent_path = root_path + self.impl_getname(suffix) + sub_path
|
||||||
)
|
else:
|
||||||
|
parent_path = self.impl_getname(suffix) + sub_path
|
||||||
def get_root_path(self, option):
|
yield OptionBag(option.to_dynoption(parent_path,
|
||||||
path = self.impl_getpath()
|
suffix,
|
||||||
rootpath = path.rsplit('.', 1)[0] if '.' in path else ''
|
self,
|
||||||
if option != self:
|
),
|
||||||
if rootpath:
|
index,
|
||||||
rootpath += '.'
|
config_bag,
|
||||||
return rootpath
|
properties=properties,
|
||||||
|
ori_option=option
|
||||||
def get_sub_path(self, option):
|
)
|
||||||
if option != self:
|
|
||||||
return option.impl_getpath()[len(self.impl_getpath()):].rsplit('.', 1)[0]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_sub_child(self,
|
|
||||||
option,
|
|
||||||
suffix,
|
|
||||||
config_bag,
|
|
||||||
*,
|
|
||||||
index: Optional[int]=None,
|
|
||||||
rootpath: Optional[str]=None,
|
|
||||||
subpath: Optional[str]=None,
|
|
||||||
properties: Optional[str]=None,
|
|
||||||
):
|
|
||||||
if rootpath is None:
|
|
||||||
rootpath = self.get_root_path(option)
|
|
||||||
if option == self:
|
|
||||||
parent_path = rootpath
|
|
||||||
else:
|
|
||||||
if subpath is None:
|
|
||||||
subpath = self.get_sub_path(option)
|
|
||||||
parent_path = rootpath + self.impl_getname(suffix) + subpath
|
|
||||||
return OptionBag(option.to_dynoption(parent_path,
|
|
||||||
suffix,
|
|
||||||
self,
|
|
||||||
),
|
|
||||||
index,
|
|
||||||
config_bag,
|
|
||||||
properties=properties,
|
|
||||||
ori_option=option
|
|
||||||
)
|
|
||||||
|
|
||||||
def _setsubdyn(self,
|
|
||||||
subdyn,
|
|
||||||
) -> None:
|
|
||||||
raise ConfigError(_('cannot set a dynoptiondescription in a '
|
|
||||||
'dynoptiondescription'))
|
|
||||||
|
|
||||||
def impl_getname(self, suffix=None) -> str:
|
def impl_getname(self, suffix=None) -> str:
|
||||||
"""get name
|
"""get name
|
||||||
|
|
|
@ -106,10 +106,9 @@ class Leadership(OptionDescription):
|
||||||
def _setsubdyn(self,
|
def _setsubdyn(self,
|
||||||
subdyn,
|
subdyn,
|
||||||
) -> None:
|
) -> None:
|
||||||
# pylint: disable=attribute-defined-outside-init,protected-access
|
|
||||||
for chld in self._children[1]:
|
for chld in self._children[1]:
|
||||||
chld._setsubdyn(subdyn)
|
chld._setsubdyn(subdyn)
|
||||||
self._subdyn = subdyn
|
super()._setsubdyn(subdyn)
|
||||||
|
|
||||||
def is_leader(self,
|
def is_leader(self,
|
||||||
opt: Option,
|
opt: Option,
|
||||||
|
|
|
@ -20,13 +20,14 @@
|
||||||
# ____________________________________________________________
|
# ____________________________________________________________
|
||||||
"""OptionDescription
|
"""OptionDescription
|
||||||
"""
|
"""
|
||||||
|
import weakref
|
||||||
from typing import Optional, Iterator, Union, List
|
from typing import Optional, Iterator, Union, List
|
||||||
|
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..setting import ConfigBag, OptionBag, groups, undefined, owners, Undefined
|
from ..setting import ConfigBag, OptionBag, groups, undefined, owners, Undefined
|
||||||
from .baseoption import BaseOption
|
from .baseoption import BaseOption
|
||||||
from .syndynoptiondescription import SynDynOptionDescription
|
from .syndynoptiondescription import SubDynOptionDescription, SynDynOptionDescription
|
||||||
from ..error import ConfigError, ConflictError
|
from ..error import ConfigError, ConflictError
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,15 +128,14 @@ class CacheOptionDescription(BaseOption):
|
||||||
dynopt = option.getsubdyn()
|
dynopt = option.getsubdyn()
|
||||||
yield from dynopt.get_sub_children(option,
|
yield from dynopt.get_sub_children(option,
|
||||||
config_bag,
|
config_bag,
|
||||||
None,
|
index=None,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
option_bag = OptionBag(option,
|
yield OptionBag(option,
|
||||||
None,
|
None,
|
||||||
config_bag,
|
config_bag,
|
||||||
properties=None,
|
properties=None,
|
||||||
)
|
)
|
||||||
yield option_bag
|
|
||||||
if 'force_store_value' not in config_bag.properties:
|
if 'force_store_value' not in config_bag.properties:
|
||||||
return
|
return
|
||||||
values = config_bag.context.get_values()
|
values = config_bag.context.get_values()
|
||||||
|
@ -194,6 +194,10 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||||
name: str,
|
name: str,
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
subpath: str,
|
subpath: str,
|
||||||
|
*,
|
||||||
|
dynoption=None,
|
||||||
|
option_suffix: Optional[str]=None,
|
||||||
|
allow_dynoption: bool=False,
|
||||||
) -> Union[BaseOption, SynDynOptionDescription]:
|
) -> Union[BaseOption, SynDynOptionDescription]:
|
||||||
"""get a child
|
"""get a child
|
||||||
"""
|
"""
|
||||||
|
@ -201,18 +205,32 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||||
if name in self._children[0]: # pylint: disable=no-member
|
if name in self._children[0]: # pylint: disable=no-member
|
||||||
option = self._children[1][self._children[0].index(name)] # pylint: disable=no-member
|
option = self._children[1][self._children[0].index(name)] # pylint: disable=no-member
|
||||||
if option.impl_is_dynoptiondescription():
|
if option.impl_is_dynoptiondescription():
|
||||||
raise AttributeError(_(f'unknown option "{name}" '
|
if allow_dynoption:
|
||||||
"in root optiondescription (it's a dynamic option)"
|
option_suffix = None
|
||||||
))
|
else:
|
||||||
|
raise AttributeError(_(f'unknown option "{name}" '
|
||||||
|
"in root optiondescription (it's a dynamic option)"
|
||||||
|
))
|
||||||
|
if option.issubdyn():
|
||||||
|
return option.to_dynoption(subpath,
|
||||||
|
option_suffix,
|
||||||
|
option,
|
||||||
|
)
|
||||||
return option
|
return option
|
||||||
# if dyn
|
# if dyn
|
||||||
|
if dynoption:
|
||||||
|
self_opt = dynoption
|
||||||
|
else:
|
||||||
|
self_opt = self
|
||||||
for child in self._children[1]: # pylint: disable=no-member
|
for child in self._children[1]: # pylint: disable=no-member
|
||||||
if not child.impl_is_dynoptiondescription():
|
if not child.impl_is_dynoptiondescription():
|
||||||
continue
|
continue
|
||||||
cname = child.impl_getname()
|
cname = child.impl_getname()
|
||||||
if not name.startswith(cname):
|
if not name.startswith(cname):
|
||||||
continue
|
continue
|
||||||
for suffix in child.get_suffixes(config_bag):
|
for suffix in child.get_suffixes(config_bag,
|
||||||
|
dynoption,
|
||||||
|
):
|
||||||
if name != cname + child.convert_suffix_to_path(suffix):
|
if name != cname + child.convert_suffix_to_path(suffix):
|
||||||
continue
|
continue
|
||||||
return child.to_dynoption(subpath,
|
return child.to_dynoption(subpath,
|
||||||
|
@ -229,22 +247,39 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||||
|
|
||||||
def get_children(self,
|
def get_children(self,
|
||||||
config_bag: Union[ConfigBag, Undefined],
|
config_bag: Union[ConfigBag, Undefined],
|
||||||
|
*,
|
||||||
dyn: bool=True,
|
dyn: bool=True,
|
||||||
|
#path: Optional[str]=None,
|
||||||
|
dynoption=None,
|
||||||
|
option_suffix: Optional[str]=None,
|
||||||
) -> Union[BaseOption, SynDynOptionDescription]:
|
) -> Union[BaseOption, SynDynOptionDescription]:
|
||||||
"""get children
|
"""get children
|
||||||
"""
|
"""
|
||||||
|
# if path:
|
||||||
|
# subpath = path
|
||||||
|
if dynoption:
|
||||||
|
self_opt = dynoption
|
||||||
|
else:
|
||||||
|
self_opt = self
|
||||||
if not dyn or config_bag is undefined or \
|
if not dyn or config_bag is undefined or \
|
||||||
config_bag.context.get_description() == self:
|
config_bag.context.get_description() == self:
|
||||||
subpath = ''
|
subpath = ''
|
||||||
else:
|
else:
|
||||||
subpath = self.impl_getpath()
|
subpath = self_opt.impl_getpath()
|
||||||
for child in self._children[1]: # pylint: disable=no-member
|
for child in self._children[1]: # pylint: disable=no-member
|
||||||
if dyn and child.impl_is_dynoptiondescription():
|
if dyn and child.impl_is_dynoptiondescription():
|
||||||
for suffix in child.get_suffixes(config_bag):
|
for suffix in child.get_suffixes(config_bag,
|
||||||
|
dynoption,
|
||||||
|
):
|
||||||
yield child.to_dynoption(subpath,
|
yield child.to_dynoption(subpath,
|
||||||
suffix,
|
suffix,
|
||||||
child,
|
child,
|
||||||
)
|
)
|
||||||
|
elif dyn and child.issubdyn() or child.impl_is_dynsymlinkoption():
|
||||||
|
yield child.to_dynoption(subpath,
|
||||||
|
option_suffix,
|
||||||
|
child,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
yield child
|
yield child
|
||||||
|
|
||||||
|
@ -320,6 +355,13 @@ class OptionDescription(OptionDescriptionWalk):
|
||||||
# the group_type is useful for filtering OptionDescriptions in a config
|
# the group_type is useful for filtering OptionDescriptions in a config
|
||||||
self._group_type = groups.default
|
self._group_type = groups.default
|
||||||
|
|
||||||
|
def _setsubdyn(self,
|
||||||
|
subdyn,
|
||||||
|
) -> None:
|
||||||
|
for child in self._children[1]:
|
||||||
|
child._setsubdyn(subdyn)
|
||||||
|
super()._setsubdyn(subdyn)
|
||||||
|
|
||||||
def impl_is_optiondescription(self) -> bool:
|
def impl_is_optiondescription(self) -> bool:
|
||||||
"""the option is an option description
|
"""the option is an option description
|
||||||
"""
|
"""
|
||||||
|
@ -367,6 +409,11 @@ class OptionDescription(OptionDescriptionWalk):
|
||||||
ori_dyn) -> SynDynOptionDescription:
|
ori_dyn) -> SynDynOptionDescription:
|
||||||
"""get syn dyn option description
|
"""get syn dyn option description
|
||||||
"""
|
"""
|
||||||
|
if suffix is None:
|
||||||
|
return SubDynOptionDescription(self,
|
||||||
|
rootpath,
|
||||||
|
ori_dyn,
|
||||||
|
)
|
||||||
return SynDynOptionDescription(self,
|
return SynDynOptionDescription(self,
|
||||||
rootpath,
|
rootpath,
|
||||||
suffix,
|
suffix,
|
||||||
|
|
|
@ -58,7 +58,7 @@ class SynDynOption:
|
||||||
def impl_get_display_name(self) -> str:
|
def impl_get_display_name(self) -> str:
|
||||||
"""get option display name
|
"""get option display name
|
||||||
"""
|
"""
|
||||||
suffix = self.dyn_parent.convert_suffix_to_path(self.suffix)
|
suffix = self.dyn_parent.getsubdyn().convert_suffix_to_path(self.suffix)
|
||||||
return self.opt._get_display_name(dyn_name=self.impl_getname(), # pylint: disable=protected-access
|
return self.opt._get_display_name(dyn_name=self.impl_getname(), # pylint: disable=protected-access
|
||||||
suffix=suffix,
|
suffix=suffix,
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,11 +25,75 @@ from typing import Optional, Iterator, Any, List
|
||||||
|
|
||||||
|
|
||||||
from ..i18n import _
|
from ..i18n import _
|
||||||
from ..setting import ConfigBag
|
from ..setting import ConfigBag, undefined
|
||||||
from .baseoption import BaseOption
|
from .baseoption import BaseOption
|
||||||
from .syndynoption import SynDynOption
|
from .syndynoption import SynDynOption
|
||||||
|
|
||||||
|
|
||||||
|
class SubDynOptionDescription:
|
||||||
|
__slots__ = ('rootpath',
|
||||||
|
'opt',
|
||||||
|
'dyn_parent',
|
||||||
|
'__weakref__',
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
opt: BaseOption,
|
||||||
|
rootpath: str,
|
||||||
|
dyn_parent,
|
||||||
|
) -> None:
|
||||||
|
self.opt = opt
|
||||||
|
self.rootpath = rootpath
|
||||||
|
self.dyn_parent = dyn_parent
|
||||||
|
|
||||||
|
def impl_getpath(self) -> str:
|
||||||
|
"""get path
|
||||||
|
"""
|
||||||
|
path = self.opt.impl_getname()
|
||||||
|
if self.rootpath:
|
||||||
|
path = f'{self.rootpath}.{path}'
|
||||||
|
return path
|
||||||
|
|
||||||
|
def get_sub_children(self,
|
||||||
|
option,
|
||||||
|
config_bag,
|
||||||
|
*,
|
||||||
|
index=None,
|
||||||
|
properties=undefined,
|
||||||
|
):
|
||||||
|
return self.opt.get_sub_children(option,
|
||||||
|
config_bag,
|
||||||
|
index=index,
|
||||||
|
properties=properties,
|
||||||
|
dynoption=self,
|
||||||
|
)
|
||||||
|
|
||||||
|
def getsubdyn(self):
|
||||||
|
return self.opt.getsubdyn()
|
||||||
|
|
||||||
|
def impl_is_optiondescription(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def impl_is_dynsymlinkoption(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def impl_is_sub_dyn_optiondescription(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def impl_get_display_name(self) -> str:
|
||||||
|
return self.opt.impl_get_display_name()
|
||||||
|
|
||||||
|
def impl_is_dynoptiondescription(self) -> bool:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def to_dynoption(self,
|
||||||
|
rootpath: str,
|
||||||
|
suffix: str,
|
||||||
|
ori_dyn,
|
||||||
|
):
|
||||||
|
return self.opt.to_dynoption(rootpath, suffix, ori_dyn)
|
||||||
|
|
||||||
|
|
||||||
class SynDynOptionDescription:
|
class SynDynOptionDescription:
|
||||||
"""SynDynOptionDescription internal option, it's an instanciate synoptiondescription
|
"""SynDynOptionDescription internal option, it's an instanciate synoptiondescription
|
||||||
"""
|
"""
|
||||||
|
@ -57,27 +121,6 @@ class SynDynOptionDescription:
|
||||||
name,
|
name,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_child(self,
|
|
||||||
name: str,
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
subpath: str,
|
|
||||||
) -> BaseOption:
|
|
||||||
"""get child by name
|
|
||||||
"""
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
try:
|
|
||||||
child = self._children[1][self._children[0].index(name)]
|
|
||||||
except ValueError:
|
|
||||||
# when name not in self._children
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
return child.to_dynoption(subpath,
|
|
||||||
self._suffix,
|
|
||||||
self.ori_dyn)
|
|
||||||
raise AttributeError(_('unknown option "{0}" '
|
|
||||||
'in dynamic optiondescription "{1}"'
|
|
||||||
'').format(name, self.impl_get_display_name()))
|
|
||||||
|
|
||||||
def impl_getname(self) -> str:
|
def impl_getname(self) -> str:
|
||||||
"""get name
|
"""get name
|
||||||
"""
|
"""
|
||||||
|
@ -98,14 +141,40 @@ class SynDynOptionDescription:
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
"""get children
|
"""get children
|
||||||
"""
|
"""
|
||||||
subpath = self.impl_getpath()
|
yield from self.opt.get_children(config_bag,
|
||||||
children = []
|
dynoption=self,
|
||||||
for child in self.opt.get_children(config_bag):
|
option_suffix=self._suffix,
|
||||||
children.append(child.to_dynoption(subpath,
|
)
|
||||||
self._suffix,
|
|
||||||
self.ori_dyn,
|
def get_child(self,
|
||||||
))
|
name: str,
|
||||||
return children
|
config_bag: ConfigBag,
|
||||||
|
subpath: str,
|
||||||
|
allow_dynoption: bool=False,
|
||||||
|
):
|
||||||
|
"""get children
|
||||||
|
"""
|
||||||
|
return self.opt.get_child(name,
|
||||||
|
config_bag,
|
||||||
|
subpath,
|
||||||
|
dynoption=self,
|
||||||
|
option_suffix=self._suffix,
|
||||||
|
allow_dynoption=allow_dynoption,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_sub_children(self,
|
||||||
|
option,
|
||||||
|
config_bag,
|
||||||
|
*,
|
||||||
|
index=None,
|
||||||
|
properties=undefined,
|
||||||
|
):
|
||||||
|
return self.opt.get_sub_children(option,
|
||||||
|
config_bag,
|
||||||
|
index=index,
|
||||||
|
properties=properties,
|
||||||
|
dynoption=self,
|
||||||
|
)
|
||||||
|
|
||||||
def impl_is_dynsymlinkoption(self) -> bool:
|
def impl_is_dynsymlinkoption(self) -> bool:
|
||||||
"""it's a dynsymlinkoption
|
"""it's a dynsymlinkoption
|
||||||
|
@ -136,6 +205,11 @@ class SynDynOptionDescription:
|
||||||
path = f'{self.rootpath}.{path}'
|
path = f'{self.rootpath}.{path}'
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
def impl_getsuffix(self) -> str:
|
||||||
|
"""get suffix
|
||||||
|
"""
|
||||||
|
return self._suffix
|
||||||
|
|
||||||
|
|
||||||
class SynDynLeadership(SynDynOptionDescription):
|
class SynDynLeadership(SynDynOptionDescription):
|
||||||
"""SynDynLeadership internal option, it's an instanciate synoptiondescription
|
"""SynDynLeadership internal option, it's an instanciate synoptiondescription
|
||||||
|
|
|
@ -373,7 +373,7 @@ class Values:
|
||||||
for index in indexes:
|
for index in indexes:
|
||||||
for coption_bag in option.get_sub_children(coption,
|
for coption_bag in option.get_sub_children(coption,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
index,
|
index=index,
|
||||||
properties=frozenset(),
|
properties=frozenset(),
|
||||||
):
|
):
|
||||||
default_value = [self.get_value(coption_bag)[0], owners.forced]
|
default_value = [self.get_value(coption_bag)[0], owners.forced]
|
||||||
|
|
Loading…
Reference in a new issue