feat: an option could be not validate

This commit is contained in:
egarette@silique.fr 2025-02-13 22:11:26 +01:00
parent 2f0e1fcb0c
commit adf94e6b15
13 changed files with 149 additions and 95 deletions

View file

@ -69,11 +69,11 @@ def test_cache_importation_property():
cfg = Config(od1) cfg = Config(od1)
cfg.option('u2').property.add('prop') cfg.option('u2').property.add('prop')
export = cfg.property.exportation() export = cfg.property.exportation()
assert cfg.option('u2').property.get() == {'prop'} assert cfg.option('u2').property.get() == {'validator', 'prop'}
cfg.option('u2').property.add('prop2') cfg.option('u2').property.add('prop2')
assert cfg.option('u2').property.get() == {'prop', 'prop2'} assert cfg.option('u2').property.get() == {'validator', 'prop', 'prop2'}
cfg.property.importation(export) cfg.property.importation(export)
assert cfg.option('u2').property.get() == {'prop'} assert cfg.option('u2').property.get() == {'validator', 'prop'}
cfg = Config(od1) cfg = Config(od1)
# assert not list_sessions() # assert not list_sessions()
@ -366,8 +366,8 @@ def test_cache_leader_and_followers():
cfg.value.get() cfg.value.get()
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value'] global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
val1_props = [] val1_props = []
val1_val1_props = ['empty', 'unique'] val1_val1_props = ['empty', 'unique', 'validator']
val1_val2_props = [] val1_val2_props = ['validator']
global_props = frozenset(global_props) global_props = frozenset(global_props)
val1_props = frozenset(val1_props) val1_props = frozenset(val1_props)
val1_val1_props = frozenset(val1_val1_props) val1_val1_props = frozenset(val1_val1_props)
@ -384,7 +384,7 @@ def test_cache_leader_and_followers():
# #
cfg.option('val1.val1').value.set([None]) cfg.option('val1.val1').value.set([None])
val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)} val_val2_props = {idx_val2: (val1_val2_props, None), None: (set(), None)}
compare(settings.get_cached(), {'val1.val1': {None: ({'empty', 'unique'}, None, True)}}) compare(settings.get_cached(), {'val1.val1': {None: ({'validator', 'empty', 'unique'}, None, True)}})
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}}) compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
cfg.value.get() cfg.value.get()
#has value #has value
@ -416,8 +416,8 @@ def test_cache_leader_callback():
cfg.value.get() cfg.value.get()
global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value'] global_props = ['cache', 'disabled', 'frozen', 'hidden', 'validator', 'warnings', 'force_store_value']
val1_props = [] val1_props = []
val1_val1_props = ['empty', 'unique'] val1_val1_props = ['empty', 'unique', 'validator']
val1_val2_props = [] val1_val2_props = ['validator']
global_props = frozenset(global_props) global_props = frozenset(global_props)
val1_props = frozenset(val1_props) val1_props = frozenset(val1_props)
val1_val1_props = frozenset(val1_val1_props) val1_val1_props = frozenset(val1_val1_props)
@ -429,7 +429,7 @@ def test_cache_leader_callback():
}) })
compare(values.get_cached(), {'val1.val1': {None: ([], None)}}) compare(values.get_cached(), {'val1.val1': {None: ([], None)}})
cfg.option('val1.val1').value.set([None]) cfg.option('val1.val1').value.set([None])
compare(settings.get_cached(), {'val1.val1': {None: ({'unique', 'empty'}, None, True)}}) compare(settings.get_cached(), {'val1.val1': {None: ({'unique', 'empty', 'validator'}, None, True)}})
compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}}) compare(values.get_cached(), {'val1.val1': {None: ([None], None, True)}})
cfg.value.get() cfg.value.get()
@ -451,24 +451,24 @@ def test_cache_requires():
settings = cfg._config_bag.context.properties_cache settings = cfg._config_bag.context.properties_cache
assert values.get_cached() == {} assert values.get_cached() == {}
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}, compare(settings.get_cached(), {'activate_service': {None: ({'validator'}, None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: ({"validator"}, None)}})
compare(values.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
cfg.value.get() cfg.value.get()
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}, compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: ({"validator"}, None)}})
compare(values.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
cfg.option('ip_address_service').value.set('1.1.1.1') cfg.option('ip_address_service').value.set('1.1.1.1')
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}}) compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)}})
compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}}) compare(values.get_cached(), {'activate_service': {None: (True, None)}, 'ip_address_service': {None: ('1.1.1.1', None, True)}})
cfg.value.get() cfg.value.get()
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}, compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: ({"validator"}, None)}})
compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)}, compare(values.get_cached(), {'ip_address_service': {None: ('1.1.1.1', None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
@ -477,8 +477,8 @@ def test_cache_requires():
compare(values.get_cached(), {'activate_service': {None: (False, None)}}) compare(values.get_cached(), {'activate_service': {None: (False, None)}})
cfg.value.get() cfg.value.get()
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}, compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
'ip_address_service': {None: (set(['disabled']), None)}}) 'ip_address_service': {None: ({'disabled', "validator"}, None)}})
compare(values.get_cached(), {'activate_service': {None: (False, None)}}) compare(values.get_cached(), {'activate_service': {None: (False, None)}})
# assert not list_sessions() # assert not list_sessions()
@ -499,19 +499,19 @@ def test_cache_global_properties():
settings = cfg._config_bag.context.properties_cache settings = cfg._config_bag.context.properties_cache
assert values.get_cached() == {} assert values.get_cached() == {}
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}, compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: ({"validator"}, None)}})
compare(values.get_cached(), {'ip_address_service': {None: (None, None)}, compare(values.get_cached(), {'ip_address_service': {None: (None, None)},
'activate_service': {None: (True, None)}}) 'activate_service': {None: (True, None)}})
cfg.property.remove('disabled') cfg.property.remove('disabled')
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}, compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: ({"validator"}, None)}})
cfg.property.add('test') cfg.property.add('test')
assert cfg.option('ip_address_service').value.get() == None assert cfg.option('ip_address_service').value.get() == None
compare(settings.get_cached(), {'activate_service': {None: (set([]), None)}, compare(settings.get_cached(), {'activate_service': {None: ({"validator"}, None)},
'ip_address_service': {None: (set([]), None)}}) 'ip_address_service': {None: ({"validator"}, None)}})
# assert not list_sessions() # assert not list_sessions()

