Compare commits
1 commit
main
...
dynamic_fa
Author | SHA1 | Date | |
---|---|---|---|
a6eacf471e |
19 changed files with 913 additions and 408 deletions
|
@ -11,13 +11,12 @@ You just have to create an object that inherits from `RegexpOption` and that has
|
||||||
|
|
||||||
- __slots__: with new data members (the values should always be `tuple()`)
|
- __slots__: with new data members (the values should always be `tuple()`)
|
||||||
- _type = with a name
|
- _type = with a name
|
||||||
- _display_name: with the display name (for example in error message)
|
|
||||||
- _regexp: with a compiled regexp
|
- _regexp: with a compiled regexp
|
||||||
|
|
||||||
Here an example to an option that only accept string with on lowercase ASCII vowel characters:
|
Here an example to an option that only accept string with on lowercase ASCII vowel characters:
|
||||||
|
|
||||||
.. literalinclude:: src/own_option.py
|
.. literalinclude:: src/own_option.py
|
||||||
:lines: 3-11
|
:lines: 3-10
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Let's try our object:
|
Let's try our object:
|
||||||
|
@ -31,31 +30,30 @@ Let's try our object:
|
||||||
...
|
...
|
||||||
"oooups" is an invalid string with vowel for "Vowel"
|
"oooups" is an invalid string with vowel for "Vowel"
|
||||||
|
|
||||||
Create you own option
|
Create your own option
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
An option always inherits from `Option` object. This object has the following class attributes:
|
An option always inherits from `Option` object. This object has the following class attributes:
|
||||||
|
|
||||||
- __slots__: with new data members (the values should always be `tuple()`)
|
- __slots__: with new data members (the values should always be `tuple()`)
|
||||||
- _type = with a name
|
- _type = with a name
|
||||||
- _display_name: with the display name (for example in error message)
|
|
||||||
|
|
||||||
Here an example to an lipogram option:
|
Here an example to a lipogram option:
|
||||||
|
|
||||||
.. literalinclude:: src/own_option2.py
|
.. literalinclude:: src/own_option2.py
|
||||||
:lines: 3-15
|
:lines: 3-12
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
First of all we want to add a custom parameter to ask the minimum length (`min_len`) of the value:
|
First of all we want to add a custom parameter to ask the minimum length (`min_len`) of the value:
|
||||||
|
|
||||||
.. literalinclude:: src/own_option2.py
|
.. literalinclude:: src/own_option2.py
|
||||||
:lines: 16-20
|
:lines: 13-17
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
We have a first validation method. In this method, we verify that the value is a string and that there is no "e" on it:
|
We have a first validation method. In this method, we verify that the value is a string and that there is no "e" on it:
|
||||||
|
|
||||||
.. literalinclude:: src/own_option2.py
|
.. literalinclude:: src/own_option2.py
|
||||||
:lines: 22-29
|
:lines: 19-26
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Even if user set warnings_only attribute, this method will raise.
|
Even if user set warnings_only attribute, this method will raise.
|
||||||
|
@ -63,7 +61,7 @@ Even if user set warnings_only attribute, this method will raise.
|
||||||
Finally we add a method to valid the value length. If `warnings_only` is set to True, a warning will be emit:
|
Finally we add a method to valid the value length. If `warnings_only` is set to True, a warning will be emit:
|
||||||
|
|
||||||
.. literalinclude:: src/own_option2.py
|
.. literalinclude:: src/own_option2.py
|
||||||
:lines: 31-43
|
:lines: 28-40
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
Let's test it:
|
Let's test it:
|
||||||
|
|
|
@ -7,5 +7,4 @@ from tiramisu import RegexpOption
|
||||||
class VowelOption(RegexpOption):
|
class VowelOption(RegexpOption):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
_type = 'vowel'
|
_type = 'vowel'
|
||||||
_display_name = "string with vowel"
|
|
||||||
_regexp = re.compile(r"^[aeiouy]*$")
|
_regexp = re.compile(r"^[aeiouy]*$")
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
from tiramisu import Option
|
from tiramisu import Option
|
||||||
from tiramisu.error import ValueWarning
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
|
|
||||||
class LipogramOption(Option):
|
class LipogramOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
_type = 'lipogram'
|
_type = 'lipogram'
|
||||||
_display_name = 'lipogram'
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
*args,
|
*args,
|
||||||
min_len=100,
|
min_len=100,
|
||||||
|
|
|
@ -66,7 +66,7 @@ def test_deref_optiondescription():
|
||||||
def test_deref_option_cache():
|
def test_deref_option_cache():
|
||||||
b = BoolOption('b', '')
|
b = BoolOption('b', '')
|
||||||
o = OptionDescription('od', '', [b])
|
o = OptionDescription('od', '', [b])
|
||||||
o._build_cache()
|
o._build_cache(None)
|
||||||
w = weakref.ref(b)
|
w = weakref.ref(b)
|
||||||
del(b)
|
del(b)
|
||||||
assert w() is not None
|
assert w() is not None
|
||||||
|
@ -77,7 +77,7 @@ def test_deref_option_cache():
|
||||||
def test_deref_optiondescription_cache():
|
def test_deref_optiondescription_cache():
|
||||||
b = BoolOption('b', '')
|
b = BoolOption('b', '')
|
||||||
o = OptionDescription('od', '', [b])
|
o = OptionDescription('od', '', [b])
|
||||||
o._build_cache()
|
o._build_cache(None)
|
||||||
w = weakref.ref(o)
|
w = weakref.ref(o)
|
||||||
del(b)
|
del(b)
|
||||||
assert w() is not None
|
assert w() is not None
|
||||||
|
|
|
@ -158,10 +158,10 @@ def test_getdoc_dyndescription():
|
||||||
assert cfg.option('od.dodval2.st').name() == 'st'
|
assert cfg.option('od.dodval2.st').name() == 'st'
|
||||||
assert cfg.option('od.dodval1').name() == 'dodval1'
|
assert cfg.option('od.dodval1').name() == 'dodval1'
|
||||||
assert cfg.option('od.dodval2').name() == 'dodval2'
|
assert cfg.option('od.dodval2').name() == 'dodval2'
|
||||||
assert cfg.option('od.dodval1.st').doc() == 'doc1val1'
|
assert cfg.option('od.dodval1.st').doc() == 'doc1'
|
||||||
assert cfg.option('od.dodval2.st').doc() == 'doc1val2'
|
assert cfg.option('od.dodval2.st').doc() == 'doc1'
|
||||||
assert cfg.option('od.dodval1').doc() == 'doc2val1'
|
assert cfg.option('od.dodval1').doc() == 'doc2'
|
||||||
assert cfg.option('od.dodval2').doc() == 'doc2val2'
|
assert cfg.option('od.dodval2').doc() == 'doc2'
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1792,7 +1792,6 @@ def test_subdynod_dyndescription():
|
||||||
assert cfg.option('st3').value.get() is None
|
assert cfg.option('st3').value.get() is None
|
||||||
# assert not list_sessions()
|
# 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():
|
def test_subdynod_dyndescription_2():
|
||||||
st2 = StrOption('st2', '')
|
st2 = StrOption('st2', '')
|
||||||
st1 = StrOption('st1', '', default=['a', 'b'], multi=True)
|
st1 = StrOption('st1', '', default=['a', 'b'], multi=True)
|
||||||
|
@ -2079,7 +2078,7 @@ def test_dyn_leadership_mandatory():
|
||||||
dyn = DynOptionDescription(name="nsd_zone_", doc="Zone ", suffixes=Calculation(calc_value, Params((ParamOption(nsd_zones_all, notraisepropertyerror=True)))), children=[is_auto, leadership], properties=frozenset({"normal"}))
|
dyn = DynOptionDescription(name="nsd_zone_", doc="Zone ", suffixes=Calculation(calc_value, Params((ParamOption(nsd_zones_all, notraisepropertyerror=True)))), children=[is_auto, leadership], properties=frozenset({"normal"}))
|
||||||
od1 = OptionDescription(name="nsd", doc="nsd", children=[nsd_zones_all, dyn])
|
od1 = OptionDescription(name="nsd", doc="nsd", children=[nsd_zones_all, dyn])
|
||||||
cfg = Config(od1)
|
cfg = Config(od1)
|
||||||
cfg.value.mandatory()
|
assert cfg.value.mandatory() == []
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
@ -2109,3 +2108,542 @@ def test_dyn_callback_with_not_dyn():
|
||||||
assert cfg.option('names').issubmulti() == False
|
assert cfg.option('names').issubmulti() == False
|
||||||
assert cfg.value.get() == {'remotes': ['a', 'b', 'c'], 'remote_a.remote_ip_': 'a', 'remote_b.remote_ip_': 'b', 'remote_c.remote_ip_': 'c', 'names': ['a', 'b', 'c']}
|
assert cfg.value.get() == {'remotes': ['a', 'b', 'c'], 'remote_a.remote_ip_': 'a', 'remote_b.remote_ip_': 'b', 'remote_c.remote_ip_': 'c', 'names': ['a', 'b', 'c']}
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
def test_dyn_link_subdyn():
|
||||||
|
database_names = StrOption(name="database_names", doc="database_names", multi=True, default=["srep", "snom", "srem"])
|
||||||
|
password = StrOption(name="password", doc="password", properties=('mandatory',))
|
||||||
|
name = StrOption(name="name", doc="name", properties=('mandatory',))
|
||||||
|
password2 = StrOption(name="password", doc="password", default=Calculation(calc_value, Params((ParamOption(password)))), properties=('mandatory',))
|
||||||
|
user = OptionDescription(name="user", doc="user", children=[name, password2])
|
||||||
|
sub = OptionDescription(name="sub", doc="sub", children=[user])
|
||||||
|
user_database = DynOptionDescription(name="user_database_", doc="user database", suffixes=Calculation(calc_value, Params((ParamOption(database_names, notraisepropertyerror=True)))), children=[password, sub])
|
||||||
|
socle = OptionDescription(name="socle", doc="socle", children=[user_database, database_names])
|
||||||
|
root = OptionDescription(name="baseoption", doc="baseoption", children=[socle])
|
||||||
|
cfg = Config(root)
|
||||||
|
assert cfg.option('socle.database_names').value.get() == ["srep", "snom", "srem"]
|
||||||
|
assert cfg.option('socle.user_database_srep.password').value.get() is None
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.name').value.get() is None
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.password').value.get() is None
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.user_database_srep.password',
|
||||||
|
'socle.user_database_srep.sub.user.name',
|
||||||
|
'socle.user_database_srep.sub.user.password',
|
||||||
|
'socle.user_database_snom.password',
|
||||||
|
'socle.user_database_snom.sub.user.name',
|
||||||
|
'socle.user_database_snom.sub.user.password',
|
||||||
|
'socle.user_database_srem.password',
|
||||||
|
'socle.user_database_srem.sub.user.name',
|
||||||
|
'socle.user_database_srem.sub.user.password',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.user_database_srep.password').value.set('pass')
|
||||||
|
cfg.option('socle.user_database_snom.sub.user.password').value.set('pass')
|
||||||
|
assert cfg.option('socle.user_database_srep.password').value.get() is 'pass'
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.name').value.get() is None
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.password').value.get() is 'pass'
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.user_database_srep.sub.user.name',
|
||||||
|
'socle.user_database_snom.password',
|
||||||
|
'socle.user_database_snom.sub.user.name',
|
||||||
|
'socle.user_database_srem.password',
|
||||||
|
'socle.user_database_srem.sub.user.name',
|
||||||
|
'socle.user_database_srem.sub.user.password',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.user_database_snom.password').value.set('pass2')
|
||||||
|
cfg.option('socle.user_database_srem.password').value.set('pass3')
|
||||||
|
cfg.option('socle.user_database_srep.sub.user.name').value.set('name1')
|
||||||
|
cfg.option('socle.user_database_snom.sub.user.name').value.set('name2')
|
||||||
|
cfg.option('socle.user_database_srem.sub.user.name').value.set('name3')
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
assert cfg.value.get() == {'socle.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.user_database_snom.password': 'pass2',
|
||||||
|
'socle.user_database_snom.sub.user.name': 'name2',
|
||||||
|
'socle.user_database_snom.sub.user.password': 'pass',
|
||||||
|
'socle.user_database_srem.password': 'pass3',
|
||||||
|
'socle.user_database_srem.sub.user.name': 'name3',
|
||||||
|
'socle.user_database_srem.sub.user.password': 'pass3',
|
||||||
|
'socle.user_database_srep.password': 'pass',
|
||||||
|
'socle.user_database_srep.sub.user.name': 'name1',
|
||||||
|
'socle.user_database_srep.sub.user.password': 'pass',
|
||||||
|
}
|
||||||
|
#
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_dyn_link_subdyn_2():
|
||||||
|
database_names = StrOption(name="database_names", doc="database_names", multi=True, default=["srep", "snom", "srem"])
|
||||||
|
password2 = StrOption(name="password", doc="password", properties=('mandatory',))
|
||||||
|
password = StrOption(name="password", doc="password", default=Calculation(calc_value, Params((ParamOption(password2)))), properties=('mandatory',))
|
||||||
|
name = StrOption(name="name", doc="name", properties=('mandatory',))
|
||||||
|
user = OptionDescription(name="user", doc="user", children=[name, password2])
|
||||||
|
sub = OptionDescription(name="sub", doc="sub", children=[user])
|
||||||
|
user_database = DynOptionDescription(name="user_database_", doc="user database", suffixes=Calculation(calc_value, Params((ParamOption(database_names, notraisepropertyerror=True)))), children=[password, sub])
|
||||||
|
socle = OptionDescription(name="socle", doc="socle", children=[user_database, database_names])
|
||||||
|
root = OptionDescription(name="baseoption", doc="baseoption", children=[socle])
|
||||||
|
cfg = Config(root)
|
||||||
|
assert cfg.option('socle.database_names').value.get() == ["srep", "snom", "srem"]
|
||||||
|
assert cfg.option('socle.user_database_srep.password').value.get() is None
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.name').value.get() is None
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.password').value.get() is None
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.user_database_srep.password',
|
||||||
|
'socle.user_database_srep.sub.user.name',
|
||||||
|
'socle.user_database_srep.sub.user.password',
|
||||||
|
'socle.user_database_snom.password',
|
||||||
|
'socle.user_database_snom.sub.user.name',
|
||||||
|
'socle.user_database_snom.sub.user.password',
|
||||||
|
'socle.user_database_srem.password',
|
||||||
|
'socle.user_database_srem.sub.user.name',
|
||||||
|
'socle.user_database_srem.sub.user.password',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.user_database_srep.password').value.set('pass')
|
||||||
|
cfg.option('socle.user_database_snom.sub.user.password').value.set('pass')
|
||||||
|
assert cfg.option('socle.user_database_srep.password').value.get() is 'pass'
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.name').value.get() is None
|
||||||
|
assert cfg.option('socle.user_database_srep.sub.user.password').value.get() is None
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.user_database_srep.sub.user.name',
|
||||||
|
'socle.user_database_srep.sub.user.password',
|
||||||
|
'socle.user_database_snom.sub.user.name',
|
||||||
|
'socle.user_database_srem.password',
|
||||||
|
'socle.user_database_srem.sub.user.name',
|
||||||
|
'socle.user_database_srem.sub.user.password',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.user_database_srep.sub.user.password').value.set('pass2')
|
||||||
|
cfg.option('socle.user_database_srem.sub.user.password').value.set('pass3')
|
||||||
|
cfg.option('socle.user_database_srep.sub.user.name').value.set('name1')
|
||||||
|
cfg.option('socle.user_database_snom.sub.user.name').value.set('name2')
|
||||||
|
cfg.option('socle.user_database_srem.sub.user.name').value.set('name3')
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
assert cfg.value.get() == {'socle.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.user_database_snom.password': 'pass',
|
||||||
|
'socle.user_database_snom.sub.user.name': 'name2',
|
||||||
|
'socle.user_database_snom.sub.user.password': 'pass',
|
||||||
|
'socle.user_database_srem.password': 'pass3',
|
||||||
|
'socle.user_database_srem.sub.user.name': 'name3',
|
||||||
|
'socle.user_database_srem.sub.user.password': 'pass3',
|
||||||
|
'socle.user_database_srep.password': 'pass',
|
||||||
|
'socle.user_database_srep.sub.user.name': 'name1',
|
||||||
|
'socle.user_database_srep.sub.user.password': 'pass2',
|
||||||
|
}
|
||||||
|
#
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_dyn_link_subdyn_twice():
|
||||||
|
password = StrOption(name="password", doc="password", properties=('mandatory',))
|
||||||
|
name = StrOption(name="name", doc="name", properties=('mandatory',))
|
||||||
|
login = StrOption(name="login", doc="login", default=Calculation(calc_value, Params((ParamOption(name)))), properties=('mandatory',))
|
||||||
|
password2 = StrOption(name="password2", doc="password2", default=Calculation(calc_value, Params((ParamOption(password)))), properties=('mandatory',))
|
||||||
|
database_names = StrOption(name="database_names", doc="database_names", multi=True, default=["srep", "snom", "srem"])
|
||||||
|
user_database = DynOptionDescription(name="user_database_", doc="user database", suffixes=Calculation(calc_value, Params((ParamOption(database_names, notraisepropertyerror=True)))), children=[name, login, password2])
|
||||||
|
databases = OptionDescription(name="databases", doc="database", children=[password, user_database])
|
||||||
|
schema_names = StrOption(name="database_schemas", doc="database_schemas", multi=True, default=["schema1", "schema2", "schema3"])
|
||||||
|
schema = DynOptionDescription(name="schema_", doc="schema_", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[database_names, databases])
|
||||||
|
socle = OptionDescription(name="socle", doc="socle", children=[schema, schema_names])
|
||||||
|
root = OptionDescription(name="baseoption", doc="baseoption", children=[socle])
|
||||||
|
cfg = Config(root)
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1',
|
||||||
|
'schema2',
|
||||||
|
'schema3'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.schema_schema1.databases.password': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.password2': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.password2': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.password2': None,
|
||||||
|
'socle.schema_schema2.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.schema_schema2.databases.password': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_snom.name': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_snom.login': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_snom.password2': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_srem.name': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_srem.login': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_srem.password2': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_srep.name': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_srep.login': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_srep.password2': None,
|
||||||
|
'socle.schema_schema3.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.schema_schema3.databases.password': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.name': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.login': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.password2': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.name': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.login': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.password2': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.name': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.login': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.password2': None,
|
||||||
|
}
|
||||||
|
#
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.schema_schema1.databases.password',
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.name',
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.login',
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.password2',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.name',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.login',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.password2',
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.name',
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.login',
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.password2',
|
||||||
|
'socle.schema_schema2.databases.password',
|
||||||
|
'socle.schema_schema2.databases.user_database_srep.name',
|
||||||
|
'socle.schema_schema2.databases.user_database_srep.login',
|
||||||
|
'socle.schema_schema2.databases.user_database_srep.password2',
|
||||||
|
'socle.schema_schema2.databases.user_database_snom.name',
|
||||||
|
'socle.schema_schema2.databases.user_database_snom.login',
|
||||||
|
'socle.schema_schema2.databases.user_database_snom.password2',
|
||||||
|
'socle.schema_schema2.databases.user_database_srem.name',
|
||||||
|
'socle.schema_schema2.databases.user_database_srem.login',
|
||||||
|
'socle.schema_schema2.databases.user_database_srem.password2',
|
||||||
|
'socle.schema_schema3.databases.password',
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.name',
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.login',
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.password2',
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.name',
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.login',
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.password2',
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.name',
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.login',
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.password2',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema2.database_names').value.set(['another'])
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1',
|
||||||
|
'schema2',
|
||||||
|
'schema3'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.schema_schema1.databases.password': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.password2': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.password2': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.password2': None,
|
||||||
|
'socle.schema_schema2.database_names': ['another'],
|
||||||
|
'socle.schema_schema2.databases.password': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_another.name': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_another.login': None,
|
||||||
|
'socle.schema_schema2.databases.user_database_another.password2': None,
|
||||||
|
'socle.schema_schema3.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.schema_schema3.databases.password': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.name': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.login': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_snom.password2': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.name': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.login': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srem.password2': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.name': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.login': None,
|
||||||
|
'socle.schema_schema3.databases.user_database_srep.password2': None,
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.database_schemas').value.set(['schema1'])
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.schema_schema1.databases.password': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.password2': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.password2': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.name': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.login': None,
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.password2': None,
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.databases.password').value.set('password')
|
||||||
|
cfg.option('socle.schema_schema1.databases.user_database_snom.name').value.set('name1')
|
||||||
|
cfg.option('socle.schema_schema1.databases.user_database_srem.name').value.set('name2')
|
||||||
|
cfg.option('socle.schema_schema1.databases.user_database_srep.name').value.set('name3')
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep',
|
||||||
|
'snom',
|
||||||
|
'srem'],
|
||||||
|
'socle.schema_schema1.databases.password': 'password',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.login': 'name1',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.name': 'name1',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.password2': 'password',
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.login': 'name2',
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.name': 'name2',
|
||||||
|
'socle.schema_schema1.databases.user_database_srem.password2': 'password',
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.login': 'name3',
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.name': 'name3',
|
||||||
|
'socle.schema_schema1.databases.user_database_srep.password2': 'password',
|
||||||
|
}
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.database_names').value.set(['snom'])
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': ['snom'],
|
||||||
|
'socle.schema_schema1.databases.password': 'password',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.login': 'name1',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.name': 'name1',
|
||||||
|
'socle.schema_schema1.databases.user_database_snom.password2': 'password',
|
||||||
|
}
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_dyn_link_subdyn_tree():
|
||||||
|
password = StrOption(name="password", doc="password", properties=('mandatory',))
|
||||||
|
name = StrOption(name="name", doc="name", properties=('mandatory',))
|
||||||
|
login = StrOption(name="login", doc="login", default=Calculation(calc_value, Params((ParamOption(name)))), properties=('mandatory',))
|
||||||
|
password2 = StrOption(name="password2", doc="password2", default=Calculation(calc_value, Params((ParamOption(password)))), properties=('mandatory',))
|
||||||
|
user_names = StrOption(name="users", doc="users", multi=True, default=["user1"])
|
||||||
|
user_database = DynOptionDescription(name="user_database_", doc="user database", suffixes=Calculation(calc_value, Params((ParamOption(user_names, notraisepropertyerror=True)))), children=[name, login, password2])
|
||||||
|
database_names = StrOption(name="database_names", doc="database_names", multi=True, default=["srep"])
|
||||||
|
databases = DynOptionDescription(name="db_", doc="database", suffixes=Calculation(calc_value, Params((ParamOption(database_names, notraisepropertyerror=True)))), children=[user_names, password, user_database])
|
||||||
|
schema_names = StrOption(name="database_schemas", doc="database_schemas", multi=True, default=["schema1"])
|
||||||
|
schema = DynOptionDescription(name="schema_", doc="schema_", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[database_names, databases])
|
||||||
|
socle = OptionDescription(name="socle", doc="socle", children=[schema, schema_names])
|
||||||
|
root = OptionDescription(name="baseoption", doc="baseoption", children=[socle])
|
||||||
|
cfg = Config(root)
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.schema_schema1.db_srep.password',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.name',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.login',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.password2',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.db_srep.user_database_user1.name').value.set('name')
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.schema_schema1.db_srep.password',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.password2',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.db_srep.password').value.set('password')
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep'],
|
||||||
|
'socle.schema_schema1.db_srep.password': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.name': 'name',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.password2': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.users': ['user1'],
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.db_srep.users').value.set(['user1', 'user2'])
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep'],
|
||||||
|
'socle.schema_schema1.db_srep.password': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.name': 'name',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.password2': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user2.login': None,
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user2.name': None,
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user2.password2': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.users': ['user1', 'user2'],
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.db_srep.users').value.set([])
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep'],
|
||||||
|
'socle.schema_schema1.db_srep.password': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.users': [],
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.database_names').value.set([])
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': [],
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.database_schemas').value.set([])
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': [],
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.database_schemas').value.reset()
|
||||||
|
cfg.option('socle.schema_schema1.database_names').value.reset()
|
||||||
|
cfg.option('socle.schema_schema1.db_srep.users').value.reset()
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.database_names': ['srep'],
|
||||||
|
'socle.schema_schema1.db_srep.password': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.name': 'name',
|
||||||
|
'socle.schema_schema1.db_srep.user_database_user1.password2': 'password',
|
||||||
|
'socle.schema_schema1.db_srep.users': ['user1'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_dyn_link_subdyn_same_variable():
|
||||||
|
password = StrOption(name="password", doc="password", properties=('mandatory',))
|
||||||
|
name = StrOption(name="name", doc="name", properties=('mandatory',))
|
||||||
|
login = StrOption(name="login", doc="login", default=Calculation(calc_value, Params((ParamOption(name)))), properties=('mandatory',))
|
||||||
|
password2 = StrOption(name="password2", doc="password2", default=Calculation(calc_value, Params((ParamOption(password)))), properties=('mandatory',))
|
||||||
|
schema_names = StrOption(name="database_schemas", doc="database_schemas", multi=True, default=["schema1"])
|
||||||
|
user_database = DynOptionDescription(name="user_database_", doc="user database", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[name, login, password2])
|
||||||
|
databases = DynOptionDescription(name="db_", doc="database", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[password, user_database])
|
||||||
|
schema = DynOptionDescription(name="schema_", doc="schema_", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[databases])
|
||||||
|
socle = OptionDescription(name="socle", doc="socle", children=[schema, schema_names])
|
||||||
|
root = OptionDescription(name="baseoption", doc="baseoption", children=[socle])
|
||||||
|
cfg = Config(root)
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.schema_schema1.db_schema1.password',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.login',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.password2',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.db_schema1.user_database_schema1.name').value.set('name')
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.schema_schema1.db_schema1.password',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.password2',
|
||||||
|
]
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.db_schema1.password').value.set('password')
|
||||||
|
cfg.option('socle.schema_schema1.db_schema1.user_database_schema1.name').value.set('name')
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.db_schema1.password': 'password',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.name': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.password2': 'password',
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.database_schemas').value.set(['schema1', 'schema2'])
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == ['socle.schema_schema1.db_schema1.user_database_schema2.name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema2.login',
|
||||||
|
'socle.schema_schema1.db_schema2.password',
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.name',
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.login',
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.password2',
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.name',
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.login',
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.password2',
|
||||||
|
'socle.schema_schema2.db_schema1.password',
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.name',
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.login',
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.password2',
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.name',
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.login',
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.password2',
|
||||||
|
'socle.schema_schema2.db_schema2.password',
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.name',
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.login',
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.password2',
|
||||||
|
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.name',
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.login',
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.password2',
|
||||||
|
]
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1', 'schema2'],
|
||||||
|
'socle.schema_schema1.db_schema1.password': 'password',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.name': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.password2': 'password',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema2.login': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema2.name': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema2.password2': 'password',
|
||||||
|
'socle.schema_schema1.db_schema2.password': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.login': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.name': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.password2': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.login': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.name': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema1.password': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.login': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.name': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.login': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.name': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema2.password': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.login': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.name': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.login': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.name': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.password2': None,
|
||||||
|
}
|
||||||
|
assert cfg.option('socle.schema_schema1.db_schema1.user_database_schema1').value.get() == {
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.name': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.password2': 'password',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_dyn_link_subdyn_disabled():
|
||||||
|
password = StrOption(name="password", doc="password")
|
||||||
|
name = StrOption(name="name", doc="name")
|
||||||
|
login = StrOption(name="login", doc="login", default=Calculation(calc_value, Params((ParamOption(name)))))
|
||||||
|
disabled_property = Calculation(calc_value,
|
||||||
|
Params(ParamValue('disabled'),
|
||||||
|
kwargs={'condition': ParamOption(login),
|
||||||
|
'expected': ParamValue('name'),
|
||||||
|
'default': ParamValue(None)}))
|
||||||
|
password2 = StrOption(name="password2", doc="password2", default=Calculation(calc_value, Params((ParamOption(password)))), properties=(disabled_property,))
|
||||||
|
schema_names = StrOption(name="database_schemas", doc="database_schemas", multi=True, default=["schema1"])
|
||||||
|
user_database = DynOptionDescription(name="user_database_", doc="user database", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[name, login, password2])
|
||||||
|
databases = DynOptionDescription(name="db_", doc="database", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[password, user_database])
|
||||||
|
schema = DynOptionDescription(name="schema_", doc="schema_", suffixes=Calculation(calc_value, Params((ParamOption(schema_names, notraisepropertyerror=True)))), children=[databases])
|
||||||
|
socle = OptionDescription(name="socle", doc="socle", children=[schema, schema_names])
|
||||||
|
root = OptionDescription(name="baseoption", doc="baseoption", children=[socle])
|
||||||
|
cfg = Config(root)
|
||||||
|
cfg.property.read_write()
|
||||||
|
assert [opt.path() for opt in cfg.value.mandatory()] == []
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.db_schema1.password': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.login': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.name': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.password2': None,
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.schema_schema1.db_schema1.user_database_schema1.name').value.set('name')
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1'],
|
||||||
|
'socle.schema_schema1.db_schema1.password': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.name': 'name',
|
||||||
|
}
|
||||||
|
#
|
||||||
|
cfg.option('socle.database_schemas').value.set(['schema1', 'schema2'])
|
||||||
|
cfg.option('socle.schema_schema2.db_schema2.user_database_schema2.name').value.set('name2')
|
||||||
|
assert cfg.value.get() == {'socle.database_schemas': ['schema1', 'schema2'],
|
||||||
|
'socle.schema_schema1.db_schema1.password': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.login': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema1.name': 'name',
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema2.login': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema2.name': None,
|
||||||
|
'socle.schema_schema1.db_schema1.user_database_schema2.password2': None,
|
||||||
|
'socle.schema_schema1.db_schema2.password': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.login': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.name': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema1.password2': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.login': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.name': None,
|
||||||
|
'socle.schema_schema1.db_schema2.user_database_schema2.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema1.password': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.login': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.name': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema1.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.login': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.name': None,
|
||||||
|
'socle.schema_schema2.db_schema1.user_database_schema2.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema2.password': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.login': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.name': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema1.password2': None,
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.login': 'name2',
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.name': 'name2',
|
||||||
|
'socle.schema_schema2.db_schema2.user_database_schema2.password2': None,
|
||||||
|
}
|
||||||
|
|
|
@ -146,23 +146,23 @@ def test_force_default_on_freeze_multi():
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_force_default_on_freeze_leader():
|
#def test_force_default_on_freeze_leader():
|
||||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_default_on_freeze',))
|
# dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_default_on_freeze',))
|
||||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
# dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
||||||
descr = Leadership("dummy1", "", [dummy1, dummy2])
|
# descr = Leadership("dummy1", "", [dummy1, dummy2])
|
||||||
od1 = OptionDescription("root", "", [descr])
|
# od1 = OptionDescription("root", "", [descr])
|
||||||
with pytest.raises(ConfigError):
|
# with pytest.raises(ConfigError):
|
||||||
Config(od1)
|
# Config(od1)
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
def test_force_metaconfig_on_freeze_leader():
|
#def test_force_metaconfig_on_freeze_leader():
|
||||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze',))
|
# dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze',))
|
||||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
# dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
||||||
descr = Leadership("dummy1", "", [dummy1, dummy2])
|
# descr = Leadership("dummy1", "", [dummy1, dummy2])
|
||||||
od1 = OptionDescription("root", "", [descr])
|
# od1 = OptionDescription("root", "", [descr])
|
||||||
with pytest.raises(ConfigError):
|
# with pytest.raises(ConfigError):
|
||||||
Config(od1)
|
# Config(od1)
|
||||||
# assert not list_sessions()
|
# assert not list_sessions()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -458,13 +458,12 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
):
|
):
|
||||||
"""Get properties for an option"""
|
"""Get properties for an option"""
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
if not only_raises:
|
|
||||||
return option_bag.properties
|
|
||||||
settings = self._config_bag.context.get_settings()
|
settings = self._config_bag.context.get_settings()
|
||||||
ret = settings.calc_raises_properties(option_bag,
|
if not only_raises:
|
||||||
|
return settings.getproperties(option_bag)
|
||||||
|
return settings.calc_raises_properties(option_bag,
|
||||||
uncalculated=uncalculated,
|
uncalculated=uncalculated,
|
||||||
)
|
)
|
||||||
return ret
|
|
||||||
|
|
||||||
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
@option_type(['option', 'optiondescription', 'with_or_without_index'])
|
||||||
def add(self,
|
def add(self,
|
||||||
|
@ -491,8 +490,9 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
):
|
):
|
||||||
"""Remove new property for an option"""
|
"""Remove new property for an option"""
|
||||||
option_bag = options_bag[-1]
|
option_bag = options_bag[-1]
|
||||||
props = option_bag.properties
|
settings = self._config_bag.context.get_settings()
|
||||||
self._config_bag.context.get_settings().setproperties(option_bag,
|
props = settings.getproperties(option_bag)
|
||||||
|
settings.setproperties(option_bag,
|
||||||
props - {prop},
|
props - {prop},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -313,8 +313,8 @@ def manager_callback(callback: Callable,
|
||||||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||||
if param.notraisepropertyerror or param.raisepropertyerror:
|
if param.notraisepropertyerror or param.raisepropertyerror:
|
||||||
raise err from err
|
raise err from err
|
||||||
raise ConfigError(_('unable to carry out a calculation for "{}"'
|
display_name = option_bag.option.impl_get_display_name()
|
||||||
', {}').format(option.impl_get_display_name(), err), err) from err
|
raise ConfigError(_('unable to carry out a calculation for "{}", {}').format(display_name, err)) from err
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option_bag.option.impl_get_display_name(), err)) from err
|
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option_bag.option.impl_get_display_name(), err)) from err
|
||||||
except AttributeError as err:
|
except AttributeError as err:
|
||||||
|
@ -324,7 +324,8 @@ def manager_callback(callback: Callable,
|
||||||
['configerror'],
|
['configerror'],
|
||||||
config_bag.context.get_settings(),
|
config_bag.context.get_settings(),
|
||||||
)
|
)
|
||||||
raise ConfigError(_(f'unable to get value for calculating "{option_bag.option.impl_get_display_name()}", {err}')) from err
|
display_name = option_bag.option.impl_get_display_name()
|
||||||
|
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def get_option_bag(config_bag,
|
def get_option_bag(config_bag,
|
||||||
|
@ -359,8 +360,8 @@ def manager_callback(callback: Callable,
|
||||||
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
# raise PropertiesOptionError (which is catched) because must not add value None in carry_out_calculation
|
||||||
if param.notraisepropertyerror or param.raisepropertyerror:
|
if param.notraisepropertyerror or param.raisepropertyerror:
|
||||||
raise err from err
|
raise err from err
|
||||||
raise ConfigError(_('unable to carry out a calculation for "{}"'
|
display_name = option.impl_get_display_name()
|
||||||
', {}').format(option.impl_get_display_name(), err), err) from err
|
raise ConfigError(_('unable to carry out a calculation for "{}", {}').format(display_name, err)) from err
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option.impl_get_display_name(), err)) from err
|
raise ValueError(_('the option "{0}" is used in a calculation but is invalid ({1})').format(option.impl_get_display_name(), err)) from err
|
||||||
except AttributeError as err:
|
except AttributeError as err:
|
||||||
|
@ -370,7 +371,8 @@ def manager_callback(callback: Callable,
|
||||||
['configerror'],
|
['configerror'],
|
||||||
config_bag.context.get_settings(),
|
config_bag.context.get_settings(),
|
||||||
)
|
)
|
||||||
raise ConfigError(_(f'unable to get value for calculating "{option.impl_get_display_name()}", {err}')) from err
|
display_name = option.impl_get_display_name()
|
||||||
|
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
||||||
if len(options_bag) > 1:
|
if len(options_bag) > 1:
|
||||||
parent_option_bag = options_bag[-2]
|
parent_option_bag = options_bag[-2]
|
||||||
else:
|
else:
|
||||||
|
@ -399,17 +401,17 @@ def manager_callback(callback: Callable,
|
||||||
param.default_value,
|
param.default_value,
|
||||||
)
|
)
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
raise ConfigError(_('option "{}" cannot be calculated: {}').format(option.impl_get_display_name(),
|
display_name = option.impl_get_display_name()
|
||||||
str(err),
|
raise ConfigError(_(f'unable to get value for calculating "{display_name}", {err}')) from err
|
||||||
))
|
|
||||||
|
|
||||||
if isinstance(param, ParamIndex):
|
if isinstance(param, ParamIndex):
|
||||||
return index
|
return index
|
||||||
|
|
||||||
if isinstance(param, ParamSuffix):
|
if isinstance(param, ParamSuffix):
|
||||||
if not option.issubdyn():
|
if not option.issubdyn():
|
||||||
raise ConfigError(_('option "{}" is not in a dynoptiondescription').format(option.impl_get_display_name()))
|
display_name = option_bag.option.impl_get_display_name()
|
||||||
return option.impl_getsuffix()
|
raise ConfigError(_('option "{display_name}" is not in a dynoptiondescription'))
|
||||||
|
return option.get_suffixes()[-1]
|
||||||
|
|
||||||
if isinstance(param, ParamSelfOption):
|
if isinstance(param, ParamSelfOption):
|
||||||
value = calc_self(param,
|
value = calc_self(param,
|
||||||
|
@ -452,46 +454,26 @@ def manager_callback(callback: Callable,
|
||||||
raise ConfigError(_(f'option "{option.impl_get_display_name()}" is not in a dynoptiondescription: {err}'))
|
raise ConfigError(_(f'option "{option.impl_get_display_name()}" is not in a dynoptiondescription: {err}'))
|
||||||
callbk_option = soptions_bag[-1].option
|
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 option.opt.issubdyn() and callbk_option.getsubdyn() == option.getsubdyn() or \
|
in_same_dyn = False
|
||||||
not option.opt.issubdyn() and callbk_option.getsubdyn() == option.opt:
|
if not option.opt.issubdyn() and callbk_option.getsubdyn() == option.opt:
|
||||||
# in same dynoption
|
# First dyn
|
||||||
suffix = option.impl_getsuffix()
|
in_same_dyn = True
|
||||||
subdyn = callbk_option.getsubdyn()
|
elif option.opt.issubdyn():
|
||||||
root_path, sub_path = subdyn.split_path(subdyn,
|
# Search if callback and option has a common subdyn
|
||||||
option,
|
callbk_subdyn = callbk_option.getsubdyn()
|
||||||
)
|
sub_dyn = option
|
||||||
if root_path:
|
while True:
|
||||||
parent_path = root_path + subdyn.impl_getname(suffix) + sub_path
|
sub_dyn = sub_dyn.getsubdyn()
|
||||||
else:
|
if sub_dyn == callbk_subdyn:
|
||||||
parent_path = subdyn.impl_getname(suffix) + sub_path
|
in_same_dyn = True
|
||||||
callbk_option = callbk_option.to_dynoption(parent_path,
|
break
|
||||||
suffix,
|
if not sub_dyn.issubdyn():
|
||||||
subdyn,
|
break
|
||||||
)
|
if in_same_dyn:
|
||||||
|
callbk_option = callbk_option.to_sub_dyoption(option.get_suffixes())
|
||||||
found = True
|
found = True
|
||||||
if not found:
|
if not found:
|
||||||
callbk_options = []
|
callbk_options = []
|
||||||
|
@ -519,8 +501,6 @@ 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,
|
||||||
|
@ -602,6 +582,7 @@ def carry_out_calculation(option,
|
||||||
kwargs,
|
kwargs,
|
||||||
)
|
)
|
||||||
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \
|
if isinstance(ret, list) and not option.impl_is_dynoptiondescription() and \
|
||||||
|
not option.impl_is_optiondescription() and \
|
||||||
option.impl_is_follower() and not option.impl_is_submulti():
|
option.impl_is_follower() and not option.impl_is_submulti():
|
||||||
if args or kwargs:
|
if args or kwargs:
|
||||||
raise LeadershipError(_('the "{}" function with positional arguments "{}" '
|
raise LeadershipError(_('the "{}" function with positional arguments "{}" '
|
||||||
|
|
|
@ -27,7 +27,6 @@ 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 _
|
||||||
|
@ -164,6 +163,16 @@ class _SubConfig:
|
||||||
)
|
)
|
||||||
except AttributeError as err:
|
except AttributeError as err:
|
||||||
raise ConfigError(_(f'option "{option.impl_get_display_name()}" is not in a dynoptiondescription: {err}'))
|
raise ConfigError(_(f'option "{option.impl_get_display_name()}" is not in a dynoptiondescription: {err}'))
|
||||||
|
if options_bag[-1].option.impl_is_dynoptiondescription():
|
||||||
|
for suffix in options_bag[-1].option.get_suffixes(config_bag, dynoption=options_bag[-2].option):
|
||||||
|
dynopt = options_bag[-1].option.to_dynoption(options_bag[-2].path,
|
||||||
|
options_bag[-2].option._suffixes + [suffix],
|
||||||
|
)
|
||||||
|
doption_bag = OptionBag(dynopt, None, option_bag.config_bag)
|
||||||
|
self.reset_one_option_cache(resetted_opts,
|
||||||
|
doption_bag,
|
||||||
|
)
|
||||||
|
else:
|
||||||
self._reset_cache_dyn_optiondescription(options_bag[-1],
|
self._reset_cache_dyn_optiondescription(options_bag[-1],
|
||||||
resetted_opts,
|
resetted_opts,
|
||||||
)
|
)
|
||||||
|
@ -182,18 +191,37 @@ class _SubConfig:
|
||||||
# it's an option in dynoptiondescription, remove cache for all generated option
|
# it's an option in dynoptiondescription, remove cache for all generated option
|
||||||
config_bag = option_bag.config_bag
|
config_bag = option_bag.config_bag
|
||||||
options = [soption_bag]
|
options = [soption_bag]
|
||||||
for wdynopt in reversed(option.get_sub_dyns()):
|
dynopt = option.get_sub_dyns()[-1]()
|
||||||
dynopt = wdynopt()
|
dyn_path = dynopt.impl_getpath()
|
||||||
sub_options = []
|
if '.' in dyn_path:
|
||||||
for sub_option in options:
|
root_path = dyn_path.rsplit('.', 1)[0]
|
||||||
sub_options.extend(dynopt.get_sub_children(sub_option.option,
|
else:
|
||||||
|
root_path = ''
|
||||||
|
for suffix in dynopt.get_suffixes(config_bag):
|
||||||
|
suffix_dynopt = dynopt.to_dynoption(root_path,
|
||||||
|
[suffix],
|
||||||
|
)
|
||||||
|
soption_bag = OptionBag(suffix_dynopt, None, config_bag)
|
||||||
|
for data in self.walk(soption_bag, validate_properties=False):
|
||||||
|
if isinstance(data, dict):
|
||||||
|
leader = data.pop('leader')
|
||||||
|
resetted_opts.append(leader.path)
|
||||||
|
leader.option.reset_cache(leader.path,
|
||||||
config_bag,
|
config_bag,
|
||||||
properties=None,
|
resetted_opts,
|
||||||
))
|
)
|
||||||
options = sub_options
|
for followers in data.values():
|
||||||
for doption_bag in options:
|
for follower in followers:
|
||||||
self.reset_one_option_cache(resetted_opts,
|
resetted_opts.append(follower.path)
|
||||||
doption_bag,
|
follower.option.reset_cache(follower.path,
|
||||||
|
config_bag,
|
||||||
|
resetted_opts,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
resetted_opts.append(data.path)
|
||||||
|
data.option.reset_cache(data.path,
|
||||||
|
config_bag,
|
||||||
|
resetted_opts,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.reset_one_option_cache(resetted_opts,
|
self.reset_one_option_cache(resetted_opts,
|
||||||
|
@ -235,12 +263,7 @@ class _SubConfig:
|
||||||
option_bag,
|
option_bag,
|
||||||
resetted_opts,
|
resetted_opts,
|
||||||
):
|
):
|
||||||
option = option_bag.option
|
for doption_bag in option_bag.option.get_sub_children(option_bag.option,
|
||||||
if isinstance(option, (DynOptionDescription, SubDynOptionDescription)):
|
|
||||||
dynoption = option
|
|
||||||
else:
|
|
||||||
dynoption = option.getsubdyn()
|
|
||||||
for doption_bag in dynoption.get_sub_children(option,
|
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
index=option_bag.index,
|
index=option_bag.index,
|
||||||
properties=None
|
properties=None
|
||||||
|
@ -338,11 +361,13 @@ class _SubConfig:
|
||||||
|
|
||||||
def walk(self,
|
def walk(self,
|
||||||
option_bag: OptionBag,
|
option_bag: OptionBag,
|
||||||
|
*,
|
||||||
types: List[str]=('option',),
|
types: List[str]=('option',),
|
||||||
group_type=None,
|
group_type=None,
|
||||||
recursive: bool=True,
|
recursive: bool=True,
|
||||||
walked: bool=False,
|
walked: bool=False,
|
||||||
flatten_leadership: bool=False,
|
flatten_leadership: bool=False,
|
||||||
|
validate_properties: bool=True,
|
||||||
):
|
):
|
||||||
"""walk to tree
|
"""walk to tree
|
||||||
"""
|
"""
|
||||||
|
@ -362,13 +387,14 @@ class _SubConfig:
|
||||||
yield from self.walk(self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
yield from self.walk(self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
||||||
opt.impl_getpath(),
|
opt.impl_getpath(),
|
||||||
None,
|
None,
|
||||||
True,
|
validate_properties,
|
||||||
follower_not_apply_requires=flatten_leadership,
|
follower_not_apply_requires=flatten_leadership,
|
||||||
)[-1],
|
)[-1],
|
||||||
types=types,
|
types=types,
|
||||||
recursive=recursive,
|
recursive=recursive,
|
||||||
group_type=group_type,
|
group_type=group_type,
|
||||||
walked=True,
|
walked=True,
|
||||||
|
validate_properties=validate_properties,
|
||||||
)
|
)
|
||||||
except PropertiesOptionError as err:
|
except PropertiesOptionError as err:
|
||||||
if err.proptype in (['mandatory'], ['empty']):
|
if err.proptype in (['mandatory'], ['empty']):
|
||||||
|
@ -380,7 +406,7 @@ class _SubConfig:
|
||||||
leader_option_bag = self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
leader_option_bag = self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
||||||
leader.impl_getpath(),
|
leader.impl_getpath(),
|
||||||
None,
|
None,
|
||||||
True,
|
validate_properties,
|
||||||
)[-1]
|
)[-1]
|
||||||
followers_dict = {'leader': leader_option_bag}
|
followers_dict = {'leader': leader_option_bag}
|
||||||
values = self.get_value(leader_option_bag,
|
values = self.get_value(leader_option_bag,
|
||||||
|
@ -403,7 +429,7 @@ class _SubConfig:
|
||||||
options_bag = self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
options_bag = self.get_sub_option_bag(option_bag, # pylint: disable=no-member
|
||||||
follower_path,
|
follower_path,
|
||||||
idx,
|
idx,
|
||||||
True,
|
validate_properties,
|
||||||
leadership_length=ls_length,
|
leadership_length=ls_length,
|
||||||
)
|
)
|
||||||
for f_follower_bag in self.walk(options_bag[-1],
|
for f_follower_bag in self.walk(options_bag[-1],
|
||||||
|
@ -411,6 +437,7 @@ class _SubConfig:
|
||||||
recursive=recursive,
|
recursive=recursive,
|
||||||
group_type=group_type,
|
group_type=group_type,
|
||||||
walked=True,
|
walked=True,
|
||||||
|
validate_properties=validate_properties,
|
||||||
):
|
):
|
||||||
if 'mandatory' in types:
|
if 'mandatory' in types:
|
||||||
yield f_follower_bag
|
yield f_follower_bag
|
||||||
|
@ -576,7 +603,7 @@ class _CommonConfig(_SubConfig):
|
||||||
def _impl_build_all_caches(self, descr):
|
def _impl_build_all_caches(self, descr):
|
||||||
if not descr.impl_already_build_caches():
|
if not descr.impl_already_build_caches():
|
||||||
descr._group_type = groups.root # pylint: disable=protected-access
|
descr._group_type = groups.root # pylint: disable=protected-access
|
||||||
descr._build_cache(display_name=self._display_name) # pylint: disable=no-member,protected-access
|
descr._build_cache(self._display_name) # pylint: disable=no-member,protected-access
|
||||||
if not hasattr(descr, '_cache_force_store_values'):
|
if not hasattr(descr, '_cache_force_store_values'):
|
||||||
raise ConfigError(_('option description seems to be part of an other '
|
raise ConfigError(_('option description seems to be part of an other '
|
||||||
'config'))
|
'config'))
|
||||||
|
@ -727,8 +754,8 @@ class _CommonConfig(_SubConfig):
|
||||||
path: str,
|
path: str,
|
||||||
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,
|
allow_dynoption: bool=False,
|
||||||
|
@ -755,13 +782,8 @@ class _CommonConfig(_SubConfig):
|
||||||
if not suboption.impl_is_optiondescription():
|
if not suboption.impl_is_optiondescription():
|
||||||
raise TypeError(f'{suboption.impl_getpath()} is not an optiondescription')
|
raise TypeError(f'{suboption.impl_getpath()} is not an optiondescription')
|
||||||
|
|
||||||
if not idx and option_bag.option == self.get_description():
|
|
||||||
subpath = None
|
|
||||||
else:
|
|
||||||
subpath = suboption.impl_getpath()
|
|
||||||
option = suboption.get_child(step,
|
option = suboption.get_child(step,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
subpath,
|
|
||||||
allow_dynoption=allow_dynoption,
|
allow_dynoption=allow_dynoption,
|
||||||
)
|
)
|
||||||
if idx == last_idx:
|
if idx == last_idx:
|
||||||
|
@ -787,6 +809,9 @@ class _CommonConfig(_SubConfig):
|
||||||
option_index = None
|
option_index = None
|
||||||
apply_requires = True
|
apply_requires = True
|
||||||
option_properties = undefined
|
option_properties = undefined
|
||||||
|
if option_properties is undefined and not validate_properties:
|
||||||
|
# not transitive property error
|
||||||
|
apply_requires = False
|
||||||
sub_option_bag = OptionBag(option,
|
sub_option_bag = OptionBag(option,
|
||||||
option_index,
|
option_index,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
|
|
|
@ -40,8 +40,8 @@ def valid_name(name):
|
||||||
"""
|
"""
|
||||||
if not isinstance(name, str):
|
if not isinstance(name, str):
|
||||||
return False
|
return False
|
||||||
# if '.' in name:
|
if '.' in name:
|
||||||
# return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -166,8 +166,7 @@ class Base:
|
||||||
def impl_is_readonly(self) -> str:
|
def impl_is_readonly(self) -> str:
|
||||||
"""the option is readonly
|
"""the option is readonly
|
||||||
"""
|
"""
|
||||||
# _path is None when initialise SymLinkOption
|
return hasattr(self, '_path')
|
||||||
return hasattr(self, '_path') and self._path is not None # pylint: disable=no-member
|
|
||||||
|
|
||||||
def impl_getproperties(self) -> FrozenSet[str]:
|
def impl_getproperties(self) -> FrozenSet[str]:
|
||||||
"""get properties
|
"""get properties
|
||||||
|
@ -322,3 +321,34 @@ class BaseOption(Base):
|
||||||
"""get dependencies information
|
"""get dependencies information
|
||||||
"""
|
"""
|
||||||
return getattr(self, '_dependencies_information', {})
|
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)
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
|
|
@ -88,6 +88,7 @@ class DynOptionDescription(OptionDescription):
|
||||||
|
|
||||||
def get_suffixes(self,
|
def get_suffixes(self,
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
|
*,
|
||||||
dynoption=None,
|
dynoption=None,
|
||||||
) -> List[str]:
|
) -> List[str]:
|
||||||
"""get dynamic suffixes
|
"""get dynamic suffixes
|
||||||
|
@ -134,8 +135,9 @@ class DynOptionDescription(OptionDescription):
|
||||||
(option.impl_is_sub_dyn_optiondescription() and option.opt == self)
|
(option.impl_is_sub_dyn_optiondescription() and option.opt == self)
|
||||||
|
|
||||||
def split_path(self,
|
def split_path(self,
|
||||||
dynoption,
|
|
||||||
option,
|
option,
|
||||||
|
*,
|
||||||
|
dynoption=None,
|
||||||
) -> Tuple[str, str]:
|
) -> Tuple[str, str]:
|
||||||
"""self.impl_getpath() is something like root.xxx.dynoption_path
|
"""self.impl_getpath() is something like root.xxx.dynoption_path
|
||||||
option.impl_getpath() is something like root.xxx.dynoption_path.sub.path
|
option.impl_getpath() is something like root.xxx.dynoption_path.sub.path
|
||||||
|
@ -169,8 +171,8 @@ class DynOptionDescription(OptionDescription):
|
||||||
properties=undefined,
|
properties=undefined,
|
||||||
dynoption=None,
|
dynoption=None,
|
||||||
):
|
):
|
||||||
root_path, sub_path = self.split_path(dynoption,
|
root_path, sub_path = self.split_path(option,
|
||||||
option,
|
dynoption=dynoption,
|
||||||
)
|
)
|
||||||
for suffix in self.get_suffixes(config_bag,
|
for suffix in self.get_suffixes(config_bag,
|
||||||
dynoption=dynoption,
|
dynoption=dynoption,
|
||||||
|
@ -182,8 +184,7 @@ class DynOptionDescription(OptionDescription):
|
||||||
else:
|
else:
|
||||||
parent_path = self.impl_getname(suffix) + sub_path
|
parent_path = self.impl_getname(suffix) + sub_path
|
||||||
yield OptionBag(option.to_dynoption(parent_path,
|
yield OptionBag(option.to_dynoption(parent_path,
|
||||||
suffix,
|
[suffix],
|
||||||
self,
|
|
||||||
),
|
),
|
||||||
index,
|
index,
|
||||||
config_bag,
|
config_bag,
|
||||||
|
|
|
@ -248,11 +248,9 @@ class Leadership(OptionDescription):
|
||||||
|
|
||||||
def to_dynoption(self,
|
def to_dynoption(self,
|
||||||
rootpath: str,
|
rootpath: str,
|
||||||
suffix: str,
|
suffixes: Optional[list],
|
||||||
ori_dyn,
|
|
||||||
) -> SynDynLeadership:
|
) -> SynDynLeadership:
|
||||||
return SynDynLeadership(self,
|
return SynDynLeadership(self,
|
||||||
rootpath,
|
rootpath,
|
||||||
suffix,
|
suffixes,
|
||||||
ori_dyn,
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -464,15 +464,13 @@ class Option(BaseOption):
|
||||||
|
|
||||||
def to_dynoption(self,
|
def to_dynoption(self,
|
||||||
rootpath: str,
|
rootpath: str,
|
||||||
suffix: str,
|
suffixes: list[str],
|
||||||
dyn_parent,
|
|
||||||
) -> SynDynOption:
|
) -> SynDynOption:
|
||||||
"""tranforme a dynoption to a syndynoption
|
"""tranforme a dynoption to a syndynoption
|
||||||
"""
|
"""
|
||||||
return SynDynOption(self,
|
return SynDynOption(self,
|
||||||
rootpath,
|
rootpath,
|
||||||
suffix,
|
suffixes,
|
||||||
dyn_parent,
|
|
||||||
)
|
)
|
||||||
def validate(self, value: Any):
|
def validate(self, value: Any):
|
||||||
"""option needs a validate function
|
"""option needs a validate function
|
||||||
|
|
|
@ -44,13 +44,13 @@ class CacheOptionDescription(BaseOption):
|
||||||
return self.impl_is_readonly()
|
return self.impl_is_readonly()
|
||||||
|
|
||||||
def _build_cache(self,
|
def _build_cache(self,
|
||||||
|
display_name,
|
||||||
_consistencies=None,
|
_consistencies=None,
|
||||||
_consistencies_id=0,
|
_consistencies_id=0,
|
||||||
currpath: List[str]=None,
|
currpath: List[str]=None,
|
||||||
cache_option=None,
|
cache_option=None,
|
||||||
force_store_values=None,
|
force_store_values=None,
|
||||||
dependencies_information=None,
|
dependencies_information=None,
|
||||||
display_name=None,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
"""validate options and set option has readonly option
|
"""validate options and set option has readonly option
|
||||||
"""
|
"""
|
||||||
|
@ -80,13 +80,13 @@ class CacheOptionDescription(BaseOption):
|
||||||
subpath = '.'.join(sub_currpath)
|
subpath = '.'.join(sub_currpath)
|
||||||
if isinstance(option, OptionDescription):
|
if isinstance(option, OptionDescription):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
option._build_cache(_consistencies,
|
option._build_cache(display_name,
|
||||||
|
_consistencies,
|
||||||
_consistencies_id,
|
_consistencies_id,
|
||||||
sub_currpath,
|
sub_currpath,
|
||||||
cache_option,
|
cache_option,
|
||||||
force_store_values,
|
force_store_values,
|
||||||
dependencies_information,
|
dependencies_information,
|
||||||
display_name,
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
for information, options in option.get_dependencies_information().items():
|
for information, options in option.get_dependencies_information().items():
|
||||||
|
@ -96,15 +96,6 @@ class CacheOptionDescription(BaseOption):
|
||||||
properties = option.impl_getproperties()
|
properties = option.impl_getproperties()
|
||||||
if 'force_store_value' in properties:
|
if 'force_store_value' in properties:
|
||||||
force_store_values.append(option)
|
force_store_values.append(option)
|
||||||
# if __debug__ and ('force_default_on_freeze' in properties or \
|
|
||||||
# 'force_metaconfig_on_freeze' in properties) and \
|
|
||||||
# 'frozen' not in properties and \
|
|
||||||
# option.impl_is_leader():
|
|
||||||
# raise ConfigError(_('a leader ({0}) cannot have '
|
|
||||||
# '"force_default_on_freeze" or '
|
|
||||||
# '"force_metaconfig_on_freeze" '
|
|
||||||
# 'property without "frozen"'
|
|
||||||
# '').format(option.impl_get_display_name()))
|
|
||||||
if option.impl_is_readonly():
|
if option.impl_is_readonly():
|
||||||
raise ConflictError(_('duplicate option: {0}').format(option))
|
raise ConflictError(_('duplicate option: {0}').format(option))
|
||||||
if not self.impl_is_readonly() and display_name:
|
if not self.impl_is_readonly() and display_name:
|
||||||
|
@ -114,7 +105,7 @@ class CacheOptionDescription(BaseOption):
|
||||||
if init:
|
if init:
|
||||||
self._cache_force_store_values = force_store_values # pylint: disable=attribute-defined-outside-init
|
self._cache_force_store_values = force_store_values # pylint: disable=attribute-defined-outside-init
|
||||||
self._cache_dependencies_information = dependencies_information # pylint: disable=attribute-defined-outside-init
|
self._cache_dependencies_information = dependencies_information # pylint: disable=attribute-defined-outside-init
|
||||||
self._path = self._name # pylint: disable=attribute-defined-outside-init,no-member
|
self._path = None # pylint: disable=attribute-defined-outside-init,no-member
|
||||||
self._set_readonly()
|
self._set_readonly()
|
||||||
|
|
||||||
def impl_build_force_store_values(self,
|
def impl_build_force_store_values(self,
|
||||||
|
@ -146,10 +137,8 @@ class CacheOptionDescription(BaseOption):
|
||||||
leader_option_bag.properties = frozenset()
|
leader_option_bag.properties = frozenset()
|
||||||
follower_len = len(values.get_value(leader_option_bag)[0])
|
follower_len = len(values.get_value(leader_option_bag)[0])
|
||||||
if option.issubdyn():
|
if option.issubdyn():
|
||||||
subpath = leader_option_bag.option.rootpath
|
doption = option.to_dynoption(leader_option_bag.option.rootpath,
|
||||||
doption = option.to_dynoption(subpath,
|
leader_option_bag.option.get_suffixes(),
|
||||||
leader_option_bag.option.impl_getsuffix(),
|
|
||||||
leader_option_bag.option.dyn_parent,
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
doption = option
|
doption = option
|
||||||
|
@ -190,56 +179,48 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||||
"""
|
"""
|
||||||
__slots__ = ('_children',)
|
__slots__ = ('_children',)
|
||||||
|
|
||||||
|
def get_child_not_dynamic(self,
|
||||||
|
name,
|
||||||
|
allow_dynoption,
|
||||||
|
):
|
||||||
|
if name in self._children[0]: # pylint: disable=no-member
|
||||||
|
option = self._children[1][self._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 option
|
||||||
|
|
||||||
def get_child(self,
|
def get_child(self,
|
||||||
name: str,
|
name: str,
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
subpath: str,
|
|
||||||
*,
|
*,
|
||||||
dynoption=None,
|
|
||||||
option_suffix: Optional[str]=None,
|
|
||||||
allow_dynoption: bool=False,
|
allow_dynoption: bool=False,
|
||||||
) -> Union[BaseOption, SynDynOptionDescription]:
|
) -> Union[BaseOption, SynDynOptionDescription]:
|
||||||
"""get a child
|
"""get a child
|
||||||
"""
|
"""
|
||||||
# if not dyn
|
# if not dyn
|
||||||
if name in self._children[0]: # pylint: disable=no-member
|
option = self.get_child_not_dynamic(name,
|
||||||
option = self._children[1][self._children[0].index(name)] # pylint: disable=no-member
|
allow_dynoption,
|
||||||
if option.impl_is_dynoptiondescription():
|
|
||||||
if allow_dynoption:
|
|
||||||
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,
|
|
||||||
)
|
)
|
||||||
|
if 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
|
||||||
for suffix in child.get_suffixes(config_bag,
|
for suffix in child.get_suffixes(config_bag):
|
||||||
dynoption,
|
|
||||||
):
|
|
||||||
if name != child.impl_getname(suffix):
|
if name != child.impl_getname(suffix):
|
||||||
continue
|
continue
|
||||||
return child.to_dynoption(subpath,
|
return child.to_dynoption(self.impl_getpath(),
|
||||||
suffix,
|
[suffix],
|
||||||
child,
|
|
||||||
)
|
)
|
||||||
if self.impl_get_group_type() == groups.root: # pylint: disable=no-member
|
if self.impl_get_group_type() == groups.root: # pylint: disable=no-member
|
||||||
raise AttributeError(_(f'unknown option "{name}" '
|
raise AttributeError(_(f'unknown option "{name}" '
|
||||||
'in root optiondescription'
|
'in root optiondescription'
|
||||||
))
|
))
|
||||||
raise AttributeError(_(f'unknown option "{name}" '
|
raise AttributeError(_(f'unknown option "{name}" '
|
||||||
f'in optiondescription "{self_opt.impl_get_display_name()}"'
|
f'in optiondescription "{self.impl_get_display_name()}"'
|
||||||
))
|
))
|
||||||
|
|
||||||
def get_children(self,
|
def get_children(self,
|
||||||
|
@ -248,43 +229,54 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||||
dyn: bool=True,
|
dyn: bool=True,
|
||||||
#path: Optional[str]=None,
|
#path: Optional[str]=None,
|
||||||
dynoption=None,
|
dynoption=None,
|
||||||
option_suffix: Optional[str]=None,
|
|
||||||
) -> Union[BaseOption, SynDynOptionDescription]:
|
) -> Union[BaseOption, SynDynOptionDescription]:
|
||||||
"""get children
|
"""get children
|
||||||
"""
|
"""
|
||||||
# if path:
|
for child in self._children[1]:
|
||||||
# subpath = path
|
|
||||||
if dynoption:
|
|
||||||
self_opt = dynoption
|
|
||||||
else:
|
|
||||||
self_opt = self
|
|
||||||
if not dyn or config_bag is undefined or \
|
|
||||||
config_bag.context.get_description() == self:
|
|
||||||
subpath = ''
|
|
||||||
else:
|
|
||||||
subpath = self_opt.impl_getpath()
|
|
||||||
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,
|
yield from self.get_suffixed_children(dynoption,
|
||||||
dynoption,
|
[],
|
||||||
):
|
config_bag,
|
||||||
yield child.to_dynoption(subpath,
|
|
||||||
suffix,
|
|
||||||
child,
|
|
||||||
)
|
|
||||||
elif dyn and child.issubdyn() or child.impl_is_dynsymlinkoption():
|
|
||||||
yield child.to_dynoption(subpath,
|
|
||||||
option_suffix,
|
|
||||||
child,
|
child,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
yield child
|
yield child
|
||||||
|
|
||||||
|
def get_path(self,
|
||||||
|
config_bag,
|
||||||
|
dynoption,
|
||||||
|
):
|
||||||
|
if dynoption:
|
||||||
|
self_opt = dynoption
|
||||||
|
else:
|
||||||
|
self_opt = self
|
||||||
|
if config_bag is undefined or \
|
||||||
|
config_bag.context.get_description() == self:
|
||||||
|
return ''
|
||||||
|
return self_opt.impl_getpath()
|
||||||
|
|
||||||
|
def get_suffixed_children(self,
|
||||||
|
dynoption,
|
||||||
|
option_suffixes: list,
|
||||||
|
config_bag: ConfigBag,
|
||||||
|
child,
|
||||||
|
):
|
||||||
|
root_path = self.get_path(config_bag, dynoption)
|
||||||
|
for suffix in child.get_suffixes(config_bag,
|
||||||
|
dynoption=dynoption,
|
||||||
|
):
|
||||||
|
yield child.to_dynoption(root_path,
|
||||||
|
option_suffixes + [suffix],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_children_recursively(self,
|
def get_children_recursively(self,
|
||||||
bytype: Optional[BaseOption],
|
bytype: Optional[BaseOption],
|
||||||
byname: Optional[str],
|
byname: Optional[str],
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
self_opt: BaseOption=None,
|
self_opt: BaseOption=None,
|
||||||
|
*,
|
||||||
|
option_suffixes: Optional[list]=None
|
||||||
) -> Iterator[Union[BaseOption, SynDynOptionDescription]]:
|
) -> Iterator[Union[BaseOption, SynDynOptionDescription]]:
|
||||||
"""get children recursively
|
"""get children recursively
|
||||||
"""
|
"""
|
||||||
|
@ -402,19 +394,19 @@ class OptionDescription(OptionDescriptionWalk):
|
||||||
|
|
||||||
def to_dynoption(self,
|
def to_dynoption(self,
|
||||||
rootpath: str,
|
rootpath: str,
|
||||||
suffix: str,
|
suffixes: Optional[list],
|
||||||
ori_dyn) -> SynDynOptionDescription:
|
#ori_dyn,
|
||||||
|
) -> Union[SubDynOptionDescription, SynDynOptionDescription]:
|
||||||
"""get syn dyn option description
|
"""get syn dyn option description
|
||||||
"""
|
"""
|
||||||
if suffix is None:
|
if self.impl_is_dynoptiondescription():
|
||||||
return SubDynOptionDescription(self,
|
obj = SynDynOptionDescription
|
||||||
|
else:
|
||||||
|
obj = SubDynOptionDescription
|
||||||
|
return obj(self,
|
||||||
rootpath,
|
rootpath,
|
||||||
ori_dyn,
|
suffixes,
|
||||||
)
|
)
|
||||||
return SynDynOptionDescription(self,
|
|
||||||
rootpath,
|
|
||||||
suffix,
|
|
||||||
ori_dyn)
|
|
||||||
|
|
||||||
def impl_is_dynsymlinkoption(self) -> bool:
|
def impl_is_dynsymlinkoption(self) -> bool:
|
||||||
"""option is not a dyn symlink option
|
"""option is not a dyn symlink option
|
||||||
|
|
|
@ -47,11 +47,12 @@ class SymLinkOption(BaseOption):
|
||||||
_setattr(self, '_name', name)
|
_setattr(self, '_name', name)
|
||||||
_setattr(self, '_opt', opt)
|
_setattr(self, '_opt', opt)
|
||||||
opt._add_dependency(self)
|
opt._add_dependency(self)
|
||||||
self._path = None
|
|
||||||
|
|
||||||
def __getattr__(self,
|
def __getattr__(self,
|
||||||
name: str,
|
name: str,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
|
if name == '_path':
|
||||||
|
raise AttributeError()
|
||||||
return getattr(self._opt, name)
|
return getattr(self._opt, name)
|
||||||
|
|
||||||
def _setsubdyn(self,
|
def _setsubdyn(self,
|
||||||
|
|
|
@ -29,20 +29,17 @@ class SynDynOption:
|
||||||
"""
|
"""
|
||||||
__slots__ = ('rootpath',
|
__slots__ = ('rootpath',
|
||||||
'opt',
|
'opt',
|
||||||
'suffix',
|
'suffixes',
|
||||||
'dyn_parent',
|
|
||||||
'__weakref__')
|
'__weakref__')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
opt: BaseOption,
|
opt: BaseOption,
|
||||||
rootpath: str,
|
rootpath: str,
|
||||||
suffix: str,
|
suffixes: list,
|
||||||
dyn_parent,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
self.opt = opt
|
self.opt = opt
|
||||||
self.rootpath = rootpath
|
self.rootpath = rootpath
|
||||||
self.suffix = suffix
|
self.suffixes = suffixes
|
||||||
self.dyn_parent = dyn_parent
|
|
||||||
|
|
||||||
def __getattr__(self,
|
def __getattr__(self,
|
||||||
name: str) -> Any:
|
name: str) -> Any:
|
||||||
|
@ -60,10 +57,10 @@ class SynDynOption:
|
||||||
"""
|
"""
|
||||||
return self.opt.impl_get_display_name(self)
|
return self.opt.impl_get_display_name(self)
|
||||||
|
|
||||||
def impl_getsuffix(self) -> str:
|
def get_suffixes(self) -> str:
|
||||||
"""get suffix
|
"""get suffix
|
||||||
"""
|
"""
|
||||||
return self.suffix
|
return self.suffixes
|
||||||
|
|
||||||
def impl_getpath(self) -> str:
|
def impl_getpath(self) -> str:
|
||||||
"""get path
|
"""get path
|
||||||
|
@ -85,6 +82,5 @@ class SynDynOption:
|
||||||
if leadership:
|
if leadership:
|
||||||
rootpath = self.rootpath.rsplit('.', 1)[0]
|
rootpath = self.rootpath.rsplit('.', 1)[0]
|
||||||
return leadership.to_dynoption(rootpath,
|
return leadership.to_dynoption(rootpath,
|
||||||
self.suffix,
|
self.suffixes,
|
||||||
self.dyn_parent,
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,155 +30,75 @@ from .baseoption import BaseOption
|
||||||
from .syndynoption import SynDynOption
|
from .syndynoption import SynDynOption
|
||||||
|
|
||||||
|
|
||||||
class SubDynOptionDescription:
|
class Syn:
|
||||||
__slots__ = ('rootpath',
|
__slots__ = ('opt',
|
||||||
'opt',
|
'rootpath',
|
||||||
'dyn_parent',
|
'_suffixes',
|
||||||
'__weakref__',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
opt: BaseOption,
|
opt: BaseOption,
|
||||||
rootpath: str,
|
rootpath: str,
|
||||||
dyn_parent,
|
suffixes: list,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.opt = opt
|
self.opt = opt
|
||||||
self.rootpath = rootpath
|
self.rootpath = rootpath
|
||||||
self.dyn_parent = dyn_parent
|
self._suffixes = suffixes
|
||||||
|
|
||||||
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:
|
def impl_get_display_name(self) -> str:
|
||||||
return self.opt.impl_get_display_name(self)
|
return self.opt.impl_get_display_name(self)
|
||||||
|
|
||||||
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:
|
|
||||||
"""SynDynOptionDescription internal option, it's an instanciate synoptiondescription
|
|
||||||
"""
|
|
||||||
__slots__ = ('opt',
|
|
||||||
'rootpath',
|
|
||||||
'_suffix',
|
|
||||||
'ori_dyn')
|
|
||||||
|
|
||||||
def __init__(self,
|
|
||||||
opt: BaseOption,
|
|
||||||
rootpath: str,
|
|
||||||
suffix: str,
|
|
||||||
ori_dyn) -> None:
|
|
||||||
self.opt = opt
|
|
||||||
self.rootpath = rootpath
|
|
||||||
self._suffix = suffix
|
|
||||||
# For a Leadership inside a DynOptionDescription
|
|
||||||
self.ori_dyn = ori_dyn
|
|
||||||
|
|
||||||
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._suffix)
|
|
||||||
return self.opt.impl_getname()
|
|
||||||
|
|
||||||
def impl_get_display_name(self) -> str:
|
|
||||||
"""get display name
|
|
||||||
"""
|
|
||||||
return self.opt.impl_get_display_name(self)
|
|
||||||
|
|
||||||
def get_children(self,
|
|
||||||
config_bag: ConfigBag,
|
|
||||||
dyn: bool=True,
|
|
||||||
):
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
"""get children
|
|
||||||
"""
|
|
||||||
yield from self.opt.get_children(config_bag,
|
|
||||||
dynoption=self,
|
|
||||||
option_suffix=self._suffix,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_child(self,
|
def get_child(self,
|
||||||
name: str,
|
name: str,
|
||||||
config_bag: ConfigBag,
|
config_bag: ConfigBag,
|
||||||
subpath: str,
|
*,
|
||||||
allow_dynoption: bool=False,
|
allow_dynoption: bool=False,
|
||||||
):
|
):
|
||||||
"""get children
|
"""get children
|
||||||
"""
|
"""
|
||||||
return self.opt.get_child(name,
|
# if not dyn
|
||||||
config_bag,
|
option = self.opt.get_child_not_dynamic(name,
|
||||||
subpath,
|
allow_dynoption,
|
||||||
dynoption=self,
|
|
||||||
option_suffix=self._suffix,
|
|
||||||
allow_dynoption=allow_dynoption,
|
|
||||||
)
|
)
|
||||||
|
if option:
|
||||||
def get_sub_children(self,
|
if allow_dynoption and option.impl_is_dynoptiondescription():
|
||||||
option,
|
return option
|
||||||
config_bag,
|
return option.to_dynoption(self.impl_getpath(),
|
||||||
*,
|
self._suffixes,
|
||||||
index=None,
|
)
|
||||||
properties=undefined,
|
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,
|
||||||
):
|
):
|
||||||
return self.opt.get_sub_children(option,
|
if name != child.impl_getname(suffix):
|
||||||
config_bag,
|
continue
|
||||||
index=index,
|
return child.to_dynoption(self.impl_getpath(),
|
||||||
properties=properties,
|
self._suffixes + [suffix],
|
||||||
dynoption=self,
|
|
||||||
)
|
)
|
||||||
|
raise AttributeError(_(f'unknown option "{name}" '
|
||||||
|
f'in optiondescription "{self.impl_get_display_name()}"'
|
||||||
|
))
|
||||||
|
|
||||||
def impl_is_dynsymlinkoption(self) -> bool:
|
def get_children(self,
|
||||||
"""it's a dynsymlinkoption
|
config_bag: ConfigBag,
|
||||||
|
):
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
"""get children
|
||||||
"""
|
"""
|
||||||
return True
|
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,
|
def get_children_recursively(self,
|
||||||
bytype: Optional[BaseOption],
|
bytype: Optional[BaseOption],
|
||||||
|
@ -196,6 +116,64 @@ class SynDynOptionDescription:
|
||||||
):
|
):
|
||||||
yield option
|
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:
|
def impl_getpath(self) -> str:
|
||||||
"""get path
|
"""get path
|
||||||
"""
|
"""
|
||||||
|
@ -204,10 +182,8 @@ class SynDynOptionDescription:
|
||||||
path = f'{self.rootpath}.{path}'
|
path = f'{self.rootpath}.{path}'
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def impl_getsuffix(self) -> str:
|
def getsubdyn(self):
|
||||||
"""get suffix
|
return self.opt
|
||||||
"""
|
|
||||||
return self._suffix
|
|
||||||
|
|
||||||
|
|
||||||
class SynDynLeadership(SynDynOptionDescription):
|
class SynDynLeadership(SynDynOptionDescription):
|
||||||
|
@ -217,8 +193,7 @@ class SynDynLeadership(SynDynOptionDescription):
|
||||||
"""get the leader
|
"""get the leader
|
||||||
"""
|
"""
|
||||||
return self.opt.get_leader().to_dynoption(self.impl_getpath(),
|
return self.opt.get_leader().to_dynoption(self.impl_getpath(),
|
||||||
self._suffix,
|
self._suffixes,
|
||||||
self.ori_dyn,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_followers(self) -> Iterator[SynDynOption]:
|
def get_followers(self) -> Iterator[SynDynOption]:
|
||||||
|
@ -227,24 +202,7 @@ class SynDynLeadership(SynDynOptionDescription):
|
||||||
subpath = self.impl_getpath()
|
subpath = self.impl_getpath()
|
||||||
for follower in self.opt.get_followers():
|
for follower in self.opt.get_followers():
|
||||||
yield follower.to_dynoption(subpath,
|
yield follower.to_dynoption(subpath,
|
||||||
self._suffix,
|
self._suffixes,
|
||||||
self.ori_dyn,
|
|
||||||
)
|
|
||||||
|
|
||||||
def reset_cache(self,
|
|
||||||
path: str,
|
|
||||||
config_bag: 'ConfigBag',
|
|
||||||
resetted_opts: List[str],
|
|
||||||
) -> None:
|
|
||||||
"""reset cache
|
|
||||||
"""
|
|
||||||
leader = self.get_leader()
|
|
||||||
followers = self.get_followers()
|
|
||||||
self._reset_cache(path,
|
|
||||||
leader,
|
|
||||||
followers,
|
|
||||||
config_bag,
|
|
||||||
resetted_opts,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def pop(self,
|
def pop(self,
|
||||||
|
@ -271,7 +229,7 @@ class SynDynLeadership(SynDynOptionDescription):
|
||||||
dyn=self,
|
dyn=self,
|
||||||
)
|
)
|
||||||
|
|
||||||
def impl_getsuffix(self) -> str:
|
def get_suffixes(self) -> str:
|
||||||
"""get suffix
|
"""get suffix
|
||||||
"""
|
"""
|
||||||
return self._suffix
|
return self._suffixes
|
||||||
|
|
|
@ -192,7 +192,7 @@ class OptionBag:
|
||||||
elif option:
|
elif option:
|
||||||
self.path = option.impl_getpath()
|
self.path = option.impl_getpath()
|
||||||
context = config_bag.context
|
context = config_bag.context
|
||||||
if '.' not in self.path and option == context.get_description():
|
if self.path is None:
|
||||||
self.properties = None
|
self.properties = None
|
||||||
elif properties is undefined:
|
elif properties is undefined:
|
||||||
settings = context.get_settings()
|
settings = context.get_settings()
|
||||||
|
@ -704,20 +704,18 @@ class Settings:
|
||||||
uncalculated=uncalculated,
|
uncalculated=uncalculated,
|
||||||
transitive_raise=transitive_raise,
|
transitive_raise=transitive_raise,
|
||||||
)
|
)
|
||||||
return self._calc_raises_properties(option_bag.config_bag.properties,
|
return self._calc_raises_properties(option_bag,
|
||||||
option_bag.config_bag.permissives,
|
|
||||||
option_properties,
|
option_properties,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _calc_raises_properties(self,
|
def _calc_raises_properties(self,
|
||||||
context_properties,
|
option_bag,
|
||||||
context_permissives,
|
|
||||||
option_properties,
|
option_properties,
|
||||||
):
|
):
|
||||||
raises_properties = context_properties - SPECIAL_PROPERTIES
|
raises_properties = option_bag.config_bag.properties - SPECIAL_PROPERTIES
|
||||||
# remove global permissive properties
|
# remove global permissive properties
|
||||||
if raises_properties and 'permissive' in raises_properties:
|
if raises_properties and 'permissive' in raises_properties:
|
||||||
raises_properties -= context_permissives
|
raises_properties -= option_bag.config_bag.permissives
|
||||||
properties = option_properties & raises_properties
|
properties = option_properties & raises_properties
|
||||||
# at this point it should not remain any property for the option
|
# at this point it should not remain any property for the option
|
||||||
return properties
|
return properties
|
||||||
|
@ -743,8 +741,7 @@ class Settings:
|
||||||
transitive_raise=transitive_raise,
|
transitive_raise=transitive_raise,
|
||||||
))
|
))
|
||||||
calc_properties = []
|
calc_properties = []
|
||||||
for property_ in self._calc_raises_properties(option_bag.config_bag.properties,
|
for property_ in self._calc_raises_properties(option_bag,
|
||||||
option_bag.config_bag.permissives,
|
|
||||||
set(help_properties.keys()),
|
set(help_properties.keys()),
|
||||||
):
|
):
|
||||||
calc_properties.append(help_properties[property_])
|
calc_properties.append(help_properties[property_])
|
||||||
|
|
|
@ -152,12 +152,7 @@ class Values:
|
||||||
"""
|
"""
|
||||||
has_calculation = False
|
has_calculation = False
|
||||||
if isinstance(value, Calculation):
|
if isinstance(value, Calculation):
|
||||||
try:
|
|
||||||
value = value.execute(option_bag)
|
value = value.execute(option_bag)
|
||||||
except ConfigError as err:
|
|
||||||
msg = _(f'error when calculating "{option_bag.option.impl_get_display_name()}": '
|
|
||||||
f'{err} : {option_bag.path}')
|
|
||||||
raise ConfigError(msg) from err
|
|
||||||
has_calculation = True
|
has_calculation = True
|
||||||
elif isinstance(value, list):
|
elif isinstance(value, list):
|
||||||
# if value is a list, do subcalculation
|
# if value is a list, do subcalculation
|
||||||
|
@ -354,6 +349,7 @@ class Values:
|
||||||
for coption in option.get_children_recursively(None,
|
for coption in option.get_children_recursively(None,
|
||||||
None,
|
None,
|
||||||
option_bag.config_bag,
|
option_bag.config_bag,
|
||||||
|
option_suffixes=[],
|
||||||
):
|
):
|
||||||
if 'force_store_value' in coption.impl_getproperties():
|
if 'force_store_value' in coption.impl_getproperties():
|
||||||
force_store_options.append(coption)
|
force_store_options.append(coption)
|
||||||
|
|
Loading…
Reference in a new issue