add config_bag and convert some tests
This commit is contained in:
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user