better support for dynoptiondescription
This commit is contained in:
parent
df233d3165
commit
97d7352a5b
5 changed files with 31 additions and 35 deletions
4
AUTHORS
4
AUTHORS
|
@ -1,8 +1,8 @@
|
||||||
Authors
|
Authors
|
||||||
--------
|
--------
|
||||||
|
|
||||||
Gwenaël Rémond <gremond@cadoles.com> lead developer
|
Emmanuel Garette <egarette@cadoles.com> lead developer
|
||||||
Emmanuel Garette <egarette@cadoles.com> developer
|
Gwenaël Rémond <gremond@cadoles.com> developer
|
||||||
|
|
||||||
Daniel Dehennin <daniel.dehennin@ac-dijon.fr> contributor
|
Daniel Dehennin <daniel.dehennin@ac-dijon.fr> contributor
|
||||||
Philippe Caseiro <pcaseiro@cadoles.com> contributor
|
Philippe Caseiro <pcaseiro@cadoles.com> contributor
|
||||||
|
|
|
@ -17,13 +17,13 @@ from py.test import raises
|
||||||
from pickle import dumps, loads
|
from pickle import dumps, loads
|
||||||
|
|
||||||
|
|
||||||
def return_true(value, param=None):
|
def return_true(value, param=None, suffix=None):
|
||||||
if value == 'val' and param in [None, 'yes']:
|
if value == 'val' and param in [None, 'yes']:
|
||||||
return
|
return
|
||||||
raise ValueError('no value')
|
raise ValueError('no value')
|
||||||
|
|
||||||
|
|
||||||
def return_dynval(suffix, value='val'):
|
def return_dynval(value='val', suffix=None):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ def return_list2(suffix):
|
||||||
return [str(suffix), 'val2']
|
return [str(suffix), 'val2']
|
||||||
|
|
||||||
|
|
||||||
def return_list(val=None):
|
def return_list(val=None, suffix=None):
|
||||||
if val:
|
if val:
|
||||||
return val
|
return val
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -139,11 +139,8 @@ def carry_out_calculation(option, context, callback, callback_params,
|
||||||
# if callback_params has a callback, launch several time calculate()
|
# if callback_params has a callback, launch several time calculate()
|
||||||
master_slave = False
|
master_slave = False
|
||||||
# multi's option should have same value for all option
|
# multi's option should have same value for all option
|
||||||
try:
|
|
||||||
if option._is_subdyn():
|
if option._is_subdyn():
|
||||||
tcparams[''] = [(option.impl_getsuffix(), False)]
|
tcparams['suffix'] = [(option.impl_getsuffix(), False)]
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
for key, callbacks in callback_params.items():
|
for key, callbacks in callback_params.items():
|
||||||
for callbk in callbacks:
|
for callbk in callbacks:
|
||||||
if isinstance(callbk, tuple):
|
if isinstance(callbk, tuple):
|
||||||
|
|
|
@ -376,10 +376,7 @@ class BaseOption(Base):
|
||||||
return self.impl_get_callback()[0] is not None
|
return self.impl_get_callback()[0] is not None
|
||||||
|
|
||||||
def _is_subdyn(self):
|
def _is_subdyn(self):
|
||||||
try:
|
return getattr(self, '_subdyn', None) is not None
|
||||||
return self._subdyn is not None
|
|
||||||
except AttributeError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def impl_getproperties(self):
|
def impl_getproperties(self):
|
||||||
return self._properties
|
return self._properties
|
||||||
|
@ -518,7 +515,7 @@ class Option(OnlyOption):
|
||||||
validator_params_ = {'': (val,)}
|
validator_params_ = {'': (val,)}
|
||||||
# Raise ValueError if not valid
|
# Raise ValueError if not valid
|
||||||
try:
|
try:
|
||||||
carry_out_calculation(self, context=context,
|
carry_out_calculation(current_opt, context=context,
|
||||||
callback=validator,
|
callback=validator,
|
||||||
callback_params=validator_params_)
|
callback_params=validator_params_)
|
||||||
except ContextError:
|
except ContextError:
|
||||||
|
@ -529,7 +526,7 @@ class Option(OnlyOption):
|
||||||
return
|
return
|
||||||
# option validation
|
# option validation
|
||||||
try:
|
try:
|
||||||
self._validate(_value, context)
|
self._validate(_value, context, current_opt)
|
||||||
except ValueError as err: # pragma: optional cover
|
except ValueError as err: # pragma: optional cover
|
||||||
log.debug('do_validation: value: {0}, index: {1}, '
|
log.debug('do_validation: value: {0}, index: {1}, '
|
||||||
'submulti_index: {2}'.format(_value, _index,
|
'submulti_index: {2}'.format(_value, _index,
|
||||||
|
|
|
@ -68,7 +68,9 @@ class ChoiceOption(Option):
|
||||||
properties=properties,
|
properties=properties,
|
||||||
warnings_only=warnings_only)
|
warnings_only=warnings_only)
|
||||||
|
|
||||||
def impl_get_values(self, context):
|
def impl_get_values(self, context, current_opt=undefined):
|
||||||
|
if current_opt is undefined:
|
||||||
|
current_opt = self
|
||||||
#FIXME cache? but in context...
|
#FIXME cache? but in context...
|
||||||
values = self._choice_values
|
values = self._choice_values
|
||||||
if isinstance(values, FunctionType):
|
if isinstance(values, FunctionType):
|
||||||
|
@ -78,7 +80,7 @@ class ChoiceOption(Option):
|
||||||
values_params = self._choice_values_params
|
values_params = self._choice_values_params
|
||||||
if values_params is None:
|
if values_params is None:
|
||||||
values_params = {}
|
values_params = {}
|
||||||
values = carry_out_calculation(self, context=context,
|
values = carry_out_calculation(current_opt, context=context,
|
||||||
callback=values,
|
callback=values,
|
||||||
callback_params=values_params)
|
callback_params=values_params)
|
||||||
if not isinstance(values, list): # pragma: optional cover
|
if not isinstance(values, list): # pragma: optional cover
|
||||||
|
@ -86,9 +88,9 @@ class ChoiceOption(Option):
|
||||||
'').format(self.impl_getname()))
|
'').format(self.impl_getname()))
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
try:
|
try:
|
||||||
values = self.impl_get_values(context)
|
values = self.impl_get_values(context, current_opt=current_opt)
|
||||||
if not value in values: # pragma: optional cover
|
if not value in values: # pragma: optional cover
|
||||||
raise ValueError(_('value {0} is not permitted, '
|
raise ValueError(_('value {0} is not permitted, '
|
||||||
'only {1} is allowed'
|
'only {1} is allowed'
|
||||||
|
@ -102,7 +104,7 @@ class BoolOption(Option):
|
||||||
"represents a choice between ``True`` and ``False``"
|
"represents a choice between ``True`` and ``False``"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
if not isinstance(value, bool):
|
if not isinstance(value, bool):
|
||||||
raise ValueError(_('invalid boolean')) # pragma: optional cover
|
raise ValueError(_('invalid boolean')) # pragma: optional cover
|
||||||
|
|
||||||
|
@ -111,7 +113,7 @@ class IntOption(Option):
|
||||||
"represents a choice of an integer"
|
"represents a choice of an integer"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
if not isinstance(value, int):
|
if not isinstance(value, int):
|
||||||
raise ValueError(_('invalid integer')) # pragma: optional cover
|
raise ValueError(_('invalid integer')) # pragma: optional cover
|
||||||
|
|
||||||
|
@ -120,7 +122,7 @@ class FloatOption(Option):
|
||||||
"represents a choice of a floating point number"
|
"represents a choice of a floating point number"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
if not isinstance(value, float):
|
if not isinstance(value, float):
|
||||||
raise ValueError(_('invalid float')) # pragma: optional cover
|
raise ValueError(_('invalid float')) # pragma: optional cover
|
||||||
|
|
||||||
|
@ -129,7 +131,7 @@ class StrOption(Option):
|
||||||
"represents the choice of a string"
|
"represents the choice of a string"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
if not isinstance(value, str):
|
if not isinstance(value, str):
|
||||||
raise ValueError(_('invalid string')) # pragma: optional cover
|
raise ValueError(_('invalid string')) # pragma: optional cover
|
||||||
|
|
||||||
|
@ -145,7 +147,7 @@ else:
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
_empty = u''
|
_empty = u''
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
if not isinstance(value, unicode):
|
if not isinstance(value, unicode):
|
||||||
raise ValueError(_('invalid unicode')) # pragma: optional cover
|
raise ValueError(_('invalid unicode')) # pragma: optional cover
|
||||||
|
|
||||||
|
@ -173,7 +175,7 @@ class IPOption(Option):
|
||||||
warnings_only=warnings_only,
|
warnings_only=warnings_only,
|
||||||
extra=extra)
|
extra=extra)
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
# sometimes an ip term starts with a zero
|
# sometimes an ip term starts with a zero
|
||||||
# but this does not fit in some case, for example bind does not like it
|
# but this does not fit in some case, for example bind does not like it
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
|
@ -273,7 +275,7 @@ class PortOption(Option):
|
||||||
warnings_only=warnings_only,
|
warnings_only=warnings_only,
|
||||||
extra=extra)
|
extra=extra)
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
if isinstance(value, int):
|
if isinstance(value, int):
|
||||||
value = unicode(value)
|
value = unicode(value)
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
|
@ -303,7 +305,7 @@ class NetworkOption(Option):
|
||||||
"represents the choice of a network"
|
"represents the choice of a network"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
try:
|
try:
|
||||||
IP(value)
|
IP(value)
|
||||||
|
@ -324,7 +326,7 @@ class NetmaskOption(Option):
|
||||||
"represents the choice of a netmask"
|
"represents the choice of a netmask"
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
try:
|
try:
|
||||||
IP('0.0.0.0/{0}'.format(value))
|
IP('0.0.0.0/{0}'.format(value))
|
||||||
|
@ -372,7 +374,7 @@ class NetmaskOption(Option):
|
||||||
class BroadcastOption(Option):
|
class BroadcastOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
try:
|
try:
|
||||||
IP('{0}/32'.format(value))
|
IP('{0}/32'.format(value))
|
||||||
|
@ -430,7 +432,7 @@ class DomainnameOption(Option):
|
||||||
warnings_only=warnings_only,
|
warnings_only=warnings_only,
|
||||||
extra=extra)
|
extra=extra)
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
|
|
||||||
def _valid_length(val):
|
def _valid_length(val):
|
||||||
|
@ -487,7 +489,7 @@ class EmailOption(DomainnameOption):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$")
|
username_re = re.compile(r"^[\w!#$%&'*+\-/=?^`{|}~.]+$")
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
splitted = value.split('@', 1)
|
splitted = value.split('@', 1)
|
||||||
try:
|
try:
|
||||||
|
@ -509,7 +511,7 @@ class URLOption(DomainnameOption):
|
||||||
proto_re = re.compile(r'(http|https)://')
|
proto_re = re.compile(r'(http|https)://')
|
||||||
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
|
path_re = re.compile(r"^[A-Za-z0-9\-\._~:/\?#\[\]@!%\$&\'\(\)\*\+,;=]+$")
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
match = self.proto_re.search(value)
|
match = self.proto_re.search(value)
|
||||||
if not match: # pragma: optional cover
|
if not match: # pragma: optional cover
|
||||||
|
@ -550,7 +552,7 @@ class UsernameOption(Option):
|
||||||
#regexp build with 'man 8 adduser' informations
|
#regexp build with 'man 8 adduser' informations
|
||||||
username_re = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
|
username_re = re.compile(r"^[a-z_][a-z0-9_-]{0,30}[$a-z0-9_-]{0,1}$")
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
match = self.username_re.search(value)
|
match = self.username_re.search(value)
|
||||||
if not match:
|
if not match:
|
||||||
|
@ -561,7 +563,7 @@ class FilenameOption(Option):
|
||||||
__slots__ = tuple()
|
__slots__ = tuple()
|
||||||
path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
|
path_re = re.compile(r"^[a-zA-Z0-9\-\._~/+]+$")
|
||||||
|
|
||||||
def _validate(self, value, context=undefined):
|
def _validate(self, value, context=undefined, current_opt=undefined):
|
||||||
self._impl_valid_unicode(value)
|
self._impl_valid_unicode(value)
|
||||||
match = self.path_re.search(value)
|
match = self.path_re.search(value)
|
||||||
if not match:
|
if not match:
|
||||||
|
|
Loading…
Reference in a new issue