convert tests
This commit is contained in:
408
tiramisu/api.py
408
tiramisu/api.py
@ -15,11 +15,17 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ____________________________________________________________
|
||||
from inspect import ismethod, getdoc
|
||||
from .error import APIError, PropertiesOptionError
|
||||
from .error import APIError, PropertiesOptionError, ConfigError
|
||||
from .i18n import _
|
||||
from .setting import owners, undefined
|
||||
from .option import ChoiceOption
|
||||
from time import time
|
||||
from copy import deepcopy
|
||||
|
||||
|
||||
TIRAMISU_VERSION = 3
|
||||
|
||||
|
||||
try:
|
||||
from .value import Multi
|
||||
except:
|
||||
@ -27,29 +33,31 @@ except:
|
||||
|
||||
|
||||
COUNT_TIME = False
|
||||
#COUNT_TIME = {}
|
||||
COUNT_TIME = {}
|
||||
|
||||
|
||||
def count(func):
|
||||
global MOD_COUNT_TIME
|
||||
class_name = func.__str__().split()[1].split('.')[0]
|
||||
func_name = func.__name__
|
||||
def wrapper(*args, **kwargs):
|
||||
time1 = time()
|
||||
ret = func(*args, **kwargs)
|
||||
time2 = time()
|
||||
diff = (time2 - time1) * 1000.0
|
||||
MOD_COUNT_TIME[func_name]['max'] = max(MOD_COUNT_TIME[func_name]['max'], diff)
|
||||
MOD_COUNT_TIME[func_name]['min'] = min(MOD_COUNT_TIME[func_name]['min'], diff)
|
||||
MOD_COUNT_TIME[func_name]['total'] += diff
|
||||
MOD_COUNT_TIME[func_name]['nb'] += 1
|
||||
MOD_COUNT_TIME[class_name][func_name]['max'] = max(MOD_COUNT_TIME[class_name][func_name]['max'], diff)
|
||||
MOD_COUNT_TIME[class_name][func_name]['min'] = min(MOD_COUNT_TIME[class_name][func_name]['min'], diff)
|
||||
MOD_COUNT_TIME[class_name][func_name]['total'] += diff
|
||||
MOD_COUNT_TIME[class_name][func_name]['nb'] += 1
|
||||
#print('%s function took %0.3f ms' % (func_name, diff))
|
||||
#print(COUNT_TIME)
|
||||
return ret
|
||||
if COUNT_TIME is not False:
|
||||
COUNT_TIME[func_name] = {'max': 0,
|
||||
'min': 1000,
|
||||
'nb': 0,
|
||||
'total': 0}
|
||||
COUNT_TIME.setdefault(class_name, {})
|
||||
COUNT_TIME[class_name][func_name] = {'max': 0,
|
||||
'min': 1000,
|
||||
'nb': 0,
|
||||
'total': 0}
|
||||
MOD_COUNT_TIME = deepcopy(COUNT_TIME)
|
||||
return wrapper
|
||||
return func
|
||||
@ -59,19 +67,23 @@ def display_count():
|
||||
if COUNT_TIME is not False:
|
||||
global MOD_COUNT_TIME
|
||||
#print(MOD_COUNT_TIME)
|
||||
for func in MOD_COUNT_TIME:
|
||||
print('>', func)
|
||||
print('=> nb:', MOD_COUNT_TIME[func]['nb'])
|
||||
if MOD_COUNT_TIME[func]['nb'] != 0:
|
||||
print('=> min:', MOD_COUNT_TIME[func]['min'])
|
||||
print('=> max:', MOD_COUNT_TIME[func]['max'])
|
||||
print('=> moy:', MOD_COUNT_TIME[func]['total'] / MOD_COUNT_TIME[func]['nb'])
|
||||
print()
|
||||
for class_name in MOD_COUNT_TIME:
|
||||
print('>', class_name)
|
||||
for func in MOD_COUNT_TIME[class_name]:
|
||||
print('=>', func)
|
||||
print('==> nb:', MOD_COUNT_TIME[class_name][func]['nb'])
|
||||
if MOD_COUNT_TIME[class_name][func]['nb'] != 0:
|
||||
print('==> min:', MOD_COUNT_TIME[class_name][func]['min'])
|
||||
print('==> max:', MOD_COUNT_TIME[class_name][func]['max'])
|
||||
print('==> moy:', MOD_COUNT_TIME[class_name][func]['total'] / MOD_COUNT_TIME[class_name][func]['nb'])
|
||||
MOD_COUNT_TIME = deepcopy(COUNT_TIME)
|
||||
|
||||
class CommonTiramisuOption(object):
|
||||
icon = '\u2937'
|
||||
tmpl_help = u' {} {}: {}'
|
||||
allow_unrestraint = False
|
||||
allow_optiondescription = False
|
||||
slave_need_index = True
|
||||
|
||||
def __init__(self,
|
||||
@ -82,8 +94,10 @@ class CommonTiramisuOption(object):
|
||||
setting_properties,
|
||||
force_permissive,
|
||||
force_unrestraint):
|
||||
self.opt = opt
|
||||
self.path = path
|
||||
if not self.allow_optiondescription and opt.impl_is_optiondescription():
|
||||
raise APIError(_('option must not be an optiondescription'))
|
||||
self._opt = opt
|
||||
self._path = path
|
||||
self.index = index
|
||||
if self.slave_need_index:
|
||||
self._test_slave_index()
|
||||
@ -95,7 +109,8 @@ class CommonTiramisuOption(object):
|
||||
self._unrestraint_not_allowed(force_unrestraint)
|
||||
|
||||
def _test_slave_index(self):
|
||||
if self.index is None and self.opt.impl_is_master_slaves('slave'):
|
||||
if not self._opt.impl_is_optiondescription() and self.index is None and \
|
||||
self._opt.impl_is_master_slaves('slave'):
|
||||
raise APIError('index must be set with a slave option')
|
||||
|
||||
def _unrestraint_not_allowed(self, force_unrestraint):
|
||||
@ -125,6 +140,7 @@ class CommonTiramisuOption(object):
|
||||
class TiramisuOptionOption(CommonTiramisuOption):
|
||||
"""get information from an option"""
|
||||
allow_unrestraint = True
|
||||
allow_optiondescription = True
|
||||
slave_need_index = False
|
||||
|
||||
def __init__(self,
|
||||
@ -145,37 +161,46 @@ class TiramisuOptionOption(CommonTiramisuOption):
|
||||
if config:
|
||||
self.values = self.config.cfgimpl_get_values()
|
||||
|
||||
@count
|
||||
def ismulti(self):
|
||||
"""test if option could have multi value"""
|
||||
return self.opt.impl_is_multi()
|
||||
return self._opt.impl_is_multi()
|
||||
|
||||
@count
|
||||
def issubmulti(self):
|
||||
"""test if option could have submulti value"""
|
||||
return self.opt.impl_is_submulti()
|
||||
return self._opt.impl_is_submulti()
|
||||
|
||||
@count
|
||||
def ismasterslaves(self):
|
||||
"""test if option is a master or a slave"""
|
||||
return self.opt.impl_is_master_slaves()
|
||||
return self._opt.impl_is_master_slaves()
|
||||
|
||||
@count
|
||||
def ismaster(self):
|
||||
"""test if option is a master"""
|
||||
return self.opt.impl_is_master_slaves('master')
|
||||
return self._opt.impl_is_master_slaves('master')
|
||||
|
||||
@count
|
||||
def isslave(self):
|
||||
"""test if option is a slave"""
|
||||
return self.opt.impl_is_master_slaves('slave')
|
||||
return self._opt.impl_is_master_slaves('slave')
|
||||
|
||||
@count
|
||||
def getname(self):
|
||||
return self.opt.impl_getname()
|
||||
return self._opt.impl_getname()
|
||||
|
||||
@count
|
||||
def getdoc(self):
|
||||
return self.opt.impl_get_display_name()
|
||||
return self._opt.impl_get_display_name()
|
||||
|
||||
@count
|
||||
def getdefault(self):
|
||||
return self.opt.impl_getdefault()
|
||||
return self._opt.impl_getdefault()
|
||||
|
||||
@count
|
||||
def getdefaultmulti(self):
|
||||
return self.opt.impl_getdefault_multi()
|
||||
return self._opt.impl_getdefault_multi()
|
||||
|
||||
|
||||
class TiramisuOptionOwner(CommonTiramisuOption):
|
||||
@ -200,39 +225,46 @@ class TiramisuOptionOwner(CommonTiramisuOption):
|
||||
if config:
|
||||
self.values = self.config.cfgimpl_get_values()
|
||||
|
||||
@count
|
||||
def get(self):
|
||||
"""get owner for a specified option"""
|
||||
return self.values.getowner(self.opt,
|
||||
self.path,
|
||||
self.setting_properties,
|
||||
return self.values.getowner(self._opt,
|
||||
path=self._path,
|
||||
setting_properties=self.setting_properties,
|
||||
index=self.index,
|
||||
force_permissive=self.force_permissive)
|
||||
|
||||
@count
|
||||
def isdefault(self):
|
||||
"""is option has defaut value"""
|
||||
return self.values.is_default_owner(self.opt,
|
||||
self.path,
|
||||
return self.values.is_default_owner(self._opt,
|
||||
self._path,
|
||||
self.setting_properties,
|
||||
index=self.index,
|
||||
force_permissive=self.force_permissive)
|
||||
|
||||
@count
|
||||
def set(self, owner):
|
||||
"""get owner for a specified option"""
|
||||
if TIRAMISU_VERSION == 2:
|
||||
if owner in ['default', 'forced', 'meta']:
|
||||
raise ConfigError()
|
||||
try:
|
||||
obj_owner = getattr(owners, owner)
|
||||
except AttributeError:
|
||||
owners.addowner(owner)
|
||||
obj_owner = getattr(owners, owner)
|
||||
self.values.setowner(self.opt,
|
||||
self.path,
|
||||
obj_owner,
|
||||
self.index)
|
||||
self.values.setowner(self._opt,
|
||||
path=self._path,
|
||||
owner=obj_owner,
|
||||
setting_properties=self.setting_properties,
|
||||
index=self.index)
|
||||
|
||||
|
||||
class TiramisuOptionProperty(CommonTiramisuOption):
|
||||
"""manager option's property"""
|
||||
#allow_unrestraint = True
|
||||
allow_optiondescription = True
|
||||
slave_need_index = False
|
||||
|
||||
def __init__(self,
|
||||
@ -253,29 +285,49 @@ class TiramisuOptionProperty(CommonTiramisuOption):
|
||||
if config:
|
||||
self.settings = config.cfgimpl_get_settings()
|
||||
|
||||
@count
|
||||
def get(self):
|
||||
self._test_slave_index()
|
||||
return self.settings.getproperties(self.opt,
|
||||
self.path,
|
||||
self.setting_properties,
|
||||
index=self.index)
|
||||
properties = self.settings.getproperties(self._opt,
|
||||
self._path,
|
||||
self.setting_properties,
|
||||
index=self.index)
|
||||
if TIRAMISU_VERSION == 2:
|
||||
properties = properties.get()
|
||||
return set(properties)
|
||||
|
||||
@count
|
||||
def set(self, properties):
|
||||
"""set properties for a specified option"""
|
||||
self.settings.setproperties(self.opt,
|
||||
self.path,
|
||||
properties)
|
||||
properties = frozenset(properties)
|
||||
self.settings.setproperties(opt=self._opt,
|
||||
path=self._path,
|
||||
properties=properties)
|
||||
|
||||
@count
|
||||
def add(self, prop):
|
||||
props = self.get()
|
||||
props.add(prop)
|
||||
self.set(props)
|
||||
|
||||
@count
|
||||
def pop(self, prop):
|
||||
props = self.get()
|
||||
props.remove(prop)
|
||||
self.set(props)
|
||||
|
||||
@count
|
||||
def reset(self):
|
||||
"""reset all personalised properties
|
||||
"""
|
||||
self.settings.reset(opt=self.opt,
|
||||
path=self.path)
|
||||
self.settings.reset(opt=self._opt,
|
||||
path=self._path)
|
||||
|
||||
|
||||
class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||
"""manager option's property"""
|
||||
allow_unrestraint = True
|
||||
allow_optiondescription = True
|
||||
slave_need_index = False
|
||||
|
||||
def __init__(self,
|
||||
@ -296,48 +348,47 @@ class TiramisuOptionPermissive(CommonTiramisuOption):
|
||||
if config:
|
||||
self.settings = config.cfgimpl_get_settings()
|
||||
|
||||
@count
|
||||
def get(self):
|
||||
"""get permissive value for a specified path"""
|
||||
return self.settings.getpermissive(self.opt,
|
||||
self.path)
|
||||
if TIRAMISU_VERSION == 2:
|
||||
args = [self.setting_properties, self._path]
|
||||
else:
|
||||
args = [self._opt, self._path]
|
||||
return self.settings.getpermissive(*args)
|
||||
|
||||
@count
|
||||
def set(self, permissive):
|
||||
self.settings.setpermissive(self.opt,
|
||||
self.path,
|
||||
permissive)
|
||||
if TIRAMISU_VERSION == 2:
|
||||
permissive = tuple(permissive)
|
||||
self.settings.setpermissive(opt=self._opt,
|
||||
path=self._path,
|
||||
permissive=permissive)
|
||||
|
||||
@count
|
||||
def reset(self, path):
|
||||
"""reset all personalised permissive
|
||||
"""
|
||||
self.set(tuple())
|
||||
|
||||
|
||||
class TiramisuOptionInformation(CommonTiramisuOption):
|
||||
allow_optiondescription = True
|
||||
|
||||
@count
|
||||
def get(self, name, default=undefined):
|
||||
return self._opt.impl_get_information(name, default)
|
||||
|
||||
|
||||
class TiramisuOptionValue(CommonTiramisuOption):
|
||||
"""manager option's value"""
|
||||
slave_need_index = False
|
||||
|
||||
def __init__(self,
|
||||
opt,
|
||||
path,
|
||||
index,
|
||||
config,
|
||||
setting_properties,
|
||||
force_permissive,
|
||||
force_unrestraint):
|
||||
|
||||
super(TiramisuOptionValue, self).__init__(opt,
|
||||
path,
|
||||
index,
|
||||
config,
|
||||
setting_properties,
|
||||
force_permissive,
|
||||
force_unrestraint)
|
||||
|
||||
@count
|
||||
def get(self):
|
||||
self._test_slave_index()
|
||||
settings = self.config.cfgimpl_get_settings()
|
||||
value = self.config.getattr(self.path,
|
||||
value = self.config.getattr(self._path,
|
||||
index=self.index,
|
||||
setting_properties=self.setting_properties,
|
||||
force_permissive=self.force_permissive)
|
||||
@ -353,17 +404,17 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||
if isinstance(value, list):
|
||||
while undefined in value:
|
||||
idx = value.index(undefined)
|
||||
value[idx] = values.getdefaultvalue(self.opt,
|
||||
self.path,
|
||||
value[idx] = values.getdefaultvalue(self._opt,
|
||||
self._path,
|
||||
self.setting_properties,
|
||||
idx)
|
||||
else:
|
||||
if value == undefined:
|
||||
value = values.getdefaultvalue(self.opt,
|
||||
self.path,
|
||||
value = values.getdefaultvalue(self._opt,
|
||||
self._path,
|
||||
self.setting_properties,
|
||||
self.index)
|
||||
self.config.setattr(self.path,
|
||||
self.config.setattr(self._path,
|
||||
value,
|
||||
index=self.index,
|
||||
setting_properties=self.setting_properties,
|
||||
@ -375,27 +426,48 @@ class TiramisuOptionValue(CommonTiramisuOption):
|
||||
"""
|
||||
self._test_slave_index()
|
||||
#FIXME only for master
|
||||
self.config.delattr(self.path,
|
||||
self.config.delattr(self._path,
|
||||
index=index,
|
||||
setting_properties=self.setting_properties,
|
||||
force_permissive=self.force_permissive)
|
||||
|
||||
@count
|
||||
def reset(self):
|
||||
"""reset value for a value"""
|
||||
self._test_slave_index()
|
||||
self.config.delattr(self.path,
|
||||
self.config.delattr(self._path,
|
||||
index=self.index,
|
||||
setting_properties=self.setting_properties,
|
||||
force_permissive=self.force_permissive)
|
||||
|
||||
@count
|
||||
def len(self):
|
||||
#FIXME only for slave
|
||||
subconfig_path = self.path.rsplit('.', 1)[0]
|
||||
subconfig_path = self._path.rsplit('.', 1)[0]
|
||||
subconfig = self.config.getattr(subconfig_path,
|
||||
setting_properties=self.setting_properties,
|
||||
force_permissive=self.force_permissive)
|
||||
return subconfig.cfgimpl_get_length()
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name == 'list':
|
||||
if isinstance(self._opt, ChoiceOption):
|
||||
return self._list
|
||||
raise APIError(_('{} allowed only for choiceoption').format(name))
|
||||
|
||||
@count
|
||||
def _list(self):
|
||||
return self._opt.impl_get_values(context=self.config,
|
||||
setting_properties=self.setting_properties)
|
||||
|
||||
|
||||
def registers(registers, prefix):
|
||||
for module_name in globals().keys():
|
||||
if module_name != prefix and module_name.startswith(prefix):
|
||||
module = globals()[module_name]
|
||||
func_name = module_name[len(prefix):].lower()
|
||||
registers[func_name] = module
|
||||
|
||||
|
||||
class TiramisuOption(object):
|
||||
icon = '\u2937'
|
||||
@ -410,20 +482,15 @@ class TiramisuOption(object):
|
||||
force_permissive,
|
||||
force_unrestraint):
|
||||
|
||||
self.opt = opt
|
||||
self.path = path
|
||||
self._opt = opt
|
||||
self._path = path
|
||||
self.index = index
|
||||
self.config = config
|
||||
self.setting_properties = setting_properties
|
||||
self.force_permissive = force_permissive
|
||||
self.force_unrestraint = force_unrestraint
|
||||
self.registers = {}
|
||||
self.prefix = self.__class__.__name__
|
||||
for module_name in globals().keys():
|
||||
if module_name != self.prefix and module_name.startswith(self.prefix):
|
||||
module = globals()[module_name]
|
||||
func_name = module_name[len(self.prefix):].lower()
|
||||
self.registers[func_name] = module
|
||||
registers(self.registers, self.__class__.__name__)
|
||||
|
||||
def _help(self):
|
||||
txt = []
|
||||
@ -435,8 +502,8 @@ class TiramisuOption(object):
|
||||
|
||||
def __getattr__(self, subfunc):
|
||||
if subfunc in self.registers:
|
||||
return self.registers[subfunc](self.opt,
|
||||
self.path,
|
||||
return self.registers[subfunc](self._opt,
|
||||
self._path,
|
||||
self.index,
|
||||
self.config,
|
||||
self.setting_properties,
|
||||
@ -445,7 +512,21 @@ class TiramisuOption(object):
|
||||
elif subfunc == 'help':
|
||||
return self._help()
|
||||
else:
|
||||
raise APIError(_('please specify a valid sub function'))
|
||||
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
||||
|
||||
@count
|
||||
def make_dict(self,
|
||||
flatten=False,
|
||||
withvalue=undefined,
|
||||
withoption=None,
|
||||
fullpath=False):
|
||||
return self.config.getattr(setting_properties=self.setting_properties,
|
||||
name=self._path).make_dict(setting_properties=self.setting_properties,
|
||||
flatten=flatten,
|
||||
fullpath=fullpath,
|
||||
withoption=withoption,
|
||||
force_permissive=self.force_permissive,
|
||||
withvalue=withvalue)
|
||||
|
||||
|
||||
class TiramisuContext(object):
|
||||
@ -461,12 +542,82 @@ class TiramisuContext(object):
|
||||
self.force_unrestraint = force_unrestraint
|
||||
self.setting_properties = setting_properties
|
||||
|
||||
|
||||
class TiramisuContextInformation(TiramisuContext):
|
||||
@count
|
||||
def get(self, name, default=undefined):
|
||||
return self.config.impl_get_information(name, default)
|
||||
|
||||
@count
|
||||
def set(self, name, value):
|
||||
self.config.impl_set_information(name, value)
|
||||
|
||||
@count
|
||||
def reset(self, name):
|
||||
self.config.impl_del_information(name)
|
||||
|
||||
|
||||
class TiramisuContextValue(TiramisuContext):
|
||||
@count
|
||||
def mandatory_warnings(self):
|
||||
return self.config.cfgimpl_get_values().mandatory_warnings(self.setting_properties)
|
||||
|
||||
@count
|
||||
def get(self):
|
||||
return self.config.cfgimpl_get_values().get_modified_values()
|
||||
|
||||
|
||||
class TiramisuContextOwner(TiramisuContext):
|
||||
@count
|
||||
def get(self):
|
||||
return self.config.cfgimpl_get_settings().getowner()
|
||||
|
||||
|
||||
class TiramisuContextProperty(TiramisuContext):
|
||||
@count
|
||||
def read_only(self):
|
||||
self.config.cfgimpl_get_settings().read_only()
|
||||
|
||||
@count
|
||||
def read_write(self):
|
||||
self.config.cfgimpl_get_settings().read_write()
|
||||
# #FIXME ?
|
||||
settings = self.config.cfgimpl_get_settings()
|
||||
settings.set_context_permissive(frozenset(['hidden']))
|
||||
#/FIXME ?
|
||||
|
||||
@count
|
||||
def add(self, prop):
|
||||
props = self.get()
|
||||
props.add(prop)
|
||||
self.set(props)
|
||||
|
||||
@count
|
||||
def pop(self, prop):
|
||||
props = self.get()
|
||||
props.remove(prop)
|
||||
self.set(props)
|
||||
|
||||
@count
|
||||
def get(self):
|
||||
return set(self.config.cfgimpl_get_settings().get_context_properties())
|
||||
|
||||
@count
|
||||
def set(self, props):
|
||||
self.config.cfgimpl_get_settings().set_context_properties(frozenset(props))
|
||||
|
||||
|
||||
class TiramisuContextPermissive(TiramisuContext):
|
||||
|
||||
@count
|
||||
def set(self, permissives):
|
||||
if TIRAMISU_VERSION != 2:
|
||||
permissives = frozenset(permissives)
|
||||
self.config.cfgimpl_get_settings().set_context_permissive(permissives)
|
||||
|
||||
|
||||
class TiramisuContextOption(TiramisuContext):
|
||||
@count
|
||||
def find_first(self,
|
||||
name,
|
||||
type='option'):
|
||||
@ -477,6 +628,7 @@ class TiramisuContextOption(TiramisuContext):
|
||||
force_permissive=self.force_permissive,
|
||||
check_properties=not self.force_unrestraint)
|
||||
|
||||
@count
|
||||
def find(self,
|
||||
name,
|
||||
type='option'):
|
||||
@ -486,19 +638,33 @@ class TiramisuContextOption(TiramisuContext):
|
||||
force_permissive=self.force_permissive,
|
||||
check_properties=not self.force_unrestraint)
|
||||
|
||||
@count
|
||||
def get(self, path):
|
||||
return self.config.unwrap_from_path(path,
|
||||
validate=False,
|
||||
validate_properties=False)
|
||||
|
||||
@count
|
||||
def make_dict(self,
|
||||
flatten=False,
|
||||
withvalue=undefined,
|
||||
withoption=None,
|
||||
fullpath=False):
|
||||
return self.config.make_dict(setting_properties=self.setting_properties,
|
||||
flatten=flatten,
|
||||
fullpath=fullpath,
|
||||
force_permissive=self.force_permissive,
|
||||
withoption=withoption,
|
||||
withvalue=withvalue)
|
||||
|
||||
class TiramisuOptionDispatcher(TiramisuContextOption):
|
||||
|
||||
class TiramisuDispatcherOption(TiramisuContextOption):
|
||||
def __init__(self,
|
||||
config,
|
||||
force_permissive,
|
||||
force_unrestraint):
|
||||
self.setting_properties = config.cfgimpl_get_settings().get_context_properties()
|
||||
super(TiramisuOptionDispatcher, self).__init__(config,
|
||||
super(TiramisuDispatcherOption, self).__init__(config,
|
||||
force_permissive,
|
||||
force_unrestraint,
|
||||
self.setting_properties)
|
||||
@ -538,32 +704,6 @@ class TiramisuOptionDispatcher(TiramisuContextOption):
|
||||
self.force_unrestraint)
|
||||
|
||||
|
||||
class TiramisuContextConfig(TiramisuContext):
|
||||
def make_dict(self):
|
||||
return self.config.make_dict(self.setting_properties)
|
||||
|
||||
|
||||
class TiramisuConfigDispatcher(TiramisuContextConfig):
|
||||
def __init__(self,
|
||||
config,
|
||||
force_permissive,
|
||||
force_unrestraint):
|
||||
self.setting_properties = config.cfgimpl_get_settings().get_context_properties()
|
||||
super(TiramisuConfigDispatcher, self).__init__(config,
|
||||
force_permissive,
|
||||
force_unrestraint,
|
||||
self.setting_properties)
|
||||
|
||||
def __call__(self, path):
|
||||
if path is None:
|
||||
subconfig = self.config
|
||||
else:
|
||||
subconfig = self.config.getconfig(path)
|
||||
return TiramisuAPI(subconfig,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=self.force_unrestraint)
|
||||
|
||||
|
||||
class TiramisuAPI(object):
|
||||
icon = '\u2937'
|
||||
tmpl_help = ' {} {}: {}'
|
||||
@ -575,6 +715,9 @@ class TiramisuAPI(object):
|
||||
self._config = config
|
||||
self.force_permissive = force_permissive
|
||||
self.force_unrestraint = force_unrestraint
|
||||
self.registers = {}
|
||||
registers(self.registers, 'TiramisuContext')
|
||||
registers(self.registers, 'TiramisuDispatcher')
|
||||
|
||||
def __getattr__(self, subfunc):
|
||||
if subfunc == 'forcepermissive':
|
||||
@ -585,20 +728,16 @@ class TiramisuAPI(object):
|
||||
return TiramisuAPI(self._config,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=True)
|
||||
elif subfunc == 'config':
|
||||
return TiramisuAPI(self._config,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=True)
|
||||
elif subfunc == 'help':
|
||||
return self._help()
|
||||
elif subfunc == 'owner':
|
||||
return TiramisuContextOwner(self._config,
|
||||
self.force_permissive,
|
||||
self.force_unrestraint)
|
||||
elif subfunc == 'config':
|
||||
return TiramisuConfigDispatcher(self._config,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=self.force_unrestraint)
|
||||
elif subfunc == 'option':
|
||||
return TiramisuOptionDispatcher(self._config,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=self.force_unrestraint)
|
||||
elif subfunc in self.registers:
|
||||
return self.registers[subfunc](self._config,
|
||||
force_permissive=self.force_permissive,
|
||||
force_unrestraint=self.force_unrestraint)
|
||||
else:
|
||||
raise APIError(_('please specify a valid sub function ({})').format(subfunc))
|
||||
|
||||
@ -610,17 +749,8 @@ class TiramisuAPI(object):
|
||||
txt.append(module(None, None).help)
|
||||
return '\n'.join(txt)
|
||||
|
||||
def read_only(self):
|
||||
self._config.read_write()
|
||||
|
||||
def read_write(self):
|
||||
settings = self._config.cfgimpl_get_settings()
|
||||
self._config.read_write()
|
||||
# #FIXME ?
|
||||
settings.set_context_permissive(frozenset(['hidden']))
|
||||
#/FIXME ?
|
||||
|
||||
|
||||
@count
|
||||
def getapi(config):
|
||||
"""instanciate TiramisuAPI
|
||||
|
||||
|
@ -30,7 +30,7 @@ def carry_out_calculation(option,
|
||||
context,
|
||||
callback,
|
||||
callback_params,
|
||||
setting_properties=undefined,
|
||||
setting_properties,
|
||||
index=undefined,
|
||||
validate=True,
|
||||
is_validator=False):
|
||||
|
@ -86,6 +86,10 @@ class SubConfig(object):
|
||||
master = descr.getmaster()
|
||||
context_ = context()
|
||||
masterp = master.impl_getpath(context_)
|
||||
context_.cfgimpl_get_settings().validate_properties(master,
|
||||
masterp,
|
||||
setting_properties,
|
||||
force_permissive=force_permissive)
|
||||
value = context_.cfgimpl_get_values().get_cached_value(master,
|
||||
masterp,
|
||||
setting_properties,
|
||||
@ -104,6 +108,7 @@ class SubConfig(object):
|
||||
resetted_opts,
|
||||
opt,
|
||||
path):
|
||||
|
||||
tresetted_opts = copy(resetted_opts)
|
||||
opt.reset_cache(opt,
|
||||
path,
|
||||
@ -121,7 +126,7 @@ class SubConfig(object):
|
||||
option = woption()
|
||||
if option in resetted_opts:
|
||||
continue
|
||||
option_path = opt.impl_getpath(self)
|
||||
option_path = option.impl_getpath(self)
|
||||
self.reset_one_option_cache(values,
|
||||
settings,
|
||||
resetted_opts,
|
||||
@ -139,17 +144,6 @@ class SubConfig(object):
|
||||
:param only_expired: if True reset only expired cached values
|
||||
:type only_expired: boolean
|
||||
"""
|
||||
|
||||
def reset_expired_cache():
|
||||
# reset cache for expired cache value ony
|
||||
datetime = int(time())
|
||||
values._p_.reset_expired_cache(datetime)
|
||||
settings._p_.reset_expired_cache(datetime)
|
||||
|
||||
def reset_all_cache():
|
||||
values._p_.reset_all_cache()
|
||||
settings._p_.reset_all_cache()
|
||||
|
||||
if resetted_opts is None:
|
||||
resetted_opts = set()
|
||||
|
||||
@ -166,9 +160,13 @@ class SubConfig(object):
|
||||
path)
|
||||
|
||||
elif only_expired:
|
||||
reset_expired_cache()
|
||||
# reset cache for expired cache value ony
|
||||
datetime = int(time())
|
||||
values._p_.reset_expired_cache(datetime)
|
||||
settings._p_.reset_expired_cache(datetime)
|
||||
else:
|
||||
reset_all_cache()
|
||||
values._p_.reset_all_cache()
|
||||
settings._p_.reset_all_cache()
|
||||
|
||||
def cfgimpl_get_home_by_path(self,
|
||||
path,
|
||||
@ -676,7 +674,7 @@ class SubConfig(object):
|
||||
setting_properties=setting_properties):
|
||||
path = '.'.join(path.split('.')[:-1])
|
||||
opt = context.unwrap_from_path(path,
|
||||
orce_permissive=True)
|
||||
force_permissive=True)
|
||||
mypath = self.cfgimpl_get_path()
|
||||
if mypath is not None:
|
||||
if mypath == path:
|
||||
@ -717,7 +715,7 @@ class SubConfig(object):
|
||||
|
||||
def _make_sub_dict(self,
|
||||
option,
|
||||
path,
|
||||
name,
|
||||
pathsvalues,
|
||||
_currpath,
|
||||
flatten,
|
||||
@ -730,17 +728,18 @@ class SubConfig(object):
|
||||
length = self.cfgimpl_get_length()
|
||||
if length:
|
||||
for idx in range(length):
|
||||
ret.append(self.getattr(path,
|
||||
ret.append(self.getattr(name,
|
||||
index=idx,
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties))
|
||||
elif setting_properties:
|
||||
path = self._get_subpath(name)
|
||||
self.cfgimpl_get_settings().validate_properties(option,
|
||||
path,
|
||||
setting_properties,
|
||||
force_permissive=force_permissive)
|
||||
else:
|
||||
ret = self.getattr(path,
|
||||
ret = self.getattr(name,
|
||||
force_permissive=force_permissive,
|
||||
setting_properties=setting_properties)
|
||||
except PropertiesOptionError:
|
||||
@ -749,7 +748,7 @@ class SubConfig(object):
|
||||
if option.impl_is_optiondescription():
|
||||
pathsvalues += ret.make_dict(setting_properties,
|
||||
flatten=flatten,
|
||||
_currpath=_currpath + path.split('.'),
|
||||
_currpath=_currpath + [name],
|
||||
force_permissive=force_permissive,
|
||||
fullpath=fullpath)
|
||||
else:
|
||||
@ -764,7 +763,7 @@ class SubConfig(object):
|
||||
# name = '.'.join([root_path, opt.impl_getname()])
|
||||
name = self._get_subpath(name)
|
||||
else:
|
||||
name = '.'.join(_currpath + [option.impl_getname()])
|
||||
name = '.'.join(_currpath + [name])
|
||||
pathsvalues.append((name, ret))
|
||||
|
||||
def cfgimpl_get_path(self,
|
||||
@ -789,30 +788,6 @@ class _CommonConfig(SubConfig):
|
||||
descr.impl_build_force_store_values(self,
|
||||
force_store_values)
|
||||
|
||||
def read_only(self):
|
||||
"read only is a global config's setting, see `settings.py`"
|
||||
self.cfgimpl_get_settings().read_only()
|
||||
|
||||
def read_write(self):
|
||||
"read write is a global config's setting, see `settings.py`"
|
||||
self.cfgimpl_get_settings().read_write()
|
||||
|
||||
def getowner(self,
|
||||
opt,
|
||||
index=None,
|
||||
force_permissive=False):
|
||||
"""convenience method to retrieve an option's owner
|
||||
from the config itself
|
||||
"""
|
||||
if not isinstance(opt, Option) and \
|
||||
not isinstance(opt, SymLinkOption) and \
|
||||
not isinstance(opt, DynSymLinkOption): # pragma: optional cover
|
||||
raise TypeError(_('opt in getowner must be an option not {0}'
|
||||
'').format(type(opt)))
|
||||
return self.cfgimpl_get_values().getowner(opt,
|
||||
index=index,
|
||||
force_permissive=force_permissive)
|
||||
|
||||
def unwrap_from_path(self,
|
||||
path,
|
||||
setting_properties=None,
|
||||
@ -847,7 +822,8 @@ class _CommonConfig(SubConfig):
|
||||
else:
|
||||
true_option = option
|
||||
true_path = path
|
||||
if index is None and true_option.impl_is_master_slaves('slave'):
|
||||
if not true_option.impl_is_optiondescription() and index is None and \
|
||||
true_option.impl_is_master_slaves('slave'):
|
||||
subpath = self._get_subpath(true_path)
|
||||
self.cfgimpl_get_settings().validate_properties(true_option,
|
||||
subpath,
|
||||
|
@ -16,7 +16,6 @@
|
||||
# ____________________________________________________________
|
||||
"user defined exceptions"
|
||||
from .i18n import _
|
||||
import sys
|
||||
|
||||
|
||||
def display_list(lst, separator='and'):
|
||||
@ -28,28 +27,22 @@ def display_list(lst, separator='and'):
|
||||
return ''
|
||||
elif len(lst) == 1:
|
||||
ret = lst[0]
|
||||
if sys.version_info[0] < 3 and isinstance(ret, unicode):
|
||||
ret = ret.encode('utf8')
|
||||
if not isinstance(ret, str):
|
||||
ret = str(ret)
|
||||
return ret
|
||||
return '"{}"'.format(ret)
|
||||
else:
|
||||
if isinstance(lst, tuple):
|
||||
lst = list(lst)
|
||||
lst.sort()
|
||||
lst_ = []
|
||||
for l in lst[:-1]:
|
||||
if sys.version_info[0] < 3 and isinstance(l, unicode):
|
||||
l = l.encode('utf8')
|
||||
elif not isinstance(l, str):
|
||||
if not isinstance(l, str):
|
||||
l = str(l)
|
||||
lst_.append(l)
|
||||
last = lst[-1]
|
||||
if sys.version_info[0] < 3 and isinstance(last, unicode):
|
||||
last = last.encode('utf8')
|
||||
if not isinstance(last, str):
|
||||
last = str(last)
|
||||
return ', '.join(lst_) + _(' {} ').format(separator) + last
|
||||
return ', '.join(lst_) + _(' "{}" ').format(separator) + last
|
||||
|
||||
|
||||
# Exceptions for an Option
|
||||
|
@ -56,17 +56,10 @@ def validate_callback(callback,
|
||||
"""
|
||||
def _validate_option(option):
|
||||
#validate option
|
||||
#FIXME etrange ...
|
||||
if hasattr(option, 'impl_is_symlinkoption'):
|
||||
if option.impl_is_symlinkoption():
|
||||
cur_opt = option.impl_getopt()
|
||||
else:
|
||||
cur_opt = option
|
||||
if option.impl_is_symlinkoption():
|
||||
cur_opt = option.impl_getopt()
|
||||
else:
|
||||
raise ValueError(_('{}_params must have an option'
|
||||
' not a {} for first argument'
|
||||
).format(type_,
|
||||
type(option)))
|
||||
cur_opt = option
|
||||
if cur_opt != callbackoption:
|
||||
cur_opt._add_dependency(callbackoption)
|
||||
callbackoption._has_dependency = True
|
||||
@ -406,7 +399,7 @@ class BaseOption(Base):
|
||||
def _impl_valid_string(self,
|
||||
value):
|
||||
if not isinstance(value, str):
|
||||
return ValueError(_('invalid string'))
|
||||
raise ValueError(_('invalid string'))
|
||||
|
||||
def impl_get_display_name(self,
|
||||
dyn_name=None):
|
||||
@ -498,7 +491,7 @@ def validate_requires_arg(new_option,
|
||||
option = exp['option']
|
||||
option._add_dependency(new_option)
|
||||
if option is not None:
|
||||
err = option._validate(exp['value'])
|
||||
err = option._validate(exp['value'], undefined)
|
||||
if err:
|
||||
raise ValueError(_('malformed requirements expected value '
|
||||
'must be valid for option {0}'
|
||||
@ -513,7 +506,7 @@ def validate_requires_arg(new_option,
|
||||
else:
|
||||
option = get_option(require)
|
||||
if expected is not None:
|
||||
err = option._validate(expected)
|
||||
err = option._validate(expected, undefined)
|
||||
if err:
|
||||
raise ValueError(_('malformed requirements expected value '
|
||||
'must be valid for option {0}'
|
||||
|
@ -29,6 +29,10 @@ class BoolOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('boolean')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
if not isinstance(value, bool):
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
@ -30,26 +30,36 @@ class BroadcastOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('broadcast address')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
self._impl_valid_string(value)
|
||||
if value.count('.') != 3:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
for val in value.split('.'):
|
||||
if val.startswith("0") and len(val) > 1:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
try:
|
||||
IP('{0}/32'.format(value))
|
||||
except ValueError:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
||||
def _cons_broadcast(self, current_opt, opts, vals, warnings_only):
|
||||
def _cons_broadcast(self,
|
||||
current_opt,
|
||||
opts,
|
||||
vals,
|
||||
warnings_only):
|
||||
if len(vals) != 3:
|
||||
return ConfigError(_('invalid len for vals'))
|
||||
if None in vals:
|
||||
return
|
||||
broadcast, network, netmask = vals
|
||||
if IP('{0}/{1}'.format(network, netmask)).broadcast() != IP(broadcast):
|
||||
return ValueError(_('broadcast {4} invalid with network {0}/{1} ({2}/{3})').format(
|
||||
network, netmask, opts[1].impl_getname(), opts[2].impl_getname(), broadcast))
|
||||
raise ValueError(_('broadcast "{4}" invalid with network {0}/{1} ("{2}"/"{3}")'
|
||||
'').format(network,
|
||||
netmask,
|
||||
opts[1].impl_get_display_name(),
|
||||
opts[2].impl_get_display_name(),
|
||||
broadcast))
|
||||
|
@ -36,16 +36,30 @@ class ChoiceOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('choice')
|
||||
|
||||
def __init__(self, name, doc, values, default=None,
|
||||
values_params=None, default_multi=None, requires=None,
|
||||
multi=False, callback=None, callback_params=None,
|
||||
validator=None, validator_params=None,
|
||||
properties=None, warnings_only=False):
|
||||
def __init__(self,
|
||||
name,
|
||||
doc,
|
||||
values,
|
||||
default=None,
|
||||
values_params=None,
|
||||
default_multi=None,
|
||||
requires=None,
|
||||
multi=False,
|
||||
callback=None,
|
||||
callback_params=None,
|
||||
validator=None,
|
||||
validator_params=None,
|
||||
properties=None,
|
||||
warnings_only=False):
|
||||
|
||||
"""
|
||||
:param values: is a list of values the option can possibly take
|
||||
"""
|
||||
if isinstance(values, FunctionType):
|
||||
validate_callback(values, values_params, 'values', self)
|
||||
validate_callback(values,
|
||||
values_params,
|
||||
'values',
|
||||
self)
|
||||
else:
|
||||
if values_params is not None:
|
||||
raise ValueError(_('values is not a function, so values_params must be None'))
|
||||
@ -55,7 +69,9 @@ class ChoiceOption(Option):
|
||||
self._choice_values = values
|
||||
if values_params is not None:
|
||||
self._choice_values_params = values_params
|
||||
super(ChoiceOption, self).__init__(name, doc, default=default,
|
||||
super(ChoiceOption, self).__init__(name,
|
||||
doc,
|
||||
default=default,
|
||||
default_multi=default_multi,
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
@ -66,7 +82,10 @@ class ChoiceOption(Option):
|
||||
properties=properties,
|
||||
warnings_only=warnings_only)
|
||||
|
||||
def impl_get_values(self, context, current_opt=undefined):
|
||||
def impl_get_values(self,
|
||||
setting_properties,
|
||||
context,
|
||||
current_opt=undefined):
|
||||
if current_opt is undefined:
|
||||
current_opt = self
|
||||
#FIXME cache? but in context...
|
||||
@ -75,25 +94,29 @@ class ChoiceOption(Option):
|
||||
if context is None:
|
||||
values = []
|
||||
else:
|
||||
values = carry_out_calculation(current_opt, context=context,
|
||||
values = carry_out_calculation(current_opt,
|
||||
setting_properties=setting_properties,
|
||||
context=context,
|
||||
callback=values,
|
||||
callback_params=getattr(self, '_choice_values_params', {}))
|
||||
if isinstance(values, Exception):
|
||||
return values
|
||||
if values is not undefined and not isinstance(values, list):
|
||||
raise ConfigError(_('calculated values for {0} is not a list'
|
||||
'').format(self.impl_getname()))
|
||||
return values
|
||||
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
values = self.impl_get_values(context, current_opt=current_opt)
|
||||
if isinstance(values, Exception):
|
||||
return values
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
values = self.impl_get_values(setting_properties,
|
||||
context,
|
||||
current_opt=current_opt)
|
||||
if values is not undefined and not value in values:
|
||||
if len(values) == 1:
|
||||
return ValueError(_('only {0} is allowed'
|
||||
'').format(values[0]))
|
||||
raise ValueError(_('only {0} is allowed'
|
||||
'').format(values[0]))
|
||||
else:
|
||||
return ValueError(_('only {0} are allowed'
|
||||
'').format(display_list(values)))
|
||||
raise ValueError(_('only {0} are allowed'
|
||||
'').format(display_list(values)))
|
||||
|
@ -29,11 +29,13 @@ class DateOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('date')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
self._impl_valid_string(value)
|
||||
try:
|
||||
datetime.strptime(value, "%Y-%m-%d")
|
||||
except ValueError:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
@ -36,11 +36,23 @@ class DomainnameOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('domain name')
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, validator=None, validator_params=None,
|
||||
properties=None, allow_ip=False, type_='domainname',
|
||||
warnings_only=False, allow_without_dot=False):
|
||||
def __init__(self,
|
||||
name,
|
||||
doc,
|
||||
default=None,
|
||||
default_multi=None,
|
||||
requires=None,
|
||||
multi=False,
|
||||
callback=None,
|
||||
callback_params=None,
|
||||
validator=None,
|
||||
validator_params=None,
|
||||
properties=None,
|
||||
allow_ip=False,
|
||||
type_='domainname',
|
||||
warnings_only=False,
|
||||
allow_without_dot=False):
|
||||
|
||||
if type_ not in ['netbios', 'hostname', 'domainname']:
|
||||
raise ValueError(_('unknown type_ {0} for hostname').format(type_))
|
||||
extra = {'_dom_type': type_}
|
||||
@ -50,8 +62,6 @@ class DomainnameOption(Option):
|
||||
raise ValueError(_('allow_without_dot must be a boolean'))
|
||||
extra['_allow_ip'] = allow_ip
|
||||
extra['_allow_without_dot'] = allow_without_dot
|
||||
# FIXME should be
|
||||
# regexp = r'^((?!-)[a-z0-9-]{1,63}(?<!-)\.{0,1})$'
|
||||
if type_ == 'domainname':
|
||||
if allow_without_dot:
|
||||
min_time = 0
|
||||
@ -67,7 +77,9 @@ class DomainnameOption(Option):
|
||||
extra['_domain_re'] = re.compile(regexp)
|
||||
extra['_has_upper'] = re.compile('[A-Z]')
|
||||
|
||||
super(DomainnameOption, self).__init__(name, doc, default=default,
|
||||
super(DomainnameOption, self).__init__(name,
|
||||
doc,
|
||||
default=default,
|
||||
default_multi=default_multi,
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
@ -85,49 +97,50 @@ class DomainnameOption(Option):
|
||||
else:
|
||||
return 63
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
self._impl_valid_string(value)
|
||||
|
||||
def _valid_length(val):
|
||||
if len(val) < 1:
|
||||
return ValueError(_("invalid length (min 1)"))
|
||||
raise ValueError(_("invalid length (min 1)"))
|
||||
if len(val) > part_name_length:
|
||||
return ValueError(_("invalid length (max {0})"
|
||||
raise ValueError(_("invalid length (max {0})"
|
||||
"").format(part_name_length))
|
||||
|
||||
if self._get_extra('_allow_ip') is True:
|
||||
try:
|
||||
IP('{0}/32'.format(value))
|
||||
return
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return
|
||||
else:
|
||||
try:
|
||||
IP('{0}/32'.format(value))
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
return ValueError(_('must not be an IP'))
|
||||
raise ValueError(_('must not be an IP'))
|
||||
part_name_length = self._get_len(self._get_extra('_dom_type'))
|
||||
if self._get_extra('_dom_type') == 'domainname':
|
||||
if not self._get_extra('_allow_without_dot') and not "." in value:
|
||||
return ValueError(_("must have dot"))
|
||||
raise ValueError(_("must have dot"))
|
||||
if len(value) > 255:
|
||||
return ValueError(_("invalid length (max 255)"))
|
||||
raise ValueError(_("invalid length (max 255)"))
|
||||
for dom in value.split('.'):
|
||||
err = _valid_length(dom)
|
||||
if err:
|
||||
return err
|
||||
_valid_length(dom)
|
||||
else:
|
||||
return _valid_length(value)
|
||||
_valid_length(value)
|
||||
|
||||
def _second_level_validation(self, value, warnings_only):
|
||||
if self._get_extra('_has_upper').search(value):
|
||||
return ValueError(_('some characters are uppercase'))
|
||||
raise ValueError(_('some characters are uppercase'))
|
||||
if not self._get_extra('_domain_re').search(value):
|
||||
if warnings_only:
|
||||
return ValueError(_('some characters may cause problems'))
|
||||
raise ValueError(_('some characters may cause problems'))
|
||||
else:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
@ -29,6 +29,10 @@ class FloatOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('float')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
if not isinstance(value, float):
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
@ -29,6 +29,10 @@ class IntOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('integer')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
if not isinstance(value, int):
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
@ -31,14 +31,26 @@ class IPOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('IP')
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, validator=None, validator_params=None,
|
||||
properties=None, private_only=False, allow_reserved=False,
|
||||
def __init__(self,
|
||||
name,
|
||||
doc,
|
||||
default=None,
|
||||
default_multi=None,
|
||||
requires=None,
|
||||
multi=False,
|
||||
callback=None,
|
||||
callback_params=None,
|
||||
validator=None,
|
||||
validator_params=None,
|
||||
properties=None,
|
||||
private_only=False,
|
||||
allow_reserved=False,
|
||||
warnings_only=False):
|
||||
extra = {'_private_only': private_only,
|
||||
'_allow_reserved': allow_reserved}
|
||||
super(IPOption, self).__init__(name, doc, default=default,
|
||||
super(IPOption, self).__init__(name,
|
||||
doc,
|
||||
default=default,
|
||||
default_multi=default_multi,
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
@ -50,47 +62,62 @@ class IPOption(Option):
|
||||
warnings_only=warnings_only,
|
||||
extra=extra)
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
# sometimes an ip term starts with a zero
|
||||
# but this does not fit in some case, for example bind does not like it
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
self._impl_valid_string(value)
|
||||
if value.count('.') != 3:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
for val in value.split('.'):
|
||||
if val.startswith("0") and len(val) > 1:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
# 'standard' validation
|
||||
try:
|
||||
IP('{0}/32'.format(value))
|
||||
except ValueError:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
||||
def _second_level_validation(self, value, warnings_only):
|
||||
def _second_level_validation(self,
|
||||
value,
|
||||
warnings_only):
|
||||
ip = IP('{0}/32'.format(value))
|
||||
if not self._get_extra('_allow_reserved') and ip.iptype() == 'RESERVED':
|
||||
if warnings_only:
|
||||
msg = _("shouldn't in reserved class")
|
||||
else:
|
||||
msg = _("mustn't be in reserved class")
|
||||
return ValueError(msg)
|
||||
raise ValueError(msg)
|
||||
if self._get_extra('_private_only') and ip.iptype() != 'PRIVATE':
|
||||
if warnings_only:
|
||||
msg = _("should be in private class")
|
||||
else:
|
||||
msg = _("must be in private class")
|
||||
return ValueError(msg)
|
||||
raise ValueError(msg)
|
||||
|
||||
def _cons_in_network(self, current_opt, opts, vals, warnings_only):
|
||||
def _cons_in_network(self,
|
||||
current_opt,
|
||||
opts,
|
||||
vals,
|
||||
warnings_only):
|
||||
if len(vals) != 3:
|
||||
return ConfigError(_('invalid len for vals'))
|
||||
if None in vals:
|
||||
return
|
||||
ip, network, netmask = vals
|
||||
if IP(ip) not in IP('{0}/{1}'.format(network, netmask)):
|
||||
msg = _('{4} is not in network {0}/{1} ({2}/{3})')
|
||||
return ValueError(msg.format(network, netmask,
|
||||
opts[1].impl_getname(), opts[2].impl_getname(), ip))
|
||||
if IP(ip) not in IP('{0}/{1}'.format(network,
|
||||
netmask)):
|
||||
msg = _('"{4}" is not in network "{0}"/"{1}" ("{2}"/"{3}")')
|
||||
raise ValueError(msg.format(network,
|
||||
netmask,
|
||||
opts[1].impl_get_display_name(),
|
||||
opts[2].impl_getname(),
|
||||
ip))
|
||||
# test if ip is not network/broadcast IP
|
||||
return opts[2]._cons_ip_netmask(current_opt, (opts[2], opts[0]), (netmask, ip), warnings_only)
|
||||
opts[2]._cons_ip_netmask(current_opt,
|
||||
(opts[2], opts[0]),
|
||||
(netmask, ip),
|
||||
warnings_only)
|
||||
|
@ -175,7 +175,7 @@ class MasterSlaves(OptionDescription):
|
||||
context):
|
||||
if option.impl_is_master_slaves('master') and isinstance(value, list):
|
||||
if len(value) < context._impl_length:
|
||||
return ValueError(_('cannot reduce length of master "{}"'
|
||||
raise ValueError(_('cannot reduce length of master "{}"'
|
||||
'').format(option.impl_get_display_name()))
|
||||
|
||||
def is_masterslaves(self):
|
||||
|
@ -31,50 +31,72 @@ class NetmaskOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('netmask address')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
self._impl_valid_string(value)
|
||||
if value.count('.') != 3:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
for val in value.split('.'):
|
||||
if val.startswith("0") and len(val) > 1:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
try:
|
||||
IP('0.0.0.0/{0}'.format(value))
|
||||
except ValueError:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
||||
def _cons_network_netmask(self, current_opt, opts, vals, warnings_only):
|
||||
def _cons_network_netmask(self,
|
||||
current_opt,
|
||||
opts,
|
||||
vals,
|
||||
warnings_only):
|
||||
#opts must be (netmask, network) options
|
||||
if None in vals:
|
||||
return
|
||||
return self.__cons_netmask(opts, vals[0], vals[1], False, warnings_only)
|
||||
return self.__cons_netmask(opts,
|
||||
vals[0],
|
||||
vals[1],
|
||||
False,
|
||||
warnings_only)
|
||||
|
||||
def _cons_ip_netmask(self, current_opt, opts, vals, warnings_only):
|
||||
def _cons_ip_netmask(self,
|
||||
current_opt,
|
||||
opts,
|
||||
vals,
|
||||
warnings_only):
|
||||
#opts must be (netmask, ip) options
|
||||
if None in vals:
|
||||
return
|
||||
return self.__cons_netmask(opts, vals[0], vals[1], True, warnings_only)
|
||||
self.__cons_netmask(opts,
|
||||
vals[0],
|
||||
vals[1],
|
||||
True,
|
||||
warnings_only)
|
||||
|
||||
def __cons_netmask(self, opts, val_netmask, val_ipnetwork, make_net,
|
||||
def __cons_netmask(self,
|
||||
opts,
|
||||
val_netmask,
|
||||
val_ipnetwork,
|
||||
make_net,
|
||||
warnings_only):
|
||||
if len(opts) != 2:
|
||||
return ConfigError(_('invalid len for opts'))
|
||||
msg = None
|
||||
try:
|
||||
ip = IP('{0}/{1}'.format(val_ipnetwork, val_netmask),
|
||||
make_net=make_net)
|
||||
ip = IP('{0}/{1}'.format(val_ipnetwork, val_netmask), make_net=make_net)
|
||||
#if cidr == 32, ip same has network
|
||||
if make_net and ip.prefixlen() != 32:
|
||||
val_ip = IP(val_ipnetwork)
|
||||
if ip.net() == val_ip:
|
||||
msg = _("this is a network with netmask {0} ({1})")
|
||||
msg = _('this is a network with netmask "{0}" ("{1}")')
|
||||
if ip.broadcast() == val_ip:
|
||||
msg = _("this is a broadcast with netmask {0} ({1})")
|
||||
msg = _('this is a broadcast with netmask "{0}" ("{1}")')
|
||||
|
||||
except ValueError:
|
||||
if not make_net:
|
||||
msg = _('with netmask {0} ({1})')
|
||||
msg = _('with netmask "{0}" ("{1}")')
|
||||
if msg is not None:
|
||||
return ValueError(msg.format(val_netmask, opts[1].impl_getname()))
|
||||
raise ValueError(msg.format(val_netmask,
|
||||
opts[1].impl_get_diplay_name()))
|
||||
|
@ -30,25 +30,29 @@ class NetworkOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('network address')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
self._impl_valid_string(value)
|
||||
if value.count('.') != 3:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
for val in value.split('.'):
|
||||
if val.startswith("0") and len(val) > 1:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
try:
|
||||
IP(value)
|
||||
except ValueError:
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
||||
def _second_level_validation(self, value, warnings_only):
|
||||
def _second_level_validation(self,
|
||||
value,
|
||||
warnings_only):
|
||||
ip = IP(value)
|
||||
if ip.iptype() == 'RESERVED':
|
||||
if warnings_only:
|
||||
msg = _("shouldn't be in reserved class")
|
||||
else:
|
||||
msg = _("mustn't be in reserved class")
|
||||
return ValueError(msg)
|
||||
raise ValueError(msg)
|
||||
|
@ -133,7 +133,8 @@ class Option(OnlyOption):
|
||||
is_multi=is_multi)
|
||||
if is_multi and default_multi is not None:
|
||||
def test_multi_value(value):
|
||||
err = self._validate(value)
|
||||
err = self._validate(value,
|
||||
undefined)
|
||||
if err:
|
||||
raise ValueError(_("invalid default_multi value {0} "
|
||||
"for option {1}: {2}").format(str(value),
|
||||
@ -152,10 +153,8 @@ class Option(OnlyOption):
|
||||
_setattr(self, '_default_multi', default_multi)
|
||||
if unique is not undefined:
|
||||
_setattr(self, '_unique', unique)
|
||||
err = self.impl_validate(default,
|
||||
is_multi=is_multi)
|
||||
if err:
|
||||
raise err
|
||||
self.impl_validate(default,
|
||||
is_multi=is_multi)
|
||||
if (is_multi and default != []) or \
|
||||
(not is_multi and default is not None):
|
||||
if is_multi:
|
||||
@ -300,8 +299,7 @@ class Option(OnlyOption):
|
||||
force_index=None,
|
||||
current_opt=undefined,
|
||||
is_multi=None,
|
||||
display_error=True,
|
||||
display_warnings=True,
|
||||
check_error=True,
|
||||
multi=None,
|
||||
setting_properties=undefined):
|
||||
"""
|
||||
@ -315,14 +313,13 @@ class Option(OnlyOption):
|
||||
"""
|
||||
if current_opt is undefined:
|
||||
current_opt = self
|
||||
|
||||
if display_warnings and setting_properties is undefined and context is not undefined:
|
||||
setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=False)
|
||||
display_warnings = display_warnings and (setting_properties is undefined or 'warnings' in setting_properties)
|
||||
|
||||
if check_error is False and not 'warnings' in setting_properties:
|
||||
return
|
||||
|
||||
def _is_not_unique(value):
|
||||
#FIXME pourquoi la longueur doit etre egal ???
|
||||
if display_error and self.impl_is_unique() and len(set(value)) != len(value):
|
||||
if check_error and self.impl_is_unique() and len(set(value)) != len(value):
|
||||
for idx, val in enumerate(value):
|
||||
if val in value[idx+1:]:
|
||||
raise ValueError(_('invalid value "{}", this value is already in "{}"'
|
||||
@ -361,16 +358,18 @@ class Option(OnlyOption):
|
||||
raise ValueError(_('invalid value "{}" for "{}" '
|
||||
'which must not be a list').format(_value,
|
||||
self.impl_get_display_name()))
|
||||
#FIXME a revoir ...
|
||||
is_warnings_only = getattr(self, '_warnings_only', False)
|
||||
try:
|
||||
if _value is not None:
|
||||
if display_error:
|
||||
if check_error:
|
||||
# option validation
|
||||
self._validate(_value,
|
||||
setting_properties,
|
||||
context,
|
||||
current_opt)
|
||||
if ((display_error and not is_warnings_only) or
|
||||
(display_warnings and is_warnings_only)):
|
||||
if ((check_error and not is_warnings_only) or
|
||||
(not check_error and is_warnings_only)):
|
||||
calculation_validator(_value,
|
||||
_index)
|
||||
self._second_level_validation(_value,
|
||||
@ -379,8 +378,7 @@ class Option(OnlyOption):
|
||||
_value,
|
||||
context,
|
||||
_index,
|
||||
display_warnings,
|
||||
display_error,
|
||||
check_error,
|
||||
setting_properties)
|
||||
except ValueError as err:
|
||||
if debug: # pragma: no cover
|
||||
@ -402,12 +400,12 @@ class Option(OnlyOption):
|
||||
err_msg = '{0}'.format(err)
|
||||
if err_msg:
|
||||
msg += ', {}'.format(err_msg)
|
||||
if is_warnings_only:
|
||||
if check_error:
|
||||
raise ValueError(msg)
|
||||
else:
|
||||
warnings.warn_explicit(ValueWarning(msg, self),
|
||||
ValueWarning,
|
||||
self.__class__.__name__, 0)
|
||||
else:
|
||||
raise ValueError(msg)
|
||||
|
||||
if is_multi is None:
|
||||
is_multi = self.impl_is_multi()
|
||||
@ -563,10 +561,10 @@ class Option(OnlyOption):
|
||||
all_cons_opts,
|
||||
params)
|
||||
#validate default value when add consistency
|
||||
err = self.impl_validate(self.impl_getdefault())
|
||||
if err:
|
||||
self._del_consistency()
|
||||
raise err
|
||||
self.impl_validate(self.impl_getdefault())
|
||||
#FIXME
|
||||
#if err:
|
||||
# self._del_consistency()
|
||||
if func != '_cons_not_equal':
|
||||
#consistency could generate warnings or errors
|
||||
self._has_dependency = True
|
||||
@ -584,8 +582,7 @@ class Option(OnlyOption):
|
||||
value,
|
||||
context,
|
||||
index,
|
||||
display_warnings,
|
||||
display_error,
|
||||
check_error,
|
||||
setting_properties):
|
||||
if context is not undefined:
|
||||
descr = context.cfgimpl_get_description()
|
||||
@ -601,7 +598,7 @@ class Option(OnlyOption):
|
||||
if consistencies is not None:
|
||||
for func, all_cons_opts, params in consistencies:
|
||||
warnings_only = params.get('warnings_only', False)
|
||||
if (warnings_only and display_warnings) or (not warnings_only and display_error):
|
||||
if (warnings_only and not check_error) or (not warnings_only and check_error):
|
||||
transitive = params.get('transitive', True)
|
||||
#all_cons_opts[0] is the option where func is set
|
||||
if isinstance(option, DynSymLinkOption):
|
||||
@ -745,6 +742,7 @@ class RegexpOption(Option):
|
||||
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
|
@ -99,7 +99,7 @@ class CacheOptionDescription(BaseOption):
|
||||
params))
|
||||
# if context is set to callback, must be reset each time a value change
|
||||
if hasattr(option, '_has_calc_context'):
|
||||
_dependencies.append(option)
|
||||
self._add_dependency(option)
|
||||
is_slave = None
|
||||
if is_multi:
|
||||
all_requires = option.impl_getrequires()
|
||||
@ -150,10 +150,10 @@ class CacheOptionDescription(BaseOption):
|
||||
return False
|
||||
|
||||
def impl_build_force_store_values(self,
|
||||
config,
|
||||
context,
|
||||
force_store_values):
|
||||
session = config._impl_values._p_.getsession()
|
||||
value_set = False
|
||||
value_setted = False
|
||||
values = context.cfgimpl_get_values()
|
||||
for subpath, option in self._cache_force_store_values:
|
||||
if option.impl_is_master_slaves('slave'):
|
||||
# problem with index
|
||||
@ -162,19 +162,24 @@ class CacheOptionDescription(BaseOption):
|
||||
if option._is_subdyn():
|
||||
raise ConfigError(_('a dynoption ({0}) cannot have '
|
||||
'force_store_value property').format(subpath))
|
||||
if force_store_values and not config._impl_values._p_.hasvalue(subpath, session):
|
||||
value = impl_build_force_store_values.getvalue(option,
|
||||
subpath,
|
||||
index=None,
|
||||
setting_properties=undefined,
|
||||
self_properties=undefined,
|
||||
validate=False)
|
||||
value_set = True
|
||||
config._impl_values._p_.setvalue(subpath, value,
|
||||
owners.forced, None, session, False)
|
||||
if force_store_values is False:
|
||||
raise Exception('ok ca existe ...')
|
||||
if force_store_values and not values._p_.hasvalue(subpath):
|
||||
value = values.getvalue(option,
|
||||
subpath,
|
||||
index=None,
|
||||
setting_properties=None,
|
||||
self_properties=None,
|
||||
validate=False)
|
||||
value_setted = True
|
||||
values._p_.setvalue(subpath,
|
||||
value,
|
||||
owners.forced,
|
||||
None,
|
||||
False)
|
||||
|
||||
if value_set:
|
||||
config._impl_values._p_.commit()
|
||||
if value_setted:
|
||||
values._p_.commit()
|
||||
|
||||
def _build_cache_option(self,
|
||||
_currpath=None,
|
||||
|
@ -29,7 +29,9 @@ class PasswordOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('password')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
self._impl_valid_string(value)
|
||||
|
@ -40,12 +40,25 @@ class PortOption(Option):
|
||||
port_re = re.compile(r"^[0-9]*$")
|
||||
_display_name = _('port')
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
callback_params=None, validator=None, validator_params=None,
|
||||
properties=None, allow_range=False, allow_zero=False,
|
||||
allow_wellknown=True, allow_registred=True,
|
||||
allow_private=False, warnings_only=False):
|
||||
def __init__(self,
|
||||
name,
|
||||
doc,
|
||||
default=None,
|
||||
default_multi=None,
|
||||
requires=None,
|
||||
multi=False,
|
||||
callback=None,
|
||||
callback_params=None,
|
||||
validator=None,
|
||||
validator_params=None,
|
||||
properties=None,
|
||||
allow_range=False,
|
||||
allow_zero=False,
|
||||
allow_wellknown=True,
|
||||
allow_registred=True,
|
||||
allow_private=False,
|
||||
warnings_only=False):
|
||||
|
||||
extra = {'_allow_range': allow_range,
|
||||
'_min_value': None,
|
||||
'_max_value': None}
|
||||
@ -69,7 +82,9 @@ class PortOption(Option):
|
||||
if extra['_max_value'] is None:
|
||||
raise ValueError(_('max value is empty'))
|
||||
|
||||
super(PortOption, self).__init__(name, doc, default=default,
|
||||
super(PortOption, self).__init__(name,
|
||||
doc,
|
||||
default=default,
|
||||
default_multi=default_multi,
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
@ -81,30 +96,29 @@ class PortOption(Option):
|
||||
warnings_only=warnings_only,
|
||||
extra=extra)
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
if isinstance(value, int):
|
||||
if sys.version_info[0] >= 3: # pragma: no cover
|
||||
value = str(value)
|
||||
else:
|
||||
value = unicode(value)
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
value = str(value)
|
||||
self._impl_valid_string(value)
|
||||
if self._get_extra('_allow_range') and ":" in str(value):
|
||||
value = str(value).split(':')
|
||||
if len(value) != 2:
|
||||
return ValueError(_('range must have two values only'))
|
||||
raise ValueError(_('range must have two values only'))
|
||||
if not value[0] < value[1]:
|
||||
return ValueError(_('first port in range must be'
|
||||
' smaller than the second one'))
|
||||
raise ValueError(_('first port in range must be'
|
||||
' smaller than the second one'))
|
||||
else:
|
||||
value = [value]
|
||||
|
||||
for val in value:
|
||||
if not self.port_re.search(val):
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
val = int(val)
|
||||
if not self._get_extra('_min_value') <= val <= self._get_extra('_max_value'):
|
||||
return ValueError(_('must be an integer between {0} '
|
||||
'and {1}').format(self._get_extra('_min_value'),
|
||||
self._get_extra('_max_value')))
|
||||
raise ValueError(_('must be an integer between {0} '
|
||||
'and {1}').format(self._get_extra('_min_value'),
|
||||
self._get_extra('_max_value')))
|
||||
|
@ -30,23 +30,16 @@ class StrOption(Option):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('string')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
if not isinstance(value, str):
|
||||
return ValueError()
|
||||
raise ValueError()
|
||||
|
||||
|
||||
if sys.version_info[0] >= 3: # pragma: no cover
|
||||
#UnicodeOption is same as StrOption in python 3+
|
||||
class UnicodeOption(StrOption):
|
||||
__slots__ = tuple()
|
||||
pass
|
||||
else:
|
||||
class UnicodeOption(Option):
|
||||
"represents the choice of a unicode string"
|
||||
__slots__ = tuple()
|
||||
_empty = u''
|
||||
_display_name = _('unicode string')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
if not isinstance(value, unicode):
|
||||
return ValueError()
|
||||
#UnicodeOption is same as StrOption in python 3+
|
||||
class UnicodeOption(StrOption):
|
||||
__slots__ = tuple()
|
||||
_display_name = _('unicode')
|
||||
|
@ -38,6 +38,10 @@ class SymLinkOption(OnlyOption):
|
||||
_setattr(self, '_opt', opt)
|
||||
opt._add_dependency(self)
|
||||
|
||||
def __getattr__(self,
|
||||
name):
|
||||
return getattr(self._opt, name)
|
||||
|
||||
def impl_has_dependency(self, self_is_dep=True):
|
||||
"""If self_is_dep is True, it has dependency (self._opt), so return True
|
||||
if self_is_dep is False, cannot has validation or callback, so return False
|
||||
@ -47,37 +51,32 @@ class SymLinkOption(OnlyOption):
|
||||
def impl_is_symlinkoption(self):
|
||||
return True
|
||||
|
||||
def __getattr__(self,
|
||||
name,
|
||||
context=undefined):
|
||||
return getattr(self.impl_getopt(), name)
|
||||
|
||||
def impl_getopt(self):
|
||||
return self._opt
|
||||
|
||||
def impl_get_information(self,
|
||||
key,
|
||||
default=undefined):
|
||||
return self.impl_getopt().impl_get_information(key, default)
|
||||
#def impl_get_information(self,
|
||||
# key,
|
||||
# default=undefined):
|
||||
# return self._opt.impl_get_information(key, default)
|
||||
|
||||
def impl_is_readonly(self):
|
||||
return True
|
||||
|
||||
def impl_getproperties(self):
|
||||
return self.impl_getopt().impl_getproperties()
|
||||
#def impl_getproperties(self):
|
||||
# return self._opt.impl_getproperties()
|
||||
|
||||
def impl_get_callback(self):
|
||||
return self.impl_getopt().impl_get_callback()
|
||||
#def impl_get_callback(self):
|
||||
# return self._opt.impl_get_callback()
|
||||
|
||||
def impl_has_callback(self):
|
||||
"to know if a callback has been defined or not"
|
||||
return self.impl_getopt().impl_has_callback()
|
||||
#def impl_has_callback(self):
|
||||
# "to know if a callback has been defined or not"
|
||||
# return self._opt.impl_has_callback()
|
||||
|
||||
def impl_is_multi(self):
|
||||
return self.impl_getopt().impl_is_multi()
|
||||
#def impl_is_multi(self):
|
||||
# return self._opt.impl_is_multi()
|
||||
|
||||
def _is_subdyn(self):
|
||||
return getattr(self.impl_getopt(), '_subdyn', None) is not None
|
||||
#def _is_subdyn(self):
|
||||
# return getattr(self._opt, '_subdyn', None) is not None
|
||||
|
||||
def _get_consistencies(self):
|
||||
return ()
|
||||
@ -100,15 +99,14 @@ class DynSymLinkOption(object):
|
||||
self._suffix = suffix
|
||||
|
||||
def __getattr__(self,
|
||||
name,
|
||||
context=undefined):
|
||||
return getattr(self.impl_getopt(), name)
|
||||
name):
|
||||
return getattr(self._opt, name)
|
||||
|
||||
def impl_getname(self):
|
||||
return self._opt.impl_getname() + self._suffix
|
||||
|
||||
def impl_get_display_name(self):
|
||||
return self.impl_getopt().impl_get_display_name(dyn_name=self.impl_getname())
|
||||
return self._opt.impl_get_display_name(dyn_name=self.impl_getname())
|
||||
|
||||
def impl_getopt(self):
|
||||
return self._opt
|
||||
@ -125,23 +123,20 @@ class DynSymLinkOption(object):
|
||||
def impl_validate(self,
|
||||
value,
|
||||
context=undefined,
|
||||
validate=True,
|
||||
force_index=None,
|
||||
is_multi=None,
|
||||
display_error=True,
|
||||
display_warnings=True,
|
||||
check_error=True,
|
||||
multi=None,
|
||||
setting_properties=undefined):
|
||||
return self.impl_getopt().impl_validate(value,
|
||||
context,
|
||||
validate,
|
||||
force_index,
|
||||
current_opt=self,
|
||||
is_multi=is_multi,
|
||||
display_error=display_error,
|
||||
display_warnings=display_warnings,
|
||||
multi=multi,
|
||||
setting_properties=setting_properties)
|
||||
# add current_opt !
|
||||
self._opt.impl_validate(value,
|
||||
context,
|
||||
force_index,
|
||||
current_opt=self,
|
||||
is_multi=is_multi,
|
||||
check_error=check_error,
|
||||
multi=multi,
|
||||
setting_properties=setting_properties)
|
||||
|
||||
def impl_is_dynsymlinkoption(self):
|
||||
return True
|
||||
|
@ -40,16 +40,23 @@ class SynDynOptionDescription(object):
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._opt, name)
|
||||
|
||||
def impl_getopt(self):
|
||||
return self._opt
|
||||
|
||||
def impl_getchild(self,
|
||||
name,
|
||||
setting_properties,
|
||||
subconfig):
|
||||
if name.endswith(self._suffix):
|
||||
oname = name[:-len(self._suffix)]
|
||||
child = self._children[1][self._children[0].index(oname)]
|
||||
return self._impl_get_dynchild(child,
|
||||
self._suffix,
|
||||
subconfig.cfgimpl_get_path())
|
||||
try:
|
||||
if name.endswith(self._suffix):
|
||||
oname = name[:-len(self._suffix)]
|
||||
child = self._children[1][self._children[0].index(oname)]
|
||||
return self._impl_get_dynchild(child,
|
||||
self._suffix,
|
||||
subconfig.cfgimpl_get_path())
|
||||
except ValueError:
|
||||
# when oname not in self._children
|
||||
pass
|
||||
raise AttributeError(_('unknown Option {0} '
|
||||
'in SynDynOptionDescription {1}'
|
||||
'').format(name, self.impl_getname()))
|
||||
|
@ -32,13 +32,15 @@ class URLOption(DomainnameOption):
|
||||
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
|
||||
_display_name = _('URL')
|
||||
|
||||
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||
err = self._impl_valid_string(value)
|
||||
if err:
|
||||
return err
|
||||
def _validate(self,
|
||||
value,
|
||||
setting_properties,
|
||||
context=undefined,
|
||||
current_opt=undefined):
|
||||
self._impl_valid_string(value)
|
||||
match = self.proto_re.search(value)
|
||||
if not match:
|
||||
return ValueError(_('must start with http:// or '
|
||||
raise ValueError(_('must start with http:// or '
|
||||
'https://'))
|
||||
value = value[len(match.group(0)):]
|
||||
# get domain/files
|
||||
@ -56,18 +58,17 @@ class URLOption(DomainnameOption):
|
||||
else:
|
||||
domain, port = splitted
|
||||
if not 0 <= int(port) <= 65535:
|
||||
return ValueError(_('port must be an between 0 and '
|
||||
raise ValueError(_('port must be an between 0 and '
|
||||
'65536'))
|
||||
# validate domainname
|
||||
err = super(URLOption, self)._validate(domain)
|
||||
if err:
|
||||
return err
|
||||
err = super(URLOption, self)._second_level_validation(domain, False)
|
||||
if err:
|
||||
return err
|
||||
super(URLOption, self)._validate(domain,
|
||||
setting_properties,
|
||||
context,
|
||||
current_opt)
|
||||
super(URLOption, self)._second_level_validation(domain, False)
|
||||
# validate file
|
||||
if files is not None and files != '' and not self.path_re.search(files):
|
||||
return ValueError(_('must ends with a valid resource name'))
|
||||
raise ValueError(_('must ends with a valid resource name'))
|
||||
|
||||
def _second_level_validation(self, value, warnings_only):
|
||||
pass
|
||||
|
@ -349,10 +349,10 @@ class Settings(object):
|
||||
opt = opt.impl_getopt()
|
||||
path = opt.impl_getpath(self._getcontext())
|
||||
meta = self._getcontext().cfgimpl_get_meta()
|
||||
if meta is None:
|
||||
return self._pp_.getpermissive(path)
|
||||
return meta.cfgimpl_get_settings().getpermissive(opt,
|
||||
path)
|
||||
if meta is not None:
|
||||
return meta.cfgimpl_get_settings().getpermissive(opt,
|
||||
path)
|
||||
return self._pp_.getpermissive(path)
|
||||
|
||||
def apply_requires(self,
|
||||
opt,
|
||||
@ -589,6 +589,7 @@ class Settings(object):
|
||||
opt,
|
||||
path,
|
||||
setting_properties,
|
||||
self_properties=undefined,
|
||||
index=None,
|
||||
force_permissive=False):
|
||||
"""
|
||||
@ -599,10 +600,11 @@ class Settings(object):
|
||||
was present
|
||||
"""
|
||||
# opt properties
|
||||
self_properties = self.getproperties(opt,
|
||||
path,
|
||||
setting_properties=setting_properties,
|
||||
index=index)
|
||||
if self_properties is undefined:
|
||||
self_properties = self.getproperties(opt,
|
||||
path,
|
||||
setting_properties=setting_properties,
|
||||
index=index)
|
||||
|
||||
# calc properties
|
||||
properties = self_properties & setting_properties - set(['frozen'])
|
||||
@ -612,7 +614,7 @@ class Settings(object):
|
||||
value = self._getcontext().cfgimpl_get_values().get_cached_value(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
validate=False,
|
||||
validate=True,
|
||||
self_properties=self_properties,
|
||||
index=index)
|
||||
if not self.validate_mandatory(opt,
|
||||
@ -663,6 +665,10 @@ class Settings(object):
|
||||
force_allow_empty_list=True,
|
||||
index=index))
|
||||
|
||||
def validate_frozen(self,
|
||||
setting_properties,
|
||||
self_properties):
|
||||
return 'everything_frozen' in setting_properties or 'frozen' in self_properties
|
||||
#____________________________________________________________
|
||||
# read only/read write
|
||||
|
||||
|
@ -90,15 +90,14 @@ class Values(object):
|
||||
"""
|
||||
ntime = None
|
||||
# try to retrive value in cache
|
||||
if 'cache' in setting_properties and self._p_.hascache(path,
|
||||
index):
|
||||
if setting_properties and 'cache' in setting_properties and \
|
||||
self._p_.hascache(path,
|
||||
index):
|
||||
if 'expire' in setting_properties:
|
||||
ntime = int(time())
|
||||
is_cached, value = self._p_.getcache(path,
|
||||
ntime,
|
||||
None)
|
||||
if index:
|
||||
value = value[index]
|
||||
index)
|
||||
if is_cached:
|
||||
return value
|
||||
|
||||
@ -120,15 +119,14 @@ class Values(object):
|
||||
validate,
|
||||
force_permissive=force_permissive)
|
||||
# store value in cache
|
||||
#FIXME pas de cache pour les slaves !!!
|
||||
if index is None and 'cache' in setting_properties and \
|
||||
if setting_properties and 'cache' in setting_properties and \
|
||||
validate and force_permissive is False \
|
||||
and trusted_cached_properties is True:
|
||||
if 'expire' in setting_properties:
|
||||
if ntime is None:
|
||||
ntime = int(time())
|
||||
ntime = ntime + expires_time
|
||||
self._p_.setcache(path, value, ntime, None)
|
||||
self._p_.setcache(path, value, ntime, index)
|
||||
# and return it
|
||||
return value
|
||||
|
||||
@ -164,15 +162,13 @@ class Values(object):
|
||||
opt.impl_validate(value,
|
||||
context,
|
||||
force_index=index,
|
||||
display_error=True,
|
||||
display_warnings=False,
|
||||
check_error=True,
|
||||
setting_properties=setting_properties)
|
||||
if display_warnings:
|
||||
opt.impl_validate(value,
|
||||
context,
|
||||
force_index=index,
|
||||
display_error=False,
|
||||
display_warnings=display_warnings,
|
||||
check_error=False,
|
||||
setting_properties=setting_properties)
|
||||
return value
|
||||
|
||||
@ -411,12 +407,11 @@ class Values(object):
|
||||
else:
|
||||
tested_context = context
|
||||
tested_values = self
|
||||
tested_values.validate_setitem(opt,
|
||||
value,
|
||||
path,
|
||||
force_permissive,
|
||||
setting_properties,
|
||||
index)
|
||||
tested_values.setvalue_validation(opt,
|
||||
value,
|
||||
path,
|
||||
setting_properties,
|
||||
index)
|
||||
|
||||
self._setvalue(opt,
|
||||
path,
|
||||
@ -425,22 +420,22 @@ class Values(object):
|
||||
index=index,
|
||||
commit=_commit)
|
||||
|
||||
def validate_setitem(self,
|
||||
opt,
|
||||
value,
|
||||
path,
|
||||
force_permissive,
|
||||
setting_properties,
|
||||
index):
|
||||
def setvalue_validation(self,
|
||||
opt,
|
||||
value,
|
||||
path,
|
||||
setting_properties,
|
||||
index):
|
||||
|
||||
context = self._getcontext()
|
||||
settings = context.cfgimpl_get_settings()
|
||||
# First validate properties with this value
|
||||
properties = settings.getproperties(opt,
|
||||
path,
|
||||
setting_properties=setting_properties,
|
||||
index=index)
|
||||
if 'everything_frozen' in setting_properties or 'frozen' in properties:
|
||||
self_properties = settings.getproperties(opt,
|
||||
path,
|
||||
setting_properties=setting_properties,
|
||||
index=index)
|
||||
if settings.validate_frozen(setting_properties,
|
||||
self_properties):
|
||||
datas = {'opt': opt,
|
||||
'path': path,
|
||||
'setting_properties': setting_properties,
|
||||
@ -455,7 +450,7 @@ class Values(object):
|
||||
index,
|
||||
value,
|
||||
setting_properties,
|
||||
properties):
|
||||
self_properties):
|
||||
datas = {'opt': opt,
|
||||
'path': path,
|
||||
'setting_properties': setting_properties,
|
||||
@ -469,13 +464,13 @@ class Values(object):
|
||||
# Value must be valid for option
|
||||
opt.impl_validate(value,
|
||||
context,
|
||||
display_warnings=False,
|
||||
check_error=True,
|
||||
force_index=index,
|
||||
setting_properties=setting_properties)
|
||||
# No error found so emit warnings
|
||||
opt.impl_validate(value,
|
||||
context,
|
||||
display_error=False,
|
||||
check_error=False,
|
||||
force_index=index,
|
||||
setting_properties=setting_properties)
|
||||
|
||||
@ -602,6 +597,7 @@ class Values(object):
|
||||
opt,
|
||||
path,
|
||||
owner,
|
||||
setting_properties,
|
||||
index=None):
|
||||
"""
|
||||
sets a owner to an option
|
||||
@ -621,6 +617,10 @@ class Values(object):
|
||||
if not self._p_.hasvalue(path):
|
||||
raise ConfigError(_('no value for {0} cannot change owner to {1}'
|
||||
'').format(path, owner))
|
||||
self.setowner_validation(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
index)
|
||||
self._p_.setowner(path, owner, index=index)
|
||||
|
||||
def is_default_owner(self,
|
||||
@ -663,12 +663,16 @@ class Values(object):
|
||||
path,
|
||||
setting_properties,
|
||||
validate=False)
|
||||
#FIXME ce n'est pas deja fait dans le reset ?
|
||||
#sinon c'est un validate_properties qu'il faut faire ...
|
||||
#fake_value.get_cached_value(opt,
|
||||
# path,
|
||||
# setting_properties=setting_properties,
|
||||
# force_permissive=force_permissive)
|
||||
value = fake_value._getdefaultvalue(opt,
|
||||
path,
|
||||
None,
|
||||
validate,
|
||||
setting_properties)
|
||||
fake_value.setvalue_validation(opt,
|
||||
value,
|
||||
path,
|
||||
setting_properties,
|
||||
None)
|
||||
if opt.impl_is_master_slaves('master'):
|
||||
opt.impl_get_master_slaves().reset(opt,
|
||||
self,
|
||||
@ -714,11 +718,16 @@ class Values(object):
|
||||
index,
|
||||
setting_properties,
|
||||
validate=False)
|
||||
fake_value.get_cached_value(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
index=index,
|
||||
force_permissive=force_permissive)
|
||||
value = fake_value._getdefaultvalue(opt,
|
||||
path,
|
||||
index,
|
||||
validate,
|
||||
setting_properties)
|
||||
fake_value.setvalue_validation(opt,
|
||||
value,
|
||||
path,
|
||||
setting_properties,
|
||||
index)
|
||||
self._p_.resetvalue_index(path, index)
|
||||
|
||||
def reset_master(self,
|
||||
@ -746,6 +755,33 @@ class Values(object):
|
||||
setting_properties,
|
||||
force_permissive)
|
||||
|
||||
|
||||
def setowner_validation(self,
|
||||
opt,
|
||||
path,
|
||||
setting_properties,
|
||||
index):
|
||||
|
||||
context = self._getcontext()
|
||||
settings = context.cfgimpl_get_settings()
|
||||
# First validate properties with this value
|
||||
self_properties = settings.getproperties(opt,
|
||||
path,
|
||||
setting_properties=setting_properties,
|
||||
index=index)
|
||||
if settings.validate_frozen(setting_properties,
|
||||
self_properties):
|
||||
datas = {'opt': opt,
|
||||
'path': path,
|
||||
'setting_properties': setting_properties,
|
||||
'index': index,
|
||||
'debug': True}
|
||||
raise PropertiesOptionError(None,
|
||||
['frozen'],
|
||||
settings,
|
||||
datas,
|
||||
'option')
|
||||
|
||||
#______________________________________________________________________
|
||||
# information
|
||||
|
||||
@ -771,7 +807,7 @@ class Values(object):
|
||||
# mandatory warnings
|
||||
|
||||
def mandatory_warnings(self,
|
||||
force_permissive=True):
|
||||
setting_properties):
|
||||
"""convenience function to trace Options that are mandatory and
|
||||
where no value has been set
|
||||
|
||||
@ -779,65 +815,82 @@ class Values(object):
|
||||
"""
|
||||
context = self._getcontext()
|
||||
settings = context.cfgimpl_get_settings()
|
||||
setting_properties = context.cfgimpl_get_settings().get_context_properties()
|
||||
# copy
|
||||
setting_properties = set(setting_properties)
|
||||
setting_properties.update(['mandatory', 'empty'])
|
||||
def _is_properties_option(err, path):
|
||||
#FIXME hum ...
|
||||
if not isinstance(err, Exception):
|
||||
pass
|
||||
elif isinstance(err, PropertiesOptionError):
|
||||
if err.proptype == ['mandatory']:
|
||||
return path
|
||||
elif isinstance(err, ConfigError):
|
||||
#assume that uncalculated value is an empty value
|
||||
return path
|
||||
else:
|
||||
raise err
|
||||
|
||||
def _mandatory_warnings(description, currpath=None):
|
||||
if currpath is None:
|
||||
currpath = []
|
||||
for opt in description._impl_getchildren(context=context):
|
||||
def _mandatory_warnings(description, currpath):
|
||||
is_masterslaves = description.is_masterslaves()
|
||||
lenmaster = None
|
||||
for opt in description.impl_getchildren(context=context,
|
||||
setting_properties=setting_properties):
|
||||
name = opt.impl_getname()
|
||||
path = '.'.join(currpath + [name])
|
||||
|
||||
if opt.impl_is_optiondescription():
|
||||
#FIXME ?
|
||||
if not settings.validate_properties(opt,
|
||||
True,
|
||||
False,
|
||||
path=path,
|
||||
force_permissive=True,
|
||||
setting_properties=setting_properties):
|
||||
try:
|
||||
settings.validate_properties(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
force_permissive=True)
|
||||
for path in _mandatory_warnings(opt,
|
||||
currpath + [name]):
|
||||
yield path
|
||||
else:
|
||||
if opt.impl_is_symlinkoption():
|
||||
continue
|
||||
except PropertiesOptionError:
|
||||
pass
|
||||
elif not opt.impl_is_symlinkoption():
|
||||
self_properties = settings.getproperties(opt,
|
||||
path,
|
||||
setting_properties=setting_properties)
|
||||
if 'mandatory' in self_properties or 'empty' in self_properties:
|
||||
values = self.get_cached_value(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
trusted_cached_properties=False,
|
||||
force_permissive=True,
|
||||
self_properties=self_properties,
|
||||
validate=True,
|
||||
display_warnings=False)
|
||||
if opt.impl_is_master_slaves('slave') and isinstance(values, list):
|
||||
for val in values:
|
||||
ret = _is_properties_option(val, path)
|
||||
if ret is not None:
|
||||
yield ret
|
||||
break
|
||||
else:
|
||||
ret = _is_properties_option(values, path)
|
||||
if ret is not None:
|
||||
yield ret
|
||||
try:
|
||||
if opt.impl_is_master_slaves('slave'):
|
||||
if lenmaster is None:
|
||||
# master is a length (so int) if value is already calculated
|
||||
# otherwise get value and calculate length
|
||||
values = self.get_cached_value(optmaster,
|
||||
pathmaster,
|
||||
setting_properties,
|
||||
self_properties=self_properties,
|
||||
trusted_cached_properties=False,
|
||||
force_permissive=True,
|
||||
validate=True,
|
||||
display_warnings=False)
|
||||
|
||||
lenmaster = len(values)
|
||||
if not lenmaster:
|
||||
settings.validate_properties(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
self_properties=self_properties,
|
||||
force_permissive=True)
|
||||
else:
|
||||
for index in range(lenmaster):
|
||||
settings.validate_properties(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
self_properties=self_properties,
|
||||
index=index,
|
||||
force_permissive=True)
|
||||
else:
|
||||
settings.validate_properties(opt,
|
||||
path,
|
||||
setting_properties,
|
||||
self_properties=self_properties,
|
||||
force_permissive=True)
|
||||
except PropertiesOptionError as err:
|
||||
if err.proptype == frozenset(['mandatory']):
|
||||
yield path
|
||||
if is_masterslaves and lenmaster is None:
|
||||
break
|
||||
except ConfigError as err:
|
||||
#assume that uncalculated value is an empty value
|
||||
yield path
|
||||
if is_masterslaves and lenmaster is None:
|
||||
break
|
||||
if is_masterslaves and lenmaster is None:
|
||||
pathmaster = path
|
||||
optmaster = opt
|
||||
|
||||
descr = context.cfgimpl_get_description()
|
||||
for path in _mandatory_warnings(descr):
|
||||
for path in _mandatory_warnings(descr, []):
|
||||
yield path
|
||||
|
Reference in New Issue
Block a user