View file

@ -423,7 +423,7 @@ def test_config_reset():
cfg.owner.set('test') cfg.owner.set('test')
assert cfg.owner.get() == 'test' assert cfg.owner.get() == 'test'
assert not cfg.option('gc.gc2.bool').value.get() assert not cfg.option('gc.gc2.bool').value.get()
assert not cfg.option('boolop').property.get() assert cfg.option('boolop').property.get() == frozenset(["validator"])
assert not cfg.option('boolop').permissive.get() assert not cfg.option('boolop').permissive.get()
assert not cfg.option('wantref').information.get('info', None) assert not cfg.option('wantref').information.get('info', None)
# #
@ -440,7 +440,7 @@ def test_config_reset():
cfg.config.reset() cfg.config.reset()
assert cfg.owner.get() == 'test' assert cfg.owner.get() == 'test'
assert not cfg.option('gc.gc2.bool').value.get() assert not cfg.option('gc.gc2.bool').value.get()
assert not cfg.option('boolop').property.get() assert cfg.option('boolop').property.get() == {"validator"}
assert not cfg.option('float').permissive.get() assert not cfg.option('float').permissive.get()
assert not cfg.option('wantref').information.get('info', None) assert not cfg.option('wantref').information.get('info', None)
# assert not list_sessions() # assert not list_sessions()

View file

@ -300,20 +300,20 @@ def test_prop_dyndescription():
od = OptionDescription('od', '', [dod]) od = OptionDescription('od', '', [dod])
od2 = OptionDescription('od', '', [od]) od2 = OptionDescription('od', '', [od])
cfg = Config(od2) cfg = Config(od2)
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test']) assert set(cfg.option('od.dodval1.st').property.get()) == {'test', "validator"}
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test']) assert set(cfg.option('od.dodval2.st').property.get()) == {'test', "validator"}
cfg.option('od.dodval2.st').property.add('test2') cfg.option('od.dodval2.st').property.add('test2')
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test']) assert set(cfg.option('od.dodval1.st').property.get()) == {'test', "validator"}
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test', 'test2']) assert set(cfg.option('od.dodval2.st').property.get()) == {'test', 'test2', "validator"}
# #
assert set(cfg.option('od.dodval1').property.get()) == set([]) assert set(cfg.option('od.dodval1').property.get()) == set()
assert set(cfg.option('od.dodval2').property.get()) == set([]) assert set(cfg.option('od.dodval2').property.get()) == set()
cfg.option('od.dodval1').property.add('test1') cfg.option('od.dodval1').property.add('test1')
assert set(cfg.option('od.dodval1').property.get()) == set(['test1']) assert set(cfg.option('od.dodval1').property.get()) == {'test1'}
assert set(cfg.option('od.dodval2').property.get()) == set([]) assert set(cfg.option('od.dodval2').property.get()) == set()
cfg.option('od.dodval1').property.remove('test1') cfg.option('od.dodval1').property.remove('test1')
assert set(cfg.option('od.dodval1').property.get()) == set([]) assert set(cfg.option('od.dodval1').property.get()) == set()
assert set(cfg.option('od.dodval2').property.get()) == set([]) assert set(cfg.option('od.dodval2').property.get()) == set()
# assert not list_sessions() # assert not list_sessions()
@ -616,14 +616,14 @@ def test_prop_dyndescription_context():
od = OptionDescription('od', '', [dod, val1]) od = OptionDescription('od', '', [dod, val1])
od2 = OptionDescription('od', '', [od]) od2 = OptionDescription('od', '', [od])
cfg = Config(od2) cfg = Config(od2)
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test']) assert set(cfg.option('od.dodval1.st').property.get()) == {"validator", 'test'}
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test']) assert set(cfg.option('od.dodval2.st').property.get()) == {"validator", 'test'}
cfg.option('od.dodval2.st').property.add('test2') cfg.option('od.dodval2.st').property.add('test2')
assert set(cfg.option('od.dodval1.st').property.get()) == set(['test']) assert set(cfg.option('od.dodval1.st').property.get()) == {"validator", 'test'}
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test', 'test2']) assert set(cfg.option('od.dodval2.st').property.get()) == {"validator", 'test', 'test2'}
cfg.option('od.dodval1.st').permissive.add('test') cfg.option('od.dodval1.st').permissive.add('test')
assert set(cfg.option('od.dodval1.st').property.get()) == set([]) assert set(cfg.option('od.dodval1.st').property.get()) == {"validator"}
assert set(cfg.option('od.dodval2.st').property.get()) == set(['test', 'test2']) assert set(cfg.option('od.dodval2.st').property.get()) == {"validator", 'test', 'test2'}
# assert not list_sessions() # assert not list_sessions()

View file

@ -796,7 +796,7 @@ def test_follower_unique():
cfg = Config(od1) cfg = Config(od1)
cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145", "192.168.230.146"]) cfg.option('ip_admin_eth0.ip_admin_eth0').value.set(["192.168.230.145", "192.168.230.146"])
# unique property is removed for a follower # unique property is removed for a follower
assert not cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).property.get() assert cfg.option('ip_admin_eth0.netmask_admin_eth0', 1).property.get() == {"validator"}
# assert not list_sessions() # assert not list_sessions()
@ -1093,3 +1093,15 @@ def test_leader_forbidden_properties_callback(config_type):
cfg = Config(od1) cfg = Config(od1)
with pytest.raises(LeadershipError): with pytest.raises(LeadershipError):
cfg.option('ip_admin_eth0.ip_admin_eth0').value.get() cfg.option('ip_admin_eth0.ip_admin_eth0').value.get()
def test_follower_value_not_list():
ip_admin_eth0 = IPOption('ip_admin_eth0', "ip réseau autorisé", multi=True, default=['1.1.1.1'])
netmask_admin_eth0 = NetmaskOption('netmask_admin_eth0', "masque du sous-réseau", default_multi='255.255.255.0', multi=True, properties=('force_store_value',))
interface0 = Leadership('interface0', '', [ip_admin_eth0, netmask_admin_eth0])
od1 = OptionDescription('od', '', [interface0])
od2 = OptionDescription('root', '', [od1])
cfg = Config(od2)
cfg.property.read_write()
with pytest.raises(ValueError):
cfg.option('od.interface0.ip_admin_eth0').value.set(None)

View file

@ -202,10 +202,10 @@ def test_property_get_unique_empty():
od1 = OptionDescription("options", "", [s, s2, s3, s4]) od1 = OptionDescription("options", "", [s, s2, s3, s4])
cfg = Config(od1) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
assert cfg.option('string').property.get() == {'empty', 'unique'} assert cfg.option('string').property.get() == {"validator", 'empty', 'unique'}
assert cfg.option('string2').property.get() == {'empty', 'notunique'} assert cfg.option('string2').property.get() == {"validator", 'empty', 'notunique'}
assert cfg.option('string3').property.get() == {'unique', 'notempty'} assert cfg.option('string3').property.get() == {"validator", 'unique', 'notempty'}
assert cfg.option('string4').property.get() == {'notunique', 'notempty'} assert cfg.option('string4').property.get() == {"validator", 'notunique', 'notempty'}
# assert not list_sessions() # assert not list_sessions()
@ -220,7 +220,7 @@ def test_property_only_raises():
od1 = OptionDescription("options", "", [s, intoption, stroption]) od1 = OptionDescription("options", "", [s, intoption, stroption])
cfg = Config(od1) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
assert cfg.option('str').property.get() == {'empty', 'unique'} assert cfg.option('str').property.get() == {'empty', 'unique', 'validator'}
assert cfg.option('str').property.get(only_raises=True) == set() assert cfg.option('str').property.get(only_raises=True) == set()
# assert not list_sessions() # assert not list_sessions()
@ -569,23 +569,23 @@ def test_access_by_get_whith_hide():
def test_append_properties(): def test_append_properties():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)
assert cfg.option('gc.dummy').property.get() == set() assert cfg.option('gc.dummy').property.get() == {"validator"}
cfg.option('gc.dummy').property.add('test') cfg.option('gc.dummy').property.add('test')
assert cfg.option('gc.dummy').property.get() == {'test'} assert cfg.option('gc.dummy').property.get() == {'test', "validator"}
with pytest.raises(ConfigError): with pytest.raises(ConfigError):
cfg.option('gc.dummy').property.add('force_store_value') cfg.option('gc.dummy').property.add('force_store_value')
assert cfg.option('gc.dummy').property.get() == {'test'} assert cfg.option('gc.dummy').property.get() == {'test', "validator"}
# assert not list_sessions() # assert not list_sessions()
def test_reset_properties(): def test_reset_properties():
od1 = make_description() od1 = make_description()
cfg = Config(od1) cfg = Config(od1)
assert cfg.option('gc.dummy').property.get() == set() assert cfg.option('gc.dummy').property.get() == {"validator"}
cfg.option('gc.dummy').property.add('frozen') cfg.option('gc.dummy').property.add('frozen')
assert cfg.option('gc.dummy').property.get() == {'frozen'} assert cfg.option('gc.dummy').property.get() == {"validator", 'frozen'}
cfg.option('gc.dummy').property.reset() cfg.option('gc.dummy').property.reset()
assert cfg.option('gc.dummy').property.get() == set() assert cfg.option('gc.dummy').property.get() == {"validator"}
# assert not list_sessions() # assert not list_sessions()
@ -594,7 +594,7 @@ def test_properties_cached():
od1 = OptionDescription("opt", "", [OptionDescription("sub", "", [b1])]) od1 = OptionDescription("opt", "", [OptionDescription("sub", "", [b1])])
cfg = Config(od1) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
assert cfg.option('sub.b1').property.get() == {'test'} assert cfg.option('sub.b1').property.get() == {'test', "validator"}
# assert not list_sessions() # assert not list_sessions()
@ -603,9 +603,9 @@ def test_append_properties_force_store_value():
gcgroup = OptionDescription('gc', '', [gcdummy]) gcgroup = OptionDescription('gc', '', [gcdummy])
od1 = OptionDescription('tiramisu', '', [gcgroup]) od1 = OptionDescription('tiramisu', '', [gcgroup])
cfg = Config(od1) cfg = Config(od1)
assert cfg.option('gc.dummy').property.get() == {'force_store_value'} assert cfg.option('gc.dummy').property.get() == {'force_store_value', "validator"}
cfg.option('gc.dummy').property.add('test') cfg.option('gc.dummy').property.add('test')
assert cfg.option('gc.dummy').property.get() == {'force_store_value', 'test'} assert cfg.option('gc.dummy').property.get() == {'force_store_value', 'test', "validator"}
# assert not list_sessions() # assert not list_sessions()

View file

@ -121,6 +121,34 @@ def test_validator(config_type):
# assert not list_sessions() # assert not list_sessions()
def test_validator_no_validation(config_type):
opt1 = StrOption('opt1', '', validators=[Calculation(return_true, Params(ParamSelfOption()))], default='val', properties=frozenset(['novalidator']))
opt2 = StrOption('opt2', '', validators=[Calculation(return_false, Params(ParamSelfOption()))], properties=frozenset(['novalidator']))
od1 = OptionDescription('root', '', [opt1, opt2])
cfg_ori = Config(od1)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('opt1').value.get() == 'val'
assert cfg.option('opt2').value.valid() is True
cfg.option('opt2').value.set('val')
def test_validator_no_validation2(config_type):
opt1 = StrOption('opt1', '', properties=frozenset(['novalidator']))
od1 = OptionDescription('root', '', [opt1])
cfg_ori = Config(od1)
cfg = get_config(cfg_ori, config_type)
cfg.option('opt1').value.set(1)
assert cfg.option('opt1').value.get() == 1
def test_validator_no_validation3(config_type):
opt1 = StrOption('opt1', '', 1, properties=frozenset(['novalidator']))
od1 = OptionDescription('root', '', [opt1])
cfg_ori = Config(od1)
cfg = get_config(cfg_ori, config_type)
assert cfg.option('opt1').value.get() == 1
def test_validator_not_valid(config_type): def test_validator_not_valid(config_type):
with pytest.raises(ValueError): with pytest.raises(ValueError):
StrOption('not_a_list', '', validators=Calculation(return_true, Params(ParamSelfOption())), default='val') StrOption('not_a_list', '', validators=Calculation(return_true, Params(ParamSelfOption())), default='val')

View file

@ -426,9 +426,9 @@ def test_requires_transitive_unrestraint(config_type):
# #
if config_type == 'tiramisu-api': if config_type == 'tiramisu-api':
cfg.send() cfg.send()
assert cfg_ori.option('activate_service_web').property.get() == {'disabled'} assert cfg_ori.option('activate_service_web').property.get() == {'disabled', "validator"}
# FIXME assert cfg_ori.unrestraint.option('ip_address_service_web').property.get() == {'disabled'} # FIXME assert cfg_ori.unrestraint.option('ip_address_service_web').property.get() == {'disabled'}
assert cfg_ori.option('ip_address_service_web').property.get() == {'disabled'} assert cfg_ori.option('ip_address_service_web').property.get() == {'disabled', "validator"}
# assert not list_sessions() # assert not list_sessions()

View file

@ -159,7 +159,7 @@ def test_symlink_getproperties():
od1 = OptionDescription('opt', '', [boolopt, linkopt]) od1 = OptionDescription('opt', '', [boolopt, linkopt])
cfg = Config(od1) cfg = Config(od1)
cfg.property.read_write() cfg.property.read_write()
assert boolopt.impl_getproperties() == linkopt.impl_getproperties() == {'test'} assert boolopt.impl_getproperties() == linkopt.impl_getproperties() == {'test', "validator"}
# assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == False # assert boolopt.impl_has_callback() == linkopt.impl_has_callback() == False
# assert not list_sessions() # assert not list_sessions()

View file

@ -804,6 +804,7 @@ class TiramisuOptionValue(CommonTiramisuOption, _TiramisuODGet):
option = self._subconfig.option option = self._subconfig.option
if ( if (
not isinstance(value, Calculation) not isinstance(value, Calculation)
and isinstance(value, list)
and option.impl_is_leader() and option.impl_is_leader()
and len(value) < self._subconfig.parent.get_length_leadership() and len(value) < self._subconfig.parent.get_length_leadership()
): ):

View file

@ -88,6 +88,8 @@ class Base:
assert isinstance(properties, frozenset), _( assert isinstance(properties, frozenset), _(
"invalid properties type {0} for {1}," " must be a frozenset" "invalid properties type {0} for {1}," " must be a frozenset"
).format(type(properties), name) ).format(type(properties), name)
if not self.impl_is_optiondescription() and "novalidator" not in properties:
properties = properties | {"validator"}
_setattr = object.__setattr__ _setattr = object.__setattr__
_setattr(self, "_name", name) _setattr(self, "_name", name)
_setattr(self, "_informations", {"doc": doc}) _setattr(self, "_informations", {"doc": doc})

View file

@ -178,16 +178,19 @@ class Option(BaseOption):
# undefined, # undefined,
# properties=None, # properties=None,
# ) # )
self_properties = getattr(self, "_properties", {})
self.impl_validate( self.impl_validate(
None, None,
default, default,
loaded=True, loaded=True,
self_properties=self_properties,
) )
self.impl_validate( self.impl_validate(
None, None,
default, default,
check_error=False, check_error=False,
loaded=True, loaded=True,
self_properties=self_properties,
) )
self.value_dependencies(default) self.value_dependencies(default)
if (is_multi and default != []) or (not is_multi and default is not None): if (is_multi and default != []) or (not is_multi and default is not None):
@ -256,16 +259,19 @@ class Option(BaseOption):
*, *,
check_error: bool = True, check_error: bool = True,
loaded: bool = False, loaded: bool = False,
self_properties: frozenset=frozenset(),
) -> bool: ) -> bool:
"""Return True if value is really valid """Return True if value is really valid
If not validate or invalid return it returns False If not validate or invalid return it returns False
""" """
if ( if check_error:
check_error if subconfig:
and subconfig config_properties = subconfig.config_bag.properties
and not "validator" in subconfig.config_bag.properties self_properties = subconfig.properties
): else:
return False config_properties = {'validator'}
if "validator" not in config_properties or "validator" not in self_properties:
return False
if subconfig: if subconfig:
force_index = subconfig.index force_index = subconfig.index
else: else:

View file

@ -94,7 +94,7 @@ EXPIRATION_TIME = 5
# demoting_error_warning # demoting_error_warning
# all value errors are convert to warning (ValueErrorWarning) # all value errors are convert to warning (ValueErrorWarning)
DEFAULT_PROPERTIES = frozenset(["cache", "validator", "warnings"]) DEFAULT_PROPERTIES = frozenset(["cache", "validator", "warnings"])
SPECIAL_PROPERTIES = {"frozen", "mandatory", "empty", "force_store_value"} SPECIAL_PROPERTIES = {"frozen", "mandatory", "empty", "force_store_value", "validator"}
# Config can be in two defaut mode: # Config can be in two defaut mode:
# #
@ -149,6 +149,7 @@ FORBIDDEN_SET_PERMISSIVES = frozenset(
"force_default_on_freeze", "force_default_on_freeze",
"force_metaconfig_on_freeze", "force_metaconfig_on_freeze",
"force_store_value", "force_store_value",
"validator",
] ]
) )
ALLOWED_LEADER_PROPERTIES = { ALLOWED_LEADER_PROPERTIES = {
@ -158,6 +159,8 @@ ALLOWED_LEADER_PROPERTIES = {
"unique", "unique",
"force_store_value", "force_store_value",
"mandatory", "mandatory",
"validator",
"novalidator",
"force_default_on_freeze", "force_default_on_freeze",
"force_metaconfig_on_freeze", "force_metaconfig_on_freeze",
"frozen", "frozen",

View file

@ -265,9 +265,10 @@ class Values:
) -> None: ) -> None:
"""set value to option""" """set value to option"""
owner = self.get_context_owner() owner = self.get_context_owner()
self_properties = subconfig.properties
setting_properties = subconfig.config_bag.properties setting_properties = subconfig.config_bag.properties
ori_value = value ori_value = value
if "validator" in setting_properties: if "validator" in setting_properties and "validator" in self_properties:
value, has_calculation = self.setvalue_validation( value, has_calculation = self.setvalue_validation(
subconfig, subconfig,
value, value,
@ -294,8 +295,9 @@ class Values:
owners.forced, owners.forced,
) )
validator = ( validator = (
"validator" in setting_properties "validator" in setting_properties and
and "demoting_error_warning" not in setting_properties "validator" in self_properties and
"demoting_error_warning" not in setting_properties
) )
if validator and not has_calculation: if validator and not has_calculation:
cache = subconfig.config_bag.context.get_values_cache() cache = subconfig.config_bag.context.get_values_cache()
@ -304,7 +306,7 @@ class Values:
value, value,
validated=validator, validated=validator,
) )
elif "validator" in setting_properties and has_calculation: elif "validator" in setting_properties and "validator" in self_properties and has_calculation:
cache = subconfig.config_bag.context.get_values_cache() cache = subconfig.config_bag.context.get_values_cache()
cache.delcache(subconfig.path) cache.delcache(subconfig.path)
@ -587,35 +589,34 @@ class Values:
"""reset value for an option""" """reset value for an option"""
config_bag = subconfig.config_bag config_bag = subconfig.config_bag
hasvalue = self.hasvalue(subconfig.path) hasvalue = self.hasvalue(subconfig.path)
self_properties = subconfig.properties
context = config_bag.context context = config_bag.context
setting_properties = config_bag.properties setting_properties = config_bag.properties
if validate: if validate and hasvalue and "validator" in setting_properties and "validator" in self_properties:
if hasvalue and "validator" in setting_properties: fake_context = context.gen_fake_context()
fake_context = context.gen_fake_context() fake_config_bag = config_bag.copy()
fake_config_bag = config_bag.copy() fake_config_bag.remove_validation()
fake_config_bag.remove_validation() fake_config_bag.context = fake_context
fake_config_bag.context = fake_context fake_subconfig = fake_context.get_sub_config(
fake_subconfig = fake_context.get_sub_config( fake_config_bag,
fake_config_bag, subconfig.path,
subconfig.path, subconfig.index,
subconfig.index, validate_properties=False,
validate_properties=False, )
) fake_values = fake_context.get_values()
fake_values = fake_context.get_values() fake_values.reset(fake_subconfig)
fake_values.reset(fake_subconfig) fake_subconfig.config_bag.properties = setting_properties
fake_subconfig.config_bag.properties = setting_properties value = fake_values.get_default_value(fake_subconfig)
value = fake_values.get_default_value(fake_subconfig) fake_values.setvalue_validation(
fake_values.setvalue_validation( fake_subconfig,
fake_subconfig, value,
value, )
)
# if hasvalue:
opt = subconfig.option opt = subconfig.option
if opt.impl_is_leader(): if opt.impl_is_leader():
opt.impl_get_leadership().reset(subconfig.parent) opt.impl_get_leadership().reset(subconfig.parent)
if ( if (
"force_store_value" in setting_properties "force_store_value" in setting_properties
and "force_store_value" in subconfig.properties and "force_store_value" in self_properties
): ):
value = self.get_default_value(subconfig) value = self.get_default_value(subconfig)
@ -662,10 +663,11 @@ class Values:
index=subconfig.index, index=subconfig.index,
): ):
return return
self_properties = subconfig.properties
config_bag = subconfig.config_bag config_bag = subconfig.config_bag
context = config_bag.context context = config_bag.context
setting_properties = config_bag.properties setting_properties = config_bag.properties
if "validator" in setting_properties: if "validator" in setting_properties and "validator" in self_properties:
fake_context = context.gen_fake_context() fake_context = context.gen_fake_context()
fake_config_bag = config_bag.copy() fake_config_bag = config_bag.copy()
fake_config_bag.remove_validation() fake_config_bag.remove_validation()
@ -686,7 +688,7 @@ class Values:
) )
if ( if (
"force_store_value" in setting_properties "force_store_value" in setting_properties
and "force_store_value" in subconfig.properties and "force_store_value" in self_properties
): ):
value = self.get_default_value( value = self.get_default_value(
subconfig, subconfig,