api: permissive => forcepermissive
api: add permissive object test api: permissive config: unwrap_from_path check properties for option, not only optiondescription option: _RegexpOption => RegexpOption
This commit is contained in:
@ -254,6 +254,32 @@ class TiramisuAPIProperty(CommonTiramisu):
|
||||
self.settings.reset(_path=path)
|
||||
|
||||
|
||||
class TiramisuAPIPermissive(CommonTiramisu):
|
||||
"""manager option's property"""
|
||||
|
||||
def __init__(self, config, force_permissive, force_unrestraint):
|
||||
super(TiramisuAPIPermissive, self).__init__(config, force_permissive, force_unrestraint)
|
||||
self.config = config
|
||||
self.force_permissive = force_permissive
|
||||
self.force_unrestraint = force_unrestraint
|
||||
if config:
|
||||
self.settings = config.cfgimpl_get_settings()
|
||||
|
||||
def get(self, path):
|
||||
"""get permissive value for a specified path"""
|
||||
setting_properties = self.settings.getproperties(None, None, obj=False)
|
||||
return self.settings.getpermissive(setting_properties, path)
|
||||
|
||||
def set(self, path, permissive):
|
||||
self.settings.setpermissive(permissive, opt=None, path=path)
|
||||
|
||||
#def reset(self, path):
|
||||
# """reset all personalised properties
|
||||
# """
|
||||
# self._get_obj_by_path(path)
|
||||
# self.settings.reset(_path=path)
|
||||
|
||||
|
||||
class TiramisuAPIValue(CommonTiramisu):
|
||||
"""manager option's value"""
|
||||
|
||||
@ -348,7 +374,7 @@ class TiramisuAPI(object):
|
||||
return self.registers[subfunc](self.config,
|
||||
self.force_permissive,
|
||||
self.force_unrestraint)
|
||||
elif subfunc == 'permissive':
|
||||
elif subfunc == 'forcepermissive':
|
||||
return TiramisuAPI(self.config, force_permissive=True, force_unrestraint=self.force_unrestraint)
|
||||
elif subfunc == 'unrestraint':
|
||||
return TiramisuAPI(self.config, force_permissive=self.force_permissive, force_unrestraint=True)
|
||||
@ -358,7 +384,7 @@ class TiramisuAPI(object):
|
||||
raise APIError(_('please specify a valid sub function'))
|
||||
|
||||
def _help(self):
|
||||
txt = ['[permissive]']
|
||||
txt = ['[forcepermissive]']
|
||||
for module_name, module in self.registers.items():
|
||||
module_doc = getdoc(module)
|
||||
txt.append(self.tmpl_help.format(self.icon, module_name, module_doc))
|
||||
|
@ -22,7 +22,7 @@
|
||||
import weakref
|
||||
import sys
|
||||
from time import time
|
||||
from itertools import chain
|
||||
from copy import copy
|
||||
|
||||
|
||||
from .error import PropertiesOptionError, ConfigError, ConflictError
|
||||
@ -76,69 +76,33 @@ class SubConfig(object):
|
||||
only=('values', 'properties', 'permissives', 'settings'),
|
||||
opt=None,
|
||||
path=None,
|
||||
orig_opts=None):
|
||||
resetted_opts=None):
|
||||
"""reset all settings in cache
|
||||
|
||||
:param only_expired: if True reset only expired cached values
|
||||
:type only_expired: boolean
|
||||
"""
|
||||
def reset_one_option_cache(opt, path):
|
||||
if opt.__class__.__name__ == 'DynOptionDescription':
|
||||
# this option is a DynOptionDescription
|
||||
descr = context.cfgimpl_get_description()
|
||||
spath = path.split('.')
|
||||
subpath = '.'.join(spath[:-1])
|
||||
dynopt = getattr(descr, subpath)._getattr(spath[-1], context=context,
|
||||
dyn=False)
|
||||
for suffix in dynopt._impl_get_suffixes(context):
|
||||
path = subpath + '.' + spath[-1] + suffix
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only or 'properties' in only:
|
||||
settings._p_.delcache(path)
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._pp_.delcache(path)
|
||||
elif not isinstance(opt, DynSymLinkOption) and opt._is_subdyn():
|
||||
# this option is an instance of DynOptionDescription
|
||||
descr = context.cfgimpl_get_description()
|
||||
spath = path.split('.')
|
||||
try:
|
||||
subpath = '.'.join(spath[:-2])
|
||||
dynsubopt = getattr(descr, subpath)
|
||||
spath1 = spath[-2]
|
||||
spath2 = spath[-1]
|
||||
spath3 = None
|
||||
except AttributeError:
|
||||
if len(spath) == 2:
|
||||
subpath = '.'.join(spath)
|
||||
spath1 = spath[-2]
|
||||
spath2 = spath[-1]
|
||||
spath3 = None
|
||||
dynsubopt = descr
|
||||
else:
|
||||
subpath = '.'.join(spath[:-3])
|
||||
spath1 = spath[-3]
|
||||
spath2 = spath[-2]
|
||||
spath3 = spath[-1]
|
||||
dynsubopt = getattr(descr, subpath)
|
||||
dynopt = dynsubopt._getattr(spath1, context=context, dyn=False)
|
||||
for suffix in dynopt._impl_get_suffixes(context):
|
||||
path = subpath + '.' + spath1 + suffix + '.' + spath2 + suffix
|
||||
if spath3:
|
||||
path += '.' + spath3 + suffix
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only or 'properties' in only:
|
||||
settings._p_.delcache(path)
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._pp_.delcache(path)
|
||||
def reset_one_option_cache(opt, resetted_opts):
|
||||
if 'values' in only:
|
||||
tresetted_opts = copy(resetted_opts)
|
||||
opt.reset_cache(opt, values, 'values', tresetted_opts)
|
||||
|
||||
if 'settings' in only:
|
||||
tresetted_opts = copy(resetted_opts)
|
||||
opt.reset_cache(opt, settings, 'settings', tresetted_opts)
|
||||
else:
|
||||
if 'values' in only:
|
||||
values._p_.delcache(path)
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._p_.delcache(path)
|
||||
if 'settings' in only or 'permissives' in only:
|
||||
settings._pp_.delcache(path)
|
||||
if 'properties' in only:
|
||||
tresetted_opts = copy(resetted_opts)
|
||||
opt.reset_cache(opt, settings, 'properties', tresetted_opts)
|
||||
if 'permissives' in only:
|
||||
tresetted_opts = copy(resetted_opts)
|
||||
opt.reset_cache(opt, settings, 'permissives', tresetted_opts)
|
||||
resetted_opts |= tresetted_opts
|
||||
for option in opt._get_dependencies(self):
|
||||
if option in resetted_opts:
|
||||
continue
|
||||
reset_one_option_cache(option, resetted_opts)
|
||||
|
||||
|
||||
def reset_expired_cache():
|
||||
# reset cache for expired cache value ony
|
||||
@ -156,9 +120,14 @@ class SubConfig(object):
|
||||
if 'settings' in only:
|
||||
settings._p_.reset_all_cache()
|
||||
settings._pp_.reset_all_cache()
|
||||
else:
|
||||
if 'properties' in only:
|
||||
settings._p_.reset_all_cache()
|
||||
if 'permissives' in only:
|
||||
settings._pp_.reset_all_cache()
|
||||
|
||||
if orig_opts is None:
|
||||
orig_opts = set()
|
||||
if resetted_opts is None:
|
||||
resetted_opts = set()
|
||||
|
||||
context = self._cfgimpl_get_context()
|
||||
if 'values' in only:
|
||||
@ -167,26 +136,8 @@ class SubConfig(object):
|
||||
settings = context.cfgimpl_get_settings()
|
||||
|
||||
if not None in (opt, path):
|
||||
reset_one_option_cache(opt, path)
|
||||
|
||||
# remove cache for option which has dependencies with this option
|
||||
#if not isinstance(opt, OptionDescription) and not isinstance(opt, SynDynOptionDescription) and \
|
||||
# opt.impl_is_master_slaves('slave'):
|
||||
# slaves = opt.impl_get_master_slaves().getslaves(opt)
|
||||
#else:
|
||||
slaves = []
|
||||
for option in chain(opt._get_dependencies(self), slaves):
|
||||
if option in orig_opts:
|
||||
continue
|
||||
if 'values' in only:
|
||||
option.reset_cache(opt, values, 'values', orig_opts)
|
||||
if 'settings' in only:
|
||||
option.reset_cache(opt, settings, 'settings', orig_opts)
|
||||
else:
|
||||
if 'properties' in only:
|
||||
option.reset_cache(opt, settings, 'properties', orig_opts)
|
||||
if 'permissives' in only:
|
||||
option.reset_cache(opt, settings, 'permissives', orig_opts)
|
||||
if opt not in resetted_opts:
|
||||
reset_one_option_cache(opt, resetted_opts)
|
||||
|
||||
elif only_expired:
|
||||
reset_expired_cache()
|
||||
@ -445,6 +396,8 @@ class SubConfig(object):
|
||||
return props
|
||||
else:
|
||||
raise props
|
||||
if returns_option is True:
|
||||
return option
|
||||
return SubConfig(option, self._impl_context, subpath)
|
||||
else:
|
||||
if validate:
|
||||
@ -737,23 +690,28 @@ class _CommonConfig(SubConfig):
|
||||
force_permissive=force_permissive)
|
||||
|
||||
def unwrap_from_path(self, path, force_permissive=False, index=None,
|
||||
validate_properties=True, validate=True):
|
||||
validate_properties=True, validate=True,
|
||||
_setting_properties=undefined):
|
||||
"""convenience method to extract and Option() object from the Config()
|
||||
and it is **fast**: finds the option directly in the appropriate
|
||||
namespace
|
||||
|
||||
:returns: Option()
|
||||
"""
|
||||
context = self._cfgimpl_get_context()
|
||||
if _setting_properties is undefined:
|
||||
context = self._cfgimpl_get_context()
|
||||
_setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=True)
|
||||
if '.' in path:
|
||||
self, path = self.cfgimpl_get_home_by_path(path,
|
||||
validate_properties=validate_properties,
|
||||
force_permissive=force_permissive)
|
||||
force_permissive=force_permissive,
|
||||
_setting_properties=_setting_properties)
|
||||
return self.getattr(path,
|
||||
validate_properties=validate_properties,
|
||||
validate=validate,
|
||||
force_permissive=force_permissive,
|
||||
index=index,
|
||||
_setting_properties=_setting_properties,
|
||||
returns_option=True)
|
||||
|
||||
def cfgimpl_get_path(self, dyn=True):
|
||||
@ -889,13 +847,19 @@ class GroupConfig(_CommonConfig):
|
||||
only=('values', 'settings'),
|
||||
opt=None,
|
||||
path=None,
|
||||
orig_opts=set()):
|
||||
resetted_opts=set()):
|
||||
if isinstance(self, MetaConfig):
|
||||
super(GroupConfig, self).cfgimpl_reset_cache(only_expired=only_expired, only=only,
|
||||
opt=opt, path=path, orig_opts=orig_opts)
|
||||
super(GroupConfig, self).cfgimpl_reset_cache(only_expired=only_expired,
|
||||
only=only,
|
||||
opt=opt,
|
||||
path=path,
|
||||
resetted_opts=copy(resetted_opts))
|
||||
for child in self._impl_children:
|
||||
child.cfgimpl_reset_cache(only_expired=only_expired, only=only, opt=opt, path=path,
|
||||
orig_opts=orig_opts)
|
||||
child.cfgimpl_reset_cache(only_expired=only_expired,
|
||||
only=only,
|
||||
opt=opt,
|
||||
path=path,
|
||||
resetted_opts=copy(resetted_opts))
|
||||
|
||||
def set_value(self, path, value, _commit=True):
|
||||
"""Setattr not in current GroupConfig, but in each children
|
||||
@ -964,7 +928,8 @@ class GroupConfig(_CommonConfig):
|
||||
|
||||
def getattr(self, name, force_permissive=False, validate=True,
|
||||
_setting_properties=undefined, _self_properties=undefined, index=None,
|
||||
returns_raise=False):
|
||||
returns_raise=False, returns_option=False,
|
||||
validate_properties=True):
|
||||
for child in self._impl_children:
|
||||
if name == child._impl_name:
|
||||
return child
|
||||
@ -973,7 +938,9 @@ class GroupConfig(_CommonConfig):
|
||||
_self_properties=_self_properties,
|
||||
index=index,
|
||||
_setting_properties=_setting_properties,
|
||||
returns_raise=returns_raise)
|
||||
returns_raise=returns_raise,
|
||||
returns_option=False,
|
||||
validate_properties=validate_properties)
|
||||
|
||||
|
||||
class MetaConfig(GroupConfig):
|
||||
|
@ -404,15 +404,16 @@ class BaseOption(Base):
|
||||
name = name.encode('utf8')
|
||||
return name
|
||||
|
||||
def reset_cache(self, opt, obj, type_, orig_opts):
|
||||
context = obj._getcontext()
|
||||
path = self.impl_getpath(context)
|
||||
obj._p_.delcache(path)
|
||||
orig_opts.add(opt)
|
||||
context.cfgimpl_reset_cache(only=(type_,),
|
||||
opt=self,
|
||||
path=path,
|
||||
orig_opts=orig_opts)
|
||||
def reset_cache(self, opt, obj, type_, resetted_opts):
|
||||
if opt in resetted_opts:
|
||||
return
|
||||
if not type_ == 'values' or not opt.impl_is_optiondescription():
|
||||
path = opt.impl_getpath(obj._getcontext())
|
||||
if type_ != 'permissives':
|
||||
obj._p_.delcache(path)
|
||||
if type_ in ['settings', 'permissives']:
|
||||
obj._pp_.delcache(path)
|
||||
resetted_opts.add(opt)
|
||||
|
||||
def _is_symlinkoption(self):
|
||||
return False
|
||||
|
@ -21,10 +21,10 @@
|
||||
import re
|
||||
|
||||
from ..i18n import _
|
||||
from .option import _RegexpOption
|
||||
from .option import RegexpOption
|
||||
|
||||
|
||||
class EmailOption(_RegexpOption):
|
||||
class EmailOption(RegexpOption):
|
||||
__slots__ = tuple()
|
||||
#https://www.w3.org/TR/html-markup/input.email.html#input.email.attrs.value.single.
|
||||
_regexp = re.compile(r"^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$")
|
||||
|
@ -21,10 +21,10 @@
|
||||
import re
|
||||
|
||||
from ..i18n import _
|
||||
from .option import _RegexpOption
|
||||
from .option import RegexpOption
|
||||
|
||||
|
||||
class FilenameOption(_RegexpOption):
|
||||
class FilenameOption(RegexpOption):
|
||||
__slots__ = tuple()
|
||||
_regexp = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
|
||||
_display_name = _('file name')
|
||||
|
@ -503,7 +503,7 @@ class Option(OnlyOption):
|
||||
all_cons_opts = tuple([self] + list(other_opts))
|
||||
unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
|
||||
if unknown_params != set():
|
||||
raise ValueError(_('unknow parameter {0} in consistency').format(unknown_params))
|
||||
raise ValueError(_('unknown parameter {0} in consistency').format(unknown_params))
|
||||
self._add_consistency(func, all_cons_opts, params)
|
||||
#validate default value when add consistency
|
||||
err = self.impl_validate(self.impl_getdefault())
|
||||
@ -660,7 +660,7 @@ class Option(OnlyOption):
|
||||
return hasattr(self, '_consistencies')
|
||||
|
||||
|
||||
class _RegexpOption(Option):
|
||||
class RegexpOption(Option):
|
||||
__slots__ = tuple()
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
@ -670,3 +670,7 @@ class _RegexpOption(Option):
|
||||
match = self._regexp.search(value)
|
||||
if not match:
|
||||
return ValueError()
|
||||
|
||||
|
||||
#FIXME compatibility
|
||||
_RegexpOption = RegexpOption
|
||||
|
@ -358,11 +358,10 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
for child in self._impl_st_getchildren(context):
|
||||
cname = child.impl_getname()
|
||||
if dyn and child.impl_is_dynoptiondescription():
|
||||
path = cname
|
||||
for value in child._impl_get_suffixes(context):
|
||||
yield SynDynOptionDescription(child,
|
||||
cname + value,
|
||||
path + value, value)
|
||||
value)
|
||||
else:
|
||||
yield child
|
||||
|
||||
@ -383,17 +382,16 @@ class OptionDescriptionWalk(CacheOptionDescription):
|
||||
for child in self._impl_st_getchildren(context, only_dyn=True):
|
||||
cname = child.impl_getname()
|
||||
if name.startswith(cname):
|
||||
path = cname
|
||||
for value in child._impl_get_suffixes(context):
|
||||
if name == cname + value:
|
||||
return SynDynOptionDescription(child, name, path + value, value)
|
||||
return SynDynOptionDescription(child, name, value)
|
||||
return ret
|
||||
|
||||
def _impl_get_dynchild(self, child, suffix):
|
||||
name = child.impl_getname() + suffix
|
||||
path = self.impl_getname() + suffix + '.' + name
|
||||
if isinstance(child, OptionDescription):
|
||||
return SynDynOptionDescription(child, name, path, suffix)
|
||||
return SynDynOptionDescription(child, name, suffix)
|
||||
else:
|
||||
return child._impl_to_dyn(name, path)
|
||||
|
||||
@ -524,12 +522,11 @@ class DynOptionDescription(OptionDescription):
|
||||
|
||||
|
||||
class SynDynOptionDescription(object):
|
||||
__slots__ = ('_opt', '_name', '_path', '_suffix')
|
||||
__slots__ = ('_opt', '_name', '_suffix')
|
||||
|
||||
def __init__(self, opt, name, path, suffix):
|
||||
def __init__(self, opt, name, suffix):
|
||||
self._opt = opt
|
||||
self._name = name
|
||||
self._path = path
|
||||
self._suffix = suffix
|
||||
|
||||
def __getattr__(self, name, context=undefined):
|
||||
@ -549,7 +546,10 @@ class SynDynOptionDescription(object):
|
||||
return self._impl_getchildren()
|
||||
|
||||
def impl_getpath(self, context):
|
||||
return self._path
|
||||
path = self._impl_getopt().impl_getpath(context).split('.')
|
||||
path[-1] += self._suffix
|
||||
path.append(self._name)
|
||||
return '.'.join(path)
|
||||
|
||||
def impl_getpaths(self, include_groups=False, _currpath=None):
|
||||
return _impl_getpaths(self, include_groups, _currpath)
|
||||
@ -825,12 +825,13 @@ class MasterSlaves(OptionDescription):
|
||||
" which has {1} as master").format(
|
||||
name, opt.impl_getname()))
|
||||
|
||||
def reset_cache(self, opt, values, type_, orig_opts):
|
||||
path = self.getmaster(opt).impl_getpath(values._getcontext())
|
||||
values._p_.delcache(path)
|
||||
for slave in self.getslaves(opt):
|
||||
slave_path = slave.impl_getpath(values._getcontext())
|
||||
values._p_.delcache(slave_path)
|
||||
def reset_cache(self, opt, obj, type_, resetted_opts):
|
||||
context = obj._getcontext()
|
||||
#FIXME pb avec dyn, devrait etre une option
|
||||
mopt = self.getmaster(None)
|
||||
mopt.reset_cache(mopt, obj, type_, resetted_opts)
|
||||
for slave in self.getslaves(mopt):
|
||||
slave.reset_cache(slave, obj, type_, resetted_opts)
|
||||
|
||||
def _getattr(self, name, suffix=undefined, context=undefined, dyn=True):
|
||||
return super(MasterSlaves, self)._getattr(name, suffix, context, dyn)
|
||||
|
@ -375,7 +375,7 @@ class Settings(object):
|
||||
if opt is not None and _path is None:
|
||||
_path = opt.impl_getpath(self._getcontext())
|
||||
self._p_.delproperties(_path)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path, only=('settings',))
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=_path, only=('settings', 'values'))
|
||||
|
||||
def _getproperties(self, opt=None, path=None,
|
||||
setting_properties=undefined, read_write=True,
|
||||
@ -394,12 +394,12 @@ class Settings(object):
|
||||
props = self._p_.getproperties(path, default_properties)
|
||||
else:
|
||||
props = meta.cfgimpl_get_settings()._getproperties()
|
||||
if 'cache' in props:
|
||||
if 'expire' in props:
|
||||
ntime = ntime + expires_time
|
||||
else:
|
||||
ntime = None
|
||||
self._p_.setcache(path, props, ntime, None)
|
||||
if 'cache' in props:
|
||||
if 'expire' in props:
|
||||
ntime = ntime + expires_time
|
||||
else:
|
||||
ntime = None
|
||||
self._p_.setcache(path, props, ntime, None)
|
||||
else:
|
||||
if path is None: # pragma: optional cover
|
||||
raise ValueError(_('if opt is not None, path should not be'
|
||||
@ -468,7 +468,8 @@ class Settings(object):
|
||||
raise ConfigError(_('cannot add those properties: {0}').format(
|
||||
' '.join(forbidden_properties)))
|
||||
self._p_.setproperties(path, properties)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path)
|
||||
#values too because of slave values could have a PropertiesOptionError has value
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path, only=('values', 'properties',))
|
||||
|
||||
def getpermissive(self, setting_properties, path=None):
|
||||
if 'cache' in setting_properties and 'expire' in setting_properties:
|
||||
@ -595,7 +596,7 @@ class Settings(object):
|
||||
raise TypeError(_('permissive must be a tuple'))
|
||||
self._pp_.setpermissive(path, permissive)
|
||||
setting_properties = self._getproperties(read_write=False)
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path, only=('values',))
|
||||
self._getcontext().cfgimpl_reset_cache(opt=opt, path=path, only=('properties', 'values'))
|
||||
if 'cache' in setting_properties:
|
||||
if 'expire' in setting_properties:
|
||||
ntime = int(time()) + expires_time
|
||||
|
@ -87,7 +87,7 @@ class Values(object):
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
index=index, validate=validate)
|
||||
_orig_context.cfgimpl_reset_cache(opt=opt, path=path, only=('values',))
|
||||
_orig_context.cfgimpl_reset_cache(opt=opt, path=path, only=('values', 'properties'))
|
||||
if isinstance(value, list) and index is not None:
|
||||
#if return a list and index is set, return value only if
|
||||
#it's a submulti without submulti_index and without list of list
|
||||
@ -295,7 +295,8 @@ class Values(object):
|
||||
if isinstance(val, Exception):
|
||||
return val
|
||||
# cache doesn't work with SubMulti yet
|
||||
if index is None and not isinstance(val, SubMulti) and 'cache' in setting_properties and \
|
||||
if not from_masterslave and index is None and not isinstance(val, SubMulti) and \
|
||||
'cache' in setting_properties and \
|
||||
validate and validate_properties and force_permissive is False \
|
||||
and trusted_cached_properties is True and _orig_context is undefined:
|
||||
if 'expire' in setting_properties:
|
||||
|
Reference in New Issue
Block a user