add config_bag and convert some tests

This commit is contained in:
2017-12-19 23:11:45 +01:00
parent b5f785d62c
commit 538e6a792a
33 changed files with 2432 additions and 1319 deletions

View File

@ -118,6 +118,55 @@ debug = False
static_set = frozenset()
class ConfigBag(object):
__slots__ = ('default',
'config',
'option',
'ori_option',
'properties',
'validate',
'validate_properties',
'setting_properties',
'force_permissive',
'force_unrestraint',
'display_warnings',
'trusted_cached_properties',
'fromconsistency',
)
def __init__(self, config, **kwargs):
self.default = {'force_permissive': False,
'force_unrestraint': False,
'validate': True,
'validate_properties': True,
'display_warnings': True,
'trusted_cached_properties': True,
}
self.config = config
for key, value in kwargs.items():
if value != self.default.get(key):
setattr(self, key, value)
def __getattr__(self, key):
if key == 'setting_properties':
if self.force_unrestraint:
return None
self.setting_properties = self.config.cfgimpl_get_settings().get_context_properties()
return self.setting_properties
return self.default.get(key)
def copy(self, filters='all'):
kwargs = {}
for key in self.__slots__:
if filters == 'nooption' and (key.startswith('option') or \
key == 'properties'):
continue
if key != 'default':
value = getattr(self, key)
if value != self.default.get(key):
kwargs[key] = value
return ConfigBag(**kwargs)
# ____________________________________________________________
class _NameSpace(object):
"""convenient class that emulates a module
@ -284,25 +333,25 @@ class Settings(object):
return props
def getproperties(self,
opt,
path,
setting_properties,
index=None,
apply_requires=True):
index,
config_bag):
"""
"""
opt = config_bag.option
if opt.impl_is_symlinkoption():
opt = opt.impl_getopt()
path = opt.impl_getpath(self._getcontext())
is_cached = False
if apply_requires:
if 'cache' in setting_properties and 'expire' in setting_properties:
if config_bag.setting_properties is not None:
if 'cache' in config_bag.setting_properties and \
'expire' in config_bag.setting_properties:
ntime = int(time())
else:
ntime = None
if 'cache' in setting_properties and self._p_.hascache(path,
index):
if 'cache' in config_bag.setting_properties and self._p_.hascache(path,
index):
is_cached, props = self._p_.getcache(path,
ntime,
index)
@ -314,24 +363,22 @@ class Settings(object):
else:
props = meta.cfgimpl_get_settings().getproperties(opt,
path,
setting_properties,
index=index,
apply_requires=False)
if apply_requires:
requires = self.apply_requires(opt,
path,
setting_properties,
index,
False)
#FIXME devrait etre un frozenset!
if requires != set([]):
props = copy(props)
props |= requires
index,
config_bag)
requires = self.apply_requires(path,
index,
False,
config_bag)
#FIXME devrait etre un frozenset!
if requires != set([]):
props = copy(props)
props |= requires
props -= self.getpermissive(opt,
path)
if apply_requires and 'cache' in setting_properties:
if 'expire' in setting_properties:
if config_bag.setting_properties is not None and \
'cache' in config_bag.setting_properties:
if 'expire' in config_bag.setting_properties:
ntime = ntime + expires_time
self._p_.setcache(path,
props,
@ -355,11 +402,10 @@ class Settings(object):
return self._pp_.getpermissive(path)
def apply_requires(self,
opt,
path,
setting_properties,
index,
debug):
debug,
config_bag):
"""carries out the jit (just in time) requirements between options
a requirement is a tuple of this form that comes from the option's
@ -403,6 +449,7 @@ class Settings(object):
:param path: the option's path in the config
:type path: str
"""
opt = config_bag.option
current_requires = opt.impl_getrequires()
# filters the callbacks
@ -437,11 +484,12 @@ class Settings(object):
idx = index
else:
idx = None
sconfig_bag = config_bag.copy('nooption')
sconfig_bag.option = option
try:
value = context.getattr(reqpath,
setting_properties,
force_permissive=True,
index=idx)
idx,
sconfig_bag)
except PropertiesOptionError as err:
if not transitive:
if all_properties is None:
@ -474,7 +522,7 @@ class Settings(object):
if operator != 'and':
if debug:
if isinstance(orig_value, PropertiesOptionError):
for msg in orig_value._settings.apply_requires(**orig_value._datas).values():
for msg in orig_value.cfgimpl_get_settings().apply_requires(**orig_value._datas).values():
calc_properties.setdefault(action, []).extend(msg)
else:
if not inverse:
@ -500,18 +548,25 @@ class Settings(object):
#____________________________________________________________
# set methods
def set_context_properties(self, properties):
self.setproperties(None, None, properties)
def set_context_properties(self,
properties):
self.setproperties(None,
properties,
None)
def setproperties(self,
opt,
path,
properties):
properties,
config_bag):
"""save properties for specified path
(never save properties if same has option properties)
"""
if self._getcontext().cfgimpl_get_meta() is not None:
raise ConfigError(_('cannot change property with metaconfig'))
if config_bag is None:
opt = None
else:
opt = config_bag.option
if opt and opt.impl_is_symlinkoption():
raise TypeError(_("can't assign properties to the SymLinkOption \"{}\""
"").format(opt.impl_get_display_name()))
@ -586,12 +641,9 @@ class Settings(object):
# validate properties
def validate_properties(self,
opt,
path,
setting_properties,
self_properties=undefined,
index=None,
force_permissive=False):
index,
config_bag):
"""
validation upon the properties related to `opt`
@ -599,48 +651,45 @@ class Settings(object):
:param force_permissive: behaves as if the permissive property
was present
"""
# opt properties
if self_properties is undefined:
self_properties = self.getproperties(opt,
path,
setting_properties=setting_properties,
index=index)
opt = config_bag.option
# calc properties
properties = self_properties & setting_properties - set(['frozen'])
self_properties = config_bag.properties
if self_properties is None:
self_properties = self.getproperties(path,
index,
config_bag)
config_bag.properties = self_properties
properties = self_properties & config_bag.setting_properties - {'frozen', 'mandatory', 'empty'}
if not opt.impl_is_optiondescription():
#mandatory
if 'mandatory' in properties or 'empty' in properties:
value = self._getcontext().cfgimpl_get_values().get_cached_value(opt,
path,
setting_properties,
validate=True,
self_properties=self_properties,
index=index)
if not self.validate_mandatory(opt,
index,
value,
setting_properties,
properties):
properties -= set(['mandatory'])
else:
properties |= set(['mandatory'])
properties -= set(['empty'])
##mandatory
#if 'mandatory' in properties or 'empty' in properties:
# value = self._getcontext().cfgimpl_get_values().get_cached_value(path,
# index,
# config_bag)
# sconfig_bag = config_bag.copy()
# sconfig_bag.properties = properties
# if not self.validate_mandatory(index,
# value,
# sconfig_bag):
# properties -= set(['mandatory'])
# else:
# properties |= set(['mandatory'])
# properties -= set(['empty'])
opt_type = 'option'
else:
opt_type = 'optiondescription'
# remove permissive properties
if force_permissive is True and properties:
if config_bag.force_permissive is True and properties:
# remove global permissive if need
properties -= self.get_context_permissive()
# at this point an option should not remain in properties
if properties != frozenset():
datas = {'opt': opt,
'path': path,
'setting_properties': setting_properties,
datas = {'path': path,
'config_bag': config_bag,
'index': index,
'debug': True}
raise PropertiesOptionError(None,
@ -650,25 +699,34 @@ class Settings(object):
opt_type)
def validate_mandatory(self,
opt,
path,
index,
value,
setting_properties,
properties):
config_bag):
values = self._getcontext().cfgimpl_get_values()
return 'mandatory' in setting_properties and \
('mandatory' in properties and values.isempty(opt,
value,
index=index) or \
'empty' in properties and values.isempty(opt,
value,
force_allow_empty_list=True,
index=index))
opt = config_bag.option
if config_bag.setting_properties and 'mandatory' in config_bag.setting_properties and \
('mandatory' in config_bag.properties and values.isempty(opt,
value,
index=index) or \
'empty' in config_bag.properties and values.isempty(opt,
value,
force_allow_empty_list=True,
index=index)):
datas = {'path': path,
'config_bag': config_bag,
'index': index,
'debug': True}
raise PropertiesOptionError(None,
['mandatory'],
self,
datas,
'option')
def validate_frozen(self,
setting_properties,
self_properties):
return 'everything_frozen' in setting_properties or 'frozen' in self_properties
config_bag):
return 'everything_frozen' in config_bag.setting_properties or \
'frozen' in config_bag.properties
#____________________________________________________________
# read only/read write