add force_metaconfig_on_freeze special properties
This commit is contained in:
parent
c3f968dbde
commit
1bbcea60ab
8 changed files with 129 additions and 34 deletions
|
@ -972,3 +972,64 @@ def test_meta_properties_meta_set_value():
|
||||||
assert isinstance(ret[0], ValueError)
|
assert isinstance(ret[0], ValueError)
|
||||||
del ret[0]
|
del ret[0]
|
||||||
del ret
|
del ret
|
||||||
|
|
||||||
|
|
||||||
|
def test_metaconfig_force_metaconfig_on_freeze():
|
||||||
|
dummy1 = StrOption('dummy1', 'doc dummy', default='default')
|
||||||
|
dummy2 = StrOption('dummy2', 'doc dummy', default='default', properties=('force_default_on_freeze',))
|
||||||
|
group = OptionDescription('group', '', [dummy1, dummy2])
|
||||||
|
config = Config(group)
|
||||||
|
meta1 = MetaConfig([config], session_id='meta1')
|
||||||
|
meta1.owner.set(owners.meta1)
|
||||||
|
meta2 = MetaConfig([meta1], session_id='meta2')
|
||||||
|
meta2.owner.set(owners.meta2)
|
||||||
|
config.property.read_write()
|
||||||
|
|
||||||
|
config.option('dummy1').property.add('frozen')
|
||||||
|
config.option('dummy1').property.add('force_metaconfig_on_freeze')
|
||||||
|
config.option('dummy2').property.add('frozen')
|
||||||
|
#
|
||||||
|
assert config.option('dummy1').value.get() == 'default'
|
||||||
|
assert config.option('dummy1').owner.get() == 'default'
|
||||||
|
assert config.option('dummy2').value.get() == 'default'
|
||||||
|
assert config.option('dummy2').owner.get() == 'default'
|
||||||
|
#
|
||||||
|
meta2.option('dummy1').value.set('meta2')
|
||||||
|
meta2.option('dummy2').value.set('meta2')
|
||||||
|
#
|
||||||
|
assert config.option('dummy1').value.get() == 'meta2'
|
||||||
|
assert config.option('dummy1').owner.get() == 'meta2'
|
||||||
|
assert config.option('dummy2').value.get() == 'default'
|
||||||
|
assert config.option('dummy2').owner.get() == 'default'
|
||||||
|
#
|
||||||
|
config.option('dummy1').property.pop('frozen')
|
||||||
|
config.option('dummy2').property.pop('frozen')
|
||||||
|
config.option('dummy1').value.set('config')
|
||||||
|
config.option('dummy2').value.set('config')
|
||||||
|
config.option('dummy1').property.add('frozen')
|
||||||
|
config.option('dummy2').property.add('frozen')
|
||||||
|
#
|
||||||
|
assert config.option('dummy1').value.get() == 'meta2'
|
||||||
|
assert config.option('dummy1').owner.get() == 'meta2'
|
||||||
|
assert config.option('dummy2').value.get() == 'default'
|
||||||
|
assert config.option('dummy2').owner.get() == 'default'
|
||||||
|
#
|
||||||
|
meta1.option('dummy1').value.set('meta1')
|
||||||
|
meta1.option('dummy2').value.set('meta1')
|
||||||
|
#
|
||||||
|
assert config.option('dummy1').value.get() == 'meta1'
|
||||||
|
assert config.option('dummy1').owner.get() == 'meta1'
|
||||||
|
assert config.option('dummy2').value.get() == 'default'
|
||||||
|
assert config.option('dummy2').owner.get() == 'default'
|
||||||
|
#
|
||||||
|
meta1.option('dummy1').property.add('force_metaconfig_on_freeze')
|
||||||
|
assert config.option('dummy1').value.get() == 'meta2'
|
||||||
|
assert config.option('dummy1').owner.get() == 'meta2'
|
||||||
|
#
|
||||||
|
meta2.option('dummy1').property.add('force_metaconfig_on_freeze')
|
||||||
|
assert config.option('dummy1').value.get() == 'default'
|
||||||
|
assert config.option('dummy1').owner.get() == 'default'
|
||||||
|
#
|
||||||
|
meta1.option('dummy1').property.pop('force_metaconfig_on_freeze')
|
||||||
|
assert config.option('dummy1').value.get() == 'meta1'
|
||||||
|
assert config.option('dummy1').owner.get() == 'meta1'
|
||||||
|
|
|
@ -120,6 +120,14 @@ def test_force_default_on_freeze_leader():
|
||||||
raises(ConfigError, "Config(descr)")
|
raises(ConfigError, "Config(descr)")
|
||||||
|
|
||||||
|
|
||||||
|
def test_force_metaconfig_on_freeze_leader():
|
||||||
|
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze',))
|
||||||
|
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
||||||
|
descr = Leadership("dummy1", "", [dummy1, dummy2])
|
||||||
|
descr = OptionDescription("root", "", [descr])
|
||||||
|
raises(ConfigError, "Config(descr)")
|
||||||
|
|
||||||
|
|
||||||
def test_force_default_on_freeze_leader_frozen():
|
def test_force_default_on_freeze_leader_frozen():
|
||||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_default_on_freeze', 'frozen'))
|
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_default_on_freeze', 'frozen'))
|
||||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
||||||
|
@ -129,6 +137,15 @@ def test_force_default_on_freeze_leader_frozen():
|
||||||
raises(ConfigError, "api.option('dummy1.dummy1').property.pop('frozen')")
|
raises(ConfigError, "api.option('dummy1.dummy1').property.pop('frozen')")
|
||||||
|
|
||||||
|
|
||||||
|
def test_force_metaconfig_on_freeze_leader_frozen():
|
||||||
|
dummy1 = BoolOption('dummy1', 'Test int option', multi=True, properties=('force_metaconfig_on_freeze', 'frozen'))
|
||||||
|
dummy2 = BoolOption('dummy2', 'Test string option', multi=True)
|
||||||
|
descr = Leadership("dummy1", "", [dummy1, dummy2])
|
||||||
|
descr = OptionDescription("root", "", [descr])
|
||||||
|
api = Config(descr)
|
||||||
|
raises(ConfigError, "api.option('dummy1.dummy1').property.pop('frozen')")
|
||||||
|
|
||||||
|
|
||||||
def test_force_default_on_freeze_follower():
|
def test_force_default_on_freeze_follower():
|
||||||
dummy1 = BoolOption('dummy1', 'Test int option', multi=True)
|
dummy1 = BoolOption('dummy1', 'Test int option', multi=True)
|
||||||
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
|
dummy2 = BoolOption('dummy2', 'Test string option', multi=True, properties=('force_default_on_freeze',))
|
||||||
|
|
|
@ -185,6 +185,7 @@ def test_forbidden_permissive():
|
||||||
api = Config(descr)
|
api = Config(descr)
|
||||||
api.property.read_write()
|
api.property.read_write()
|
||||||
raises(ConfigError, "api.permissive.set(frozenset(['force_default_on_freeze']))")
|
raises(ConfigError, "api.permissive.set(frozenset(['force_default_on_freeze']))")
|
||||||
|
raises(ConfigError, "api.permissive.set(frozenset(['force_metaconfig_on_freeze']))")
|
||||||
|
|
||||||
|
|
||||||
def test_permissive_option():
|
def test_permissive_option():
|
||||||
|
|
|
@ -350,11 +350,11 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||||
raise ConfigError(_('cannot add this property: "{0}"').format(
|
raise ConfigError(_('cannot add this property: "{0}"').format(
|
||||||
' '.join(prop)))
|
' '.join(prop)))
|
||||||
props = self._settings.getproperties(self._option_bag,
|
props = self._settings.getproperties(self._option_bag,
|
||||||
apply_requires=False)
|
apply_requires=False)
|
||||||
self._settings.setproperties(self._option_bag.path,
|
self._settings.setproperties(self._option_bag.path,
|
||||||
props | {prop},
|
props | {prop},
|
||||||
self._option_bag,
|
self._option_bag,
|
||||||
self._option_bag.config_bag.context)
|
self._option_bag.config_bag.context)
|
||||||
|
|
||||||
def pop(self, prop):
|
def pop(self, prop):
|
||||||
"""Remove new property for an option"""
|
"""Remove new property for an option"""
|
||||||
|
|
|
@ -167,7 +167,7 @@ class Leadership(OptionDescription):
|
||||||
follower_path,
|
follower_path,
|
||||||
index,
|
index,
|
||||||
config_bag)
|
config_bag)
|
||||||
# do not check force_default_on_freeze
|
# do not check force_default_on_freeze or force_metaconfig_on_freeze
|
||||||
soption_bag.properties = set()
|
soption_bag.properties = set()
|
||||||
if not values.is_default_owner(soption_bag,
|
if not values.is_default_owner(soption_bag,
|
||||||
validate_meta=False) and followerlen > index:
|
validate_meta=False) and followerlen > index:
|
||||||
|
|
|
@ -90,12 +90,15 @@ class CacheOptionDescription(BaseOption):
|
||||||
'"force_store_value" property').format(
|
'"force_store_value" property').format(
|
||||||
option.impl_get_display_name()))
|
option.impl_get_display_name()))
|
||||||
force_store_values.append((subpath, option))
|
force_store_values.append((subpath, option))
|
||||||
if __debug__ and 'force_default_on_freeze' in properties and \
|
if __debug__ and ('force_default_on_freeze' in properties or \
|
||||||
|
'force_metaconfig_on_freeze' in properties) and \
|
||||||
'frozen' not in properties and \
|
'frozen' not in properties and \
|
||||||
option.impl_is_leader():
|
option.impl_is_leader():
|
||||||
raise ConfigError(_('a leader ({0}) cannot have '
|
raise ConfigError(_('a leader ({0}) cannot have '
|
||||||
'"force_default_on_freeze" property without "frozen"'
|
'"force_default_on_freeze" or '
|
||||||
'').format(subpath))
|
'"force_metaconfig_on_freeze" '
|
||||||
|
'property without "frozen"'
|
||||||
|
'').format(option.impl_get_display_name()))
|
||||||
for cons_id, func, all_cons_opts, params in option.get_consistencies():
|
for cons_id, func, all_cons_opts, params in option.get_consistencies():
|
||||||
option._valid_consistencies(all_cons_opts[1:], init=False)
|
option._valid_consistencies(all_cons_opts[1:], init=False)
|
||||||
if func not in ALLOWED_CONST_LIST and is_multi:
|
if func not in ALLOWED_CONST_LIST and is_multi:
|
||||||
|
|
|
@ -113,6 +113,7 @@ RW_REMOVE = frozenset(['permissive', 'everything_frozen', 'mandatory',
|
||||||
|
|
||||||
FORBIDDEN_SET_PROPERTIES = frozenset(['force_store_value'])
|
FORBIDDEN_SET_PROPERTIES = frozenset(['force_store_value'])
|
||||||
FORBIDDEN_SET_PERMISSIVES = frozenset(['force_default_on_freeze',
|
FORBIDDEN_SET_PERMISSIVES = frozenset(['force_default_on_freeze',
|
||||||
|
'force_metaconfig_on_freeze',
|
||||||
'force_store_value'])
|
'force_store_value'])
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,11 +165,14 @@ class OptionBag:
|
||||||
|
|
||||||
def __delattr__(self, key):
|
def __delattr__(self, key):
|
||||||
if key in ['properties', 'permissives']:
|
if key in ['properties', 'permissives']:
|
||||||
|
try:
|
||||||
|
super().__delattr__(key)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
return
|
return
|
||||||
raise KeyError('unknown key {} for ConfigBag'.format(key)) # pragma: no cover
|
raise KeyError('unknown key {} for ConfigBag'.format(key)) # pragma: no cover
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
kwargs = {}
|
|
||||||
option_bag = OptionBag()
|
option_bag = OptionBag()
|
||||||
for key in self.__slots__:
|
for key in self.__slots__:
|
||||||
if key == 'properties' and self.config_bag is undefined:
|
if key == 'properties' and self.config_bag is undefined:
|
||||||
|
@ -182,7 +186,7 @@ class ConfigBag:
|
||||||
'properties', # properties for current context
|
'properties', # properties for current context
|
||||||
'true_properties', # properties for current context
|
'true_properties', # properties for current context
|
||||||
'permissives', # permissives for current context
|
'permissives', # permissives for current context
|
||||||
)
|
)
|
||||||
def __init__(self, context, **kwargs):
|
def __init__(self, context, **kwargs):
|
||||||
self.context = context
|
self.context = context
|
||||||
for key, value in kwargs.items():
|
for key, value in kwargs.items():
|
||||||
|
@ -302,10 +306,10 @@ groups = GroupModule()
|
||||||
groups.default = groups.DefaultGroupType('default')
|
groups.default = groups.DefaultGroupType('default')
|
||||||
|
|
||||||
"""groups.leadership
|
"""groups.leadership
|
||||||
leadership group is a special optiondescription, all suboptions should be
|
leadership group is a special optiondescription, all suboptions should
|
||||||
multi option and all values should have same length, to find leader's
|
be multi option and all values should have same length, to find
|
||||||
option, the optiondescription's name should be same than de leader's
|
leader's option, the optiondescription's name should be same than de
|
||||||
option"""
|
leader's option"""
|
||||||
groups.leadership = groups.LeadershipGroupType('leadership')
|
groups.leadership = groups.LeadershipGroupType('leadership')
|
||||||
|
|
||||||
""" groups.family
|
""" groups.family
|
||||||
|
@ -607,10 +611,9 @@ class Settings(object):
|
||||||
def set_context_properties(self,
|
def set_context_properties(self,
|
||||||
properties,
|
properties,
|
||||||
context):
|
context):
|
||||||
self.setproperties(None,
|
self._p_.setproperties(None,
|
||||||
properties,
|
properties)
|
||||||
None,
|
context.cfgimpl_reset_cache(None)
|
||||||
context)
|
|
||||||
|
|
||||||
def setproperties(self,
|
def setproperties(self,
|
||||||
path,
|
path,
|
||||||
|
@ -621,33 +624,29 @@ class Settings(object):
|
||||||
(never save properties if same has option properties)
|
(never save properties if same has option properties)
|
||||||
"""
|
"""
|
||||||
# should have index !!!
|
# should have index !!!
|
||||||
if path is not None and option_bag.option.impl_getrequires() is not None:
|
opt = option_bag.option
|
||||||
|
if opt.impl_getrequires() is not None:
|
||||||
not_allowed_props = properties & \
|
not_allowed_props = properties & \
|
||||||
getattr(option_bag.option, '_calc_properties', static_set)
|
getattr(opt, '_calc_properties', static_set)
|
||||||
if not_allowed_props:
|
if not_allowed_props:
|
||||||
raise ValueError(_('cannot set property {} for option "{}" this property is '
|
raise ValueError(_('cannot set property {} for option "{}" this property is '
|
||||||
'calculated').format(display_list(list(not_allowed_props),
|
'calculated').format(display_list(list(not_allowed_props),
|
||||||
add_quote=True),
|
add_quote=True),
|
||||||
option_bag.option.impl_get_display_name()))
|
opt.impl_get_display_name()))
|
||||||
if option_bag is None:
|
if opt.impl_is_symlinkoption():
|
||||||
opt = None
|
|
||||||
else:
|
|
||||||
opt = option_bag.option
|
|
||||||
if opt and opt.impl_is_symlinkoption():
|
|
||||||
raise TypeError(_("can't assign property to the symlinkoption \"{}\""
|
raise TypeError(_("can't assign property to the symlinkoption \"{}\""
|
||||||
"").format(opt.impl_get_display_name()))
|
"").format(opt.impl_get_display_name()))
|
||||||
if 'force_default_on_freeze' in properties and \
|
if ('force_default_on_freeze' in properties or 'force_metaconfig_on_freeze' in properties) and \
|
||||||
'frozen' not in properties and \
|
'frozen' not in properties and \
|
||||||
opt.impl_is_leader():
|
opt.impl_is_leader():
|
||||||
raise ConfigError(_('a leader ({0}) cannot have '
|
raise ConfigError(_('a leader ({0}) cannot have '
|
||||||
'"force_default_on_freeze" property without "frozen"'
|
'"force_default_on_freeze" or "force_metaconfig_on_freeze" property without "frozen"'
|
||||||
'').format(opt.impl_get_display_name()))
|
'').format(opt.impl_get_display_name()))
|
||||||
self._p_.setproperties(path,
|
self._p_.setproperties(path,
|
||||||
properties)
|
properties)
|
||||||
# values too because of follower values could have a PropertiesOptionError has value
|
# values too because of follower values could have a PropertiesOptionError has value
|
||||||
context.cfgimpl_reset_cache(option_bag)
|
context.cfgimpl_reset_cache(option_bag)
|
||||||
if option_bag is not None:
|
del option_bag.properties
|
||||||
del option_bag.properties
|
|
||||||
|
|
||||||
def set_context_permissives(self,
|
def set_context_permissives(self,
|
||||||
permissives):
|
permissives):
|
||||||
|
|
|
@ -114,10 +114,12 @@ class Values(object):
|
||||||
owners.default,
|
owners.default,
|
||||||
index=_index,
|
index=_index,
|
||||||
with_value=True)
|
with_value=True)
|
||||||
if owner != owners.default and not ('frozen' in option_bag.properties and \
|
if owner != owners.default and \
|
||||||
'force_default_on_freeze' in option_bag.properties):
|
not ('frozen' in option_bag.properties and 'force_default_on_freeze' in option_bag.properties) and \
|
||||||
|
not ('frozen' in option_bag.properties and 'force_metaconfig_on_freeze' in option_bag.properties):
|
||||||
# if a value is store in storage, check if not frozen + force_default_on_freeze
|
# if a value is store in storage, check if not frozen + force_default_on_freeze
|
||||||
# if frozen + force_default_on_freeze => force default value
|
# if frozen + force_default_on_freeze => force default value
|
||||||
|
# if frozen + force_metaconfig_on_freeze => force value of metaconfig
|
||||||
return value
|
return value
|
||||||
return self.getdefaultvalue(option_bag)
|
return self.getdefaultvalue(option_bag)
|
||||||
|
|
||||||
|
@ -325,8 +327,17 @@ class Values(object):
|
||||||
doption_bag = option_bag.copy()
|
doption_bag = option_bag.copy()
|
||||||
config_bag = option_bag.config_bag.copy()
|
config_bag = option_bag.config_bag.copy()
|
||||||
config_bag.context = meta
|
config_bag.context = meta
|
||||||
config_bag.unrestraint()
|
|
||||||
doption_bag.config_bag = config_bag
|
doption_bag.config_bag = config_bag
|
||||||
|
if 'force_metaconfig_on_freeze' in option_bag.properties:
|
||||||
|
# remove force_metaconfig_on_freeze only if option in metaconfig
|
||||||
|
# hasn't force_metaconfig_on_freeze properties
|
||||||
|
ori_properties = doption_bag.properties
|
||||||
|
del doption_bag.properties
|
||||||
|
if 'force_metaconfig_on_freeze' not in doption_bag.properties:
|
||||||
|
doption_bag.properties = ori_properties - {'force_metaconfig_on_freeze'}
|
||||||
|
else:
|
||||||
|
doption_bag.properties = ori_properties
|
||||||
|
config_bag.unrestraint()
|
||||||
meta_option_bag = meta.cfgimpl_get_values().getowner(doption_bag,
|
meta_option_bag = meta.cfgimpl_get_values().getowner(doption_bag,
|
||||||
only_default=True)
|
only_default=True)
|
||||||
if meta_option_bag == owners.default:
|
if meta_option_bag == owners.default:
|
||||||
|
@ -378,11 +389,14 @@ class Values(object):
|
||||||
owner = self._p_.getowner(option_bag.path,
|
owner = self._p_.getowner(option_bag.path,
|
||||||
owners.default,
|
owners.default,
|
||||||
index=option_bag.index)
|
index=option_bag.index)
|
||||||
if owner is owners.default and validate_meta is not False:
|
if validate_meta is not False and (owner is owners.default or \
|
||||||
|
'force_metaconfig_on_freeze' in option_bag.properties):
|
||||||
moption_bag = self._get_meta(option_bag)
|
moption_bag = self._get_meta(option_bag)
|
||||||
if moption_bag:
|
if moption_bag:
|
||||||
owner = moption_bag.config_bag.context.cfgimpl_get_values().getowner(moption_bag,
|
owner = moption_bag.config_bag.context.cfgimpl_get_values().getowner(moption_bag,
|
||||||
only_default=only_default)
|
only_default=only_default)
|
||||||
|
elif 'force_metaconfig_on_freeze' in option_bag.properties:
|
||||||
|
return owners.default
|
||||||
return owner
|
return owner
|
||||||
|
|
||||||
def setowner(self,
|
def setowner(self,
|
||||||
|
|
Loading…
Reference in a new issue