context=context)
if isinstance(child, OptionDescription) or isinstance(child, SynDynOptionDescription):
raise TypeError(_("can't assign to an OptionDescription")) # pragma: optional cover
- elif isinstance(child, SymLinkOption) and \
+ elif child._is_symlinkoption() and \
not isinstance(child, DynSymLinkOption): # pragma: no dynoptiondescription cover
path = context.cfgimpl_get_description().impl_get_path_by_opt(
child._impl_getopt())
setting_properties=_setting_properties,
self_properties=_self_properties,
index=index)
- elif isinstance(option, SymLinkOption): # pragma: no dynoptiondescription cover
+ elif option._is_symlinkoption(): # pragma: no dynoptiondescription cover
path = context.cfgimpl_get_description().impl_get_path_by_opt(
option._impl_getopt())
cfg = context.getattr(path, validate=validate,
from .masterslave import MasterSlaves
from .optiondescription import OptionDescription, DynOptionDescription, \
SynDynOptionDescription
-from .baseoption import Option, SymLinkOption, DynSymLinkOption, submulti
+from .baseoption import SymLinkOption, DynSymLinkOption, submulti
+from .option import Option
from .choiceoption import ChoiceOption
from .booloption import BoolOption
from .intoption import IntOption
# ____________________________________________________________
import re
from types import FunctionType
-import warnings
import sys
from ..i18n import _
-from ..setting import log, undefined, debug
-from ..autolib import carry_out_calculation
-from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
- display_list)
+from ..setting import undefined
+from ..error import ConfigError
if sys.version_info[0] >= 3: # pragma: no cover
from inspect import signature
STATIC_TUPLE = tuple()
-if sys.version_info[0] >= 3: # pragma: no cover
- xrange = range
-
submulti = 2
NAME_REGEXP = re.compile(r'^[a-z][a-zA-Z\d_]*$')
FORBIDDEN_NAMES = frozenset(['iter_all', 'iter_group', 'find', 'find_first',
'make_dict', 'unwrap_from_path', 'read_only',
'read_write', 'getowner', 'set_contexts'])
-ALLOWED_CONST_LIST = ['_cons_not_equal']
def valid_name(name):
"""
def _validate_option(option):
#validate option
- if isinstance(option, SymLinkOption):
- cur_opt = option._impl_getopt()
- elif isinstance(option, Option):
- cur_opt = option
+ if hasattr(option, '_is_symlinkoption'):
+ if option._is_symlinkoption():
+ cur_opt = option._impl_getopt()
+ else:
+ cur_opt = option
else:
raise ValueError(_('{}_params must have an option'
' not a {} for first argument'
return validator_params
def _set_has_dependency(self):
- if not isinstance(self, SymLinkOption):
+ if not self._is_symlinkoption():
self._has_dependency = True
def impl_has_dependency(self):
opt=self,
path=path)
-
-class OnlyOption(BaseOption):
- __slots__ = tuple()
-
-
-class Option(OnlyOption):
- """
- Abstract base class for configuration option's.
-
- Reminder: an Option object is **not** a container for the value.
- """
- __slots__ = ('_extra',
- '_warnings_only',
- '_allow_empty_list',
- #multi
- '_multi',
- '_unique',
- #value
- '_default',
- '_default_multi',
- #calcul
- '_val_call',
- #
- '_master_slaves',
- '_choice_values',
- '_choice_values_params',
- )
- _empty = ''
- def __init__(self, name, doc, default=None, default_multi=None,
- requires=None, multi=False, unique=undefined, callback=None,
- callback_params=None, validator=None, validator_params=None,
- properties=None, warnings_only=False, extra=None,
- allow_empty_list=undefined):
-
- _setattr = object.__setattr__
- if not multi and default_multi is not None:
- raise ValueError(_("default_multi is set whereas multi is False"
- " in option: {0}").format(name))
- if multi is True:
- is_multi = True
- _multi = 0
- elif multi is False:
- is_multi = False
- _multi = 1
- elif multi is submulti:
- is_multi = True
- _multi = submulti
- else:
- raise ValueError(_('invalid multi value'))
- if _multi != 1:
- _setattr(self, '_multi', _multi)
- if multi is not False and default is None:
- default = []
- if validator is not None:
- if multi: # and validator_params is None:
- validator_params = self._build_validator_params(validator, validator_params)
-
- validate_callback(validator, validator_params, 'validator', self)
- if validator_params is None:
- val_call = (validator,)
- else:
- val_call = (validator, validator_params)
- self._val_call = (val_call, None)
- self._set_has_dependency()
- if extra is not None:
- _setattr(self, '_extra', extra)
- if unique != undefined and not isinstance(unique, bool):
- raise ValueError(_('unique must be a boolean'))
- if not is_multi and unique is True:
- raise ValueError(_('unique must be set only with multi value'))
- if warnings_only is True:
- _setattr(self, '_warnings_only', warnings_only)
- if allow_empty_list is not undefined:
- _setattr(self, '_allow_empty_list', allow_empty_list)
-
- super(Option, self).__init__(name, doc, requires=requires,
- properties=properties, is_multi=is_multi)
- if is_multi and default_multi is not None:
- err = self._validate(default_multi)
- if err:
- raise ValueError(_("invalid default_multi value {0} "
- "for option {1}: {2}").format(
- str(default_multi),
- self.impl_getname(), str(err)))
- _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
- if (is_multi and default != []) or \
- (not is_multi and default is not None):
- if is_multi:
- default = tuple(default)
- _setattr(self, '_default', default)
-
- self.impl_set_callback(callback, callback_params, _init=True)
-
- def impl_is_multi(self):
- return getattr(self, '_multi', 1) != 1
-
- def _add_dependencies(self, option):
- options = set(getattr(self, '_dependencies', tuple()))
- options.add(option)
- self._dependencies = tuple(options)
-
- def _launch_consistency(self, current_opt, func, option, value, context,
- index, submulti_index, opts, warnings_only,
- transitive):
- """Launch consistency now
-
- :param func: function name, this name should start with _cons_
- :type func: `str`
- :param option: option that value is changing
- :type option: `tiramisu.option.Option`
- :param value: new value of this option
- :param context: Config's context, if None, check default value instead
- :type context: `tiramisu.config.Config`
- :param index: only for multi option, consistency should be launch for
- specified index
- :type index: `int`
- :param opts: all options concerne by this consistency
- :type opts: `list` of `tiramisu.option.Option`
- :param warnings_only: specific raise error for warning
- :type warnings_only: `boolean`
- :param transitive: propertyerror is transitive
- :type transitive: `boolean`
- """
- if context is not undefined:
- descr = context.cfgimpl_get_description()
-
- all_cons_vals = []
- all_cons_opts = []
- val_consistencies = True
- for opt in opts:
- if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
- option == opt:
- # option is current option
- # we have already value, so use it
- all_cons_vals.append(value)
- all_cons_opts.append(opt)
- else:
- #if context, calculate value, otherwise get default value
- path = None
- is_multi = opt.impl_is_multi() and not opt.impl_is_master_slaves()
- if context is not undefined:
- if isinstance(opt, DynSymLinkOption):
- path = opt.impl_getpath(context)
- else:
- path = descr.impl_get_path_by_opt(opt)
- if is_multi:
- _index = None
- else:
- _index = index
- opt_value = context.getattr(path, validate=False,
- index=_index,
- force_permissive=True,
- returns_raise=True)
- if isinstance(opt_value, Exception):
- if isinstance(opt_value, PropertiesOptionError):
- if debug: # pragma: no cover
- log.debug('propertyerror in _launch_consistency: {0}'.format(opt_value))
- if transitive:
- opt_value.set_orig_opt(option)
- return opt_value
- else:
- opt_value = None
- else: # pragma: no cover
- return opt_value
- elif index is None:
- opt_value = opt.impl_getdefault()
- else:
- opt_value = opt.impl_getdefault()[index]
-
- if self.impl_is_multi() and index is None:
- # only check propertyerror for master/slaves is transitive
- val_consistencies = False
- if is_multi and isinstance(opt_value, list):
- all_cons_vals.extend(opt_value)
- for len_ in xrange(len(opt_value)):
- all_cons_opts.append(opt)
- else:
- all_cons_vals.append(opt_value)
- all_cons_opts.append(opt)
-
- if val_consistencies:
- err = getattr(self, func)(current_opt, all_cons_opts, all_cons_vals, warnings_only)
- if err:
- if warnings_only:
- msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}').format(
- value, self._display_name, current_opt.impl_get_display_name(), err)
- warnings.warn_explicit(ValueWarning(msg, self),
- ValueWarning,
- self.__class__.__name__, 0)
- else:
- return err
-
- def impl_is_unique(self):
- return getattr(self, '_unique', False)
-
- def impl_get_validator(self):
- val = getattr(self, '_val_call', (None,))[0]
- if val is None:
- ret_val = (None, {})
- elif len(val) == 1:
- ret_val = (val[0], {})
- else:
- ret_val = val
- return ret_val
-
- def impl_validate(self, value, context=undefined, validate=True,
- force_index=None, force_submulti_index=None,
- current_opt=undefined, is_multi=None,
- display_error=True, display_warnings=True, multi=None,
- setting_properties=undefined):
- """
- :param value: the option's value
- :param context: Config's context
- :type context: :class:`tiramisu.config.Config`
- :param validate: if true enables ``self._validator`` validation
- :type validate: boolean
- :param force_index: if multi, value has to be a list
- not if force_index is not None
- :type force_index: integer
- :param force_submulti_index: if submulti, value has to be a list
- not if force_submulti_index is not None
- :type force_submulti_index: integer
- """
- if not validate:
- return
- 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)
-
- def _is_not_unique(value):
- if display_error and self.impl_is_unique() and len(set(value)) != len(value):
- for idx, val in enumerate(value):
- if val in value[idx+1:]:
- return ValueError(_('invalid value "{}", this value is already in "{}"').format(
- val, self.impl_get_display_name()))
-
- def calculation_validator(val, _index):
- validator, validator_params = self.impl_get_validator()
- if validator is not None:
- if validator_params != {}:
- validator_params_ = {}
- for val_param, values in validator_params.items():
- validator_params_[val_param] = values
- #inject value in calculation
- if '' in validator_params_:
- lst = list(validator_params_[''])
- lst.insert(0, val)
- validator_params_[''] = tuple(lst)
- else:
- validator_params_[''] = (val,)
- else:
- validator_params_ = {'': (val,)}
- # Raise ValueError if not valid
- value = carry_out_calculation(current_opt, context=context,
- callback=validator,
- callback_params=validator_params_,
- index=_index,
- is_validator=True)
- if isinstance(value, Exception):
- return value
-
- def do_validation(_value, _index, submulti_index):
- if _value is None:
- error = warning = None
- else:
- if display_error:
- # option validation
- err = self._validate(_value, context, current_opt)
- if err:
- if debug: # pragma: no cover
- log.debug('do_validation: value: {0}, index: {1}, '
- 'submulti_index: {2}'.format(_value, _index,
- submulti_index),
- exc_info=True)
- err_msg = '{0}'.format(err)
- if err_msg:
- msg = _('"{0}" is an invalid {1} for "{2}", {3}'
- '').format(_value, self._display_name,
- self.impl_get_display_name(), err_msg)
- else:
- msg = _('"{0}" is an invalid {1} for "{2}"'
- '').format(_value, self._display_name,
- self.impl_get_display_name())
- return ValueError(msg)
- error = None
- is_warnings_only = getattr(self, '_warnings_only', False)
- if ((display_error and not is_warnings_only) or
- (display_warnings and is_warnings_only)):
- error = calculation_validator(_value, _index)
- if not error:
- error = self._second_level_validation(_value, is_warnings_only)
- if error:
- if debug: # pragma: no cover
- log.debug(_('do_validation for {0}: error in value').format(
- self.impl_getname()), exc_info=True)
- if is_warnings_only:
- msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}').format(
- _value, self._display_name, self.impl_get_display_name(), error)
- warnings.warn_explicit(ValueWarning(msg, self),
- ValueWarning,
- self.__class__.__name__, 0)
- error = None
- if error is None:
- # if context launch consistency validation
- #if context is not undefined:
- ret = self._valid_consistency(current_opt, _value, context,
- _index, submulti_index, display_warnings,
- display_error)
- if isinstance(ret, ValueError):
- error = ret
- elif ret:
- return ret
- if error:
- err_msg = '{0}'.format(error)
- if err_msg:
- msg = _('"{0}" is an invalid {1} for "{2}", {3}'
- '').format(_value, self._display_name,
- self.impl_get_display_name(), err_msg)
- else:
- msg = _('"{0}" is an invalid {1} for "{2}"'
- '').format(_value, self._display_name,
- self.impl_get_display_name())
- return ValueError(msg)
-
- if is_multi is None:
- is_multi = self.impl_is_multi()
-
- if not is_multi:
- return do_validation(value, None, None)
- elif force_index is not None:
- if self.impl_is_submulti() and force_submulti_index is None:
- err = _is_not_unique(value)
- if err:
- return err
- if not isinstance(value, list):
- return ValueError(_('invalid value "{0}" for "{1}" which'
- ' must be a list').format(
- value, self.impl_get_display_name()))
- for idx, val in enumerate(value):
- if isinstance(val, list): # pragma: no cover
- return ValueError(_('invalid value "{}" for "{}" '
- 'which must not be a list').format(val,
- self.impl_get_display_name()))
- err = do_validation(val, force_index, idx)
- if err:
- return err
- else:
- if multi is not None and self.impl_is_unique() and value in multi:
- if not self.impl_is_submulti() and len(multi) - 1 >= force_index:
- lst = list(multi)
- lst.pop(force_index)
- else:
- lst = multi
- if value in lst:
- return ValueError(_('invalid value "{}", this value is already'
- ' in "{}"').format(value,
- self.impl_get_display_name()))
- return do_validation(value, force_index, force_submulti_index)
- elif not isinstance(value, list):
- return ValueError(_('invalid value "{0}" for "{1}" which '
- 'must be a list').format(value,
- self.impl_getname()))
- elif self.impl_is_submulti() and force_submulti_index is None:
- for idx, val in enumerate(value):
- err = _is_not_unique(val)
- if err:
- return err
- if not isinstance(val, list):
- return ValueError(_('invalid value "{0}" for "{1}" '
- 'which must be a list of list'
- '').format(val,
- self.impl_getname()))
- for slave_idx, slave_val in enumerate(val):
- err = do_validation(slave_val, idx, slave_idx)
- if err:
- return err
- else:
- err = _is_not_unique(value)
- if err:
- return err
- for idx, val in enumerate(value):
- err = do_validation(val, idx, force_submulti_index)
- if err:
- return err
- return self._valid_consistency(current_opt, None, context,
- None, None, display_warnings, display_error)
-
- def impl_is_dynsymlinkoption(self):
+ def _is_symlinkoption(self):
return False
- def impl_is_master_slaves(self, type_='both'):
- """FIXME
- """
- master_slaves = self.impl_get_master_slaves()
- if master_slaves is not None:
- if type_ in ('both', 'master') and \
- master_slaves.is_master(self):
- return True
- if type_ in ('both', 'slave') and \
- not master_slaves.is_master(self):
- return True
- return False
-
- def impl_get_master_slaves(self):
- return getattr(self, '_master_slaves', None)
-
- def impl_getdoc(self):
- "accesses the Option's doc"
- return self.impl_get_information('doc')
- def _valid_consistencies(self, other_opts, init=True, func=None):
- if self._is_subdyn():
- dynod = self._subdyn
- else:
- dynod = None
- if self.impl_is_submulti():
- raise ConfigError(_('cannot add consistency with submulti option'))
- is_multi = self.impl_is_multi()
- for opt in other_opts:
- if opt.impl_is_submulti():
- raise ConfigError(_('cannot add consistency with submulti option'))
- if not isinstance(opt, Option):
- raise ConfigError(_('consistency must be set with an option'))
- if opt._is_subdyn():
- if dynod is None:
- raise ConfigError(_('almost one option in consistency is '
- 'in a dynoptiondescription but not all'))
- if dynod != opt._subdyn:
- raise ConfigError(_('option in consistency must be in same'
- ' dynoptiondescription'))
- dynod = opt._subdyn
- elif dynod is not None:
- raise ConfigError(_('almost one option in consistency is in a '
- 'dynoptiondescription but not all'))
- if self is opt:
- raise ConfigError(_('cannot add consistency with itself'))
- if is_multi != opt.impl_is_multi():
- raise ConfigError(_('every options in consistency must be '
- 'multi or none'))
- if init:
- # FIXME
- if func != 'not_equal':
- opt._set_has_dependency()
-
- def impl_add_consistency(self, func, *other_opts, **params):
- """Add consistency means that value will be validate with other_opts
- option's values.
-
- :param func: function's name
- :type func: `str`
- :param other_opts: options used to validate value
- :type other_opts: `list` of `tiramisu.option.Option`
- :param params: extra params (warnings_only and transitive are allowed)
- """
- if self.impl_is_readonly():
- raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
- " read-only").format(
- self.__class__.__name__,
- self.impl_getname()))
- self._valid_consistencies(other_opts, func=func)
- func = '_cons_{0}'.format(func)
- if func not in dir(self):
- raise ConfigError(_('consistency {0} not available for this option').format(func))
- all_cons_opts = tuple([self] + list(other_opts))
- unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
- if unknown_params != set():
- raise ValueError(_('unknow parameter {0} in consistency').format(unknown_params))
- self._add_consistency(func, all_cons_opts, params)
- #validate default value when add consistency
- err = self.impl_validate(self.impl_getdefault())
- if err:
- self._del_consistency()
- raise err
- if func in ALLOWED_CONST_LIST:
- for opt in all_cons_opts:
- if getattr(opt, '_unique', undefined) == undefined:
- opt._unique = True
- if func != '_cons_not_equal':
- #consistency could generate warnings or errors
- self._set_has_dependency()
-
- def _valid_consistency(self, option, value, context, index, submulti_idx,
- display_warnings, display_error):
- if context is not undefined:
- descr = context.cfgimpl_get_description()
- if descr._cache_consistencies is None:
- return
- #consistencies is something like [('_cons_not_equal', (opt1, opt2))]
- if isinstance(option, DynSymLinkOption):
- consistencies = descr._cache_consistencies.get(option._impl_getopt())
- else:
- consistencies = descr._cache_consistencies.get(option)
- else:
- consistencies = option._get_consistencies()
- 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):
- transitive = params.get('transitive', True)
- #all_cons_opts[0] is the option where func is set
- if isinstance(option, DynSymLinkOption):
- subpath = '.'.join(option._dyn.split('.')[:-1])
- namelen = len(option._impl_getopt().impl_getname())
- suffix = option.impl_getname()[namelen:]
- opts = []
- for opt in all_cons_opts:
- name = opt.impl_getname() + suffix
- path = subpath + '.' + name
- opts.append(opt._impl_to_dyn(name, path))
- else:
- opts = all_cons_opts
- err = opts[0]._launch_consistency(self, func, option, value,
- context, index, submulti_idx,
- opts, warnings_only,
- transitive)
- if err:
- return err
-
- def _cons_not_equal(self, current_opt, opts, vals, warnings_only):
- equal = set()
- is_current = False
- for idx_inf, val_inf in enumerate(vals):
- for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
- if val_inf == val_sup is not None:
- for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
- if opt_ == current_opt:
- is_current = True
- else:
- equal.add(opt_)
- if equal:
- if debug: # pragma: no cover
- log.debug(_('_cons_not_equal: {} are not different').format(display_list(list(equal))))
- if is_current:
- if warnings_only:
- msg = _('should be different from the value of {}')
- else:
- msg = _('must be different from the value of {}')
- else:
- if warnings_only:
- msg = _('value for {} should be different')
- else:
- msg = _('value for {} must be different')
- equal_name = []
- for opt in equal:
- equal_name.append(opt.impl_get_display_name())
- return ValueError(msg.format(display_list(list(equal_name))))
-
- def _second_level_validation(self, value, warnings_only):
- pass
-
- def _impl_to_dyn(self, name, path):
- return DynSymLinkOption(name, self, dyn=path)
-
- def impl_getdefault_multi(self):
- "accessing the default value for a multi"
- return getattr(self, '_default_multi', None)
-
- def _validate_callback(self, callback, callback_params):
- """callback_params:
- * None
- * {'': ((option, permissive),), 'ip': ((None,), (option, permissive))
- """
- if callback is None:
- return
- default_multi = self.impl_getdefault_multi()
- is_multi = self.impl_is_multi()
- default = self.impl_getdefault()
- if (not is_multi and (default is not None or default_multi is not None)) or \
- (is_multi and (default != [] or default_multi is not None)):
- raise ValueError(_("default value not allowed if option: {0} "
- "is calculated").format(self.impl_getname()))
-
- def impl_getdefault(self):
- "accessing the default value"
- is_multi = self.impl_is_multi()
- default = getattr(self, '_default', undefined)
- if default is undefined:
- if is_multi:
- default = []
- else:
- default = None
- else:
- if is_multi:
- default = list(default)
- return default
-
- def _get_extra(self, key):
- extra = self._extra
- if isinstance(extra, tuple):
- return extra[1][extra[0].index(key)]
- else:
- return extra[key]
-
- def impl_is_submulti(self):
- return getattr(self, '_multi', 1) == 2
-
- def impl_allow_empty_list(self):
- return getattr(self, '_allow_empty_list', undefined)
-
- #____________________________________________________________
- # consistency
- def _add_consistency(self, func, all_cons_opts, params):
- cons = (func, all_cons_opts, params)
- consistencies = getattr(self, '_consistencies', None)
- if consistencies is None:
- self._consistencies = [cons]
- else:
- consistencies.append(cons)
-
- def _del_consistency(self):
- self._consistencies.pop(-1)
-
- def _get_consistencies(self):
- return getattr(self, '_consistencies', STATIC_TUPLE)
-
- def _has_consistencies(self):
- return hasattr(self, '_consistencies')
+class OnlyOption(BaseOption):
+ __slots__ = tuple()
def validate_requires_arg(new_option, multi, requires, name):
def get_option(require):
option = require['option']
- if not isinstance(option, Option):
+ if not hasattr(option, '_is_symlinkoption'):
raise ValueError(_('malformed requirements '
'must be an option in option {0}').format(name))
if not multi and option.impl_is_multi():
class SymLinkOption(OnlyOption):
def __init__(self, name, opt):
- if not isinstance(opt, Option):
+ if not isinstance(opt, OnlyOption) or \
+ opt._is_symlinkoption():
raise ValueError(_('malformed symlinkoption '
'must be an option '
'for symlink {0}').format(name))
_setattr(self, '_opt', opt)
opt._set_has_dependency()
+ def _is_symlinkoption(self):
+ return True
+
def __getattr__(self, name, context=undefined):
return getattr(self._impl_getopt(), name)
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class BoolOption(Option):
from ..error import ConfigError
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class BroadcastOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option, validate_callback, display_list
+from .baseoption import validate_callback
+from .option import Option
from ..autolib import carry_out_calculation
-from ..error import ConfigError
+from ..error import ConfigError, display_list
class ChoiceOption(Option):
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
# the whole pypy projet is under MIT licence
# ____________________________________________________________
-import re
from datetime import datetime
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class DateOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class DomainnameOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class FloatOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class IntOption(Option):
from ..error import ConfigError
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class IPOption(Option):
from ..error import ConfigError
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class NetmaskOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class NetworkOption(Option):
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
# the whole pypy projet is under MIT licence
# ____________________________________________________________
-from ..setting import undefined
+import warnings
+import sys
-from .baseoption import Option
+from .baseoption import OnlyOption, submulti, DynSymLinkOption, validate_callback, STATIC_TUPLE
+from ..i18n import _
+from ..setting import log, undefined, debug
+from ..autolib import carry_out_calculation
+from ..error import (ConfigError, ValueWarning, PropertiesOptionError,
+ display_list)
+
+ALLOWED_CONST_LIST = ['_cons_not_equal']
+
+if sys.version_info[0] >= 3: # pragma: no cover
+ xrange = range
+
+
+class Option(OnlyOption):
+ """
+ Abstract base class for configuration option's.
+
+ Reminder: an Option object is **not** a container for the value.
+ """
+ __slots__ = ('_extra',
+ '_warnings_only',
+ '_allow_empty_list',
+ #multi
+ '_multi',
+ '_unique',
+ #value
+ '_default',
+ '_default_multi',
+ #calcul
+ '_val_call',
+ #
+ '_master_slaves',
+ '_choice_values',
+ '_choice_values_params',
+ )
+ _empty = ''
+ def __init__(self, name, doc, default=None, default_multi=None,
+ requires=None, multi=False, unique=undefined, callback=None,
+ callback_params=None, validator=None, validator_params=None,
+ properties=None, warnings_only=False, extra=None,
+ allow_empty_list=undefined):
+
+ _setattr = object.__setattr__
+ if not multi and default_multi is not None:
+ raise ValueError(_("default_multi is set whereas multi is False"
+ " in option: {0}").format(name))
+ if multi is True:
+ is_multi = True
+ _multi = 0
+ elif multi is False:
+ is_multi = False
+ _multi = 1
+ elif multi is submulti:
+ is_multi = True
+ _multi = submulti
+ else:
+ raise ValueError(_('invalid multi value'))
+ if _multi != 1:
+ _setattr(self, '_multi', _multi)
+ if multi is not False and default is None:
+ default = []
+ if validator is not None:
+ if multi: # and validator_params is None:
+ validator_params = self._build_validator_params(validator, validator_params)
+
+ validate_callback(validator, validator_params, 'validator', self)
+ if validator_params is None:
+ val_call = (validator,)
+ else:
+ val_call = (validator, validator_params)
+ self._val_call = (val_call, None)
+ self._set_has_dependency()
+ if extra is not None:
+ _setattr(self, '_extra', extra)
+ if unique != undefined and not isinstance(unique, bool):
+ raise ValueError(_('unique must be a boolean'))
+ if not is_multi and unique is True:
+ raise ValueError(_('unique must be set only with multi value'))
+ if warnings_only is True:
+ _setattr(self, '_warnings_only', warnings_only)
+ if allow_empty_list is not undefined:
+ _setattr(self, '_allow_empty_list', allow_empty_list)
+
+ super(Option, self).__init__(name, doc, requires=requires,
+ properties=properties, is_multi=is_multi)
+ if is_multi and default_multi is not None:
+ err = self._validate(default_multi)
+ if err:
+ raise ValueError(_("invalid default_multi value {0} "
+ "for option {1}: {2}").format(
+ str(default_multi),
+ self.impl_getname(), str(err)))
+ _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
+ if (is_multi and default != []) or \
+ (not is_multi and default is not None):
+ if is_multi:
+ default = tuple(default)
+ _setattr(self, '_default', default)
+
+ self.impl_set_callback(callback, callback_params, _init=True)
+
+ def impl_is_multi(self):
+ return getattr(self, '_multi', 1) != 1
+
+ def _add_dependencies(self, option):
+ options = set(getattr(self, '_dependencies', tuple()))
+ options.add(option)
+ self._dependencies = tuple(options)
+
+ def _launch_consistency(self, current_opt, func, option, value, context,
+ index, submulti_index, opts, warnings_only,
+ transitive):
+ """Launch consistency now
+
+ :param func: function name, this name should start with _cons_
+ :type func: `str`
+ :param option: option that value is changing
+ :type option: `tiramisu.option.Option`
+ :param value: new value of this option
+ :param context: Config's context, if None, check default value instead
+ :type context: `tiramisu.config.Config`
+ :param index: only for multi option, consistency should be launch for
+ specified index
+ :type index: `int`
+ :param opts: all options concerne by this consistency
+ :type opts: `list` of `tiramisu.option.Option`
+ :param warnings_only: specific raise error for warning
+ :type warnings_only: `boolean`
+ :param transitive: propertyerror is transitive
+ :type transitive: `boolean`
+ """
+ if context is not undefined:
+ descr = context.cfgimpl_get_description()
+
+ all_cons_vals = []
+ all_cons_opts = []
+ val_consistencies = True
+ for opt in opts:
+ if (isinstance(opt, DynSymLinkOption) and option._dyn == opt._dyn) or \
+ option == opt:
+ # option is current option
+ # we have already value, so use it
+ all_cons_vals.append(value)
+ all_cons_opts.append(opt)
+ else:
+ #if context, calculate value, otherwise get default value
+ path = None
+ is_multi = opt.impl_is_multi() and not opt.impl_is_master_slaves()
+ if context is not undefined:
+ if isinstance(opt, DynSymLinkOption):
+ path = opt.impl_getpath(context)
+ else:
+ path = descr.impl_get_path_by_opt(opt)
+ if is_multi:
+ _index = None
+ else:
+ _index = index
+ opt_value = context.getattr(path, validate=False,
+ index=_index,
+ force_permissive=True,
+ returns_raise=True)
+ if isinstance(opt_value, Exception):
+ if isinstance(opt_value, PropertiesOptionError):
+ if debug: # pragma: no cover
+ log.debug('propertyerror in _launch_consistency: {0}'.format(opt_value))
+ if transitive:
+ opt_value.set_orig_opt(option)
+ return opt_value
+ else:
+ opt_value = None
+ else: # pragma: no cover
+ return opt_value
+ elif index is None:
+ opt_value = opt.impl_getdefault()
+ else:
+ opt_value = opt.impl_getdefault()[index]
+
+ if self.impl_is_multi() and index is None:
+ # only check propertyerror for master/slaves is transitive
+ val_consistencies = False
+ if is_multi and isinstance(opt_value, list):
+ all_cons_vals.extend(opt_value)
+ for len_ in xrange(len(opt_value)):
+ all_cons_opts.append(opt)
+ else:
+ all_cons_vals.append(opt_value)
+ all_cons_opts.append(opt)
+
+ if val_consistencies:
+ err = getattr(self, func)(current_opt, all_cons_opts, all_cons_vals, warnings_only)
+ if err:
+ if warnings_only:
+ msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}').format(
+ value, self._display_name, current_opt.impl_get_display_name(), err)
+ warnings.warn_explicit(ValueWarning(msg, self),
+ ValueWarning,
+ self.__class__.__name__, 0)
+ else:
+ return err
+
+ def impl_is_unique(self):
+ return getattr(self, '_unique', False)
+
+ def impl_get_validator(self):
+ val = getattr(self, '_val_call', (None,))[0]
+ if val is None:
+ ret_val = (None, {})
+ elif len(val) == 1:
+ ret_val = (val[0], {})
+ else:
+ ret_val = val
+ return ret_val
+
+ def impl_validate(self, value, context=undefined, validate=True,
+ force_index=None, force_submulti_index=None,
+ current_opt=undefined, is_multi=None,
+ display_error=True, display_warnings=True, multi=None,
+ setting_properties=undefined):
+ """
+ :param value: the option's value
+ :param context: Config's context
+ :type context: :class:`tiramisu.config.Config`
+ :param validate: if true enables ``self._validator`` validation
+ :type validate: boolean
+ :param force_index: if multi, value has to be a list
+ not if force_index is not None
+ :type force_index: integer
+ :param force_submulti_index: if submulti, value has to be a list
+ not if force_submulti_index is not None
+ :type force_submulti_index: integer
+ """
+ if not validate:
+ return
+ 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)
+
+ def _is_not_unique(value):
+ if display_error and self.impl_is_unique() and len(set(value)) != len(value):
+ for idx, val in enumerate(value):
+ if val in value[idx+1:]:
+ return ValueError(_('invalid value "{}", this value is already in "{}"').format(
+ val, self.impl_get_display_name()))
+
+ def calculation_validator(val, _index):
+ validator, validator_params = self.impl_get_validator()
+ if validator is not None:
+ if validator_params != {}:
+ validator_params_ = {}
+ for val_param, values in validator_params.items():
+ validator_params_[val_param] = values
+ #inject value in calculation
+ if '' in validator_params_:
+ lst = list(validator_params_[''])
+ lst.insert(0, val)
+ validator_params_[''] = tuple(lst)
+ else:
+ validator_params_[''] = (val,)
+ else:
+ validator_params_ = {'': (val,)}
+ # Raise ValueError if not valid
+ value = carry_out_calculation(current_opt, context=context,
+ callback=validator,
+ callback_params=validator_params_,
+ index=_index,
+ is_validator=True)
+ if isinstance(value, Exception):
+ return value
+
+ def do_validation(_value, _index, submulti_index):
+ if _value is None:
+ error = warning = None
+ else:
+ if display_error:
+ # option validation
+ err = self._validate(_value, context, current_opt)
+ if err:
+ if debug: # pragma: no cover
+ log.debug('do_validation: value: {0}, index: {1}, '
+ 'submulti_index: {2}'.format(_value, _index,
+ submulti_index),
+ exc_info=True)
+ err_msg = '{0}'.format(err)
+ if err_msg:
+ msg = _('"{0}" is an invalid {1} for "{2}", {3}'
+ '').format(_value, self._display_name,
+ self.impl_get_display_name(), err_msg)
+ else:
+ msg = _('"{0}" is an invalid {1} for "{2}"'
+ '').format(_value, self._display_name,
+ self.impl_get_display_name())
+ return ValueError(msg)
+ error = None
+ is_warnings_only = getattr(self, '_warnings_only', False)
+ if ((display_error and not is_warnings_only) or
+ (display_warnings and is_warnings_only)):
+ error = calculation_validator(_value, _index)
+ if not error:
+ error = self._second_level_validation(_value, is_warnings_only)
+ if error:
+ if debug: # pragma: no cover
+ log.debug(_('do_validation for {0}: error in value').format(
+ self.impl_getname()), exc_info=True)
+ if is_warnings_only:
+ msg = _('attention, "{0}" could be an invalid {1} for "{2}", {3}').format(
+ _value, self._display_name, self.impl_get_display_name(), error)
+ warnings.warn_explicit(ValueWarning(msg, self),
+ ValueWarning,
+ self.__class__.__name__, 0)
+ error = None
+ if error is None:
+ # if context launch consistency validation
+ #if context is not undefined:
+ ret = self._valid_consistency(current_opt, _value, context,
+ _index, submulti_index, display_warnings,
+ display_error)
+ if isinstance(ret, ValueError):
+ error = ret
+ elif ret:
+ return ret
+ if error:
+ err_msg = '{0}'.format(error)
+ if err_msg:
+ msg = _('"{0}" is an invalid {1} for "{2}", {3}'
+ '').format(_value, self._display_name,
+ self.impl_get_display_name(), err_msg)
+ else:
+ msg = _('"{0}" is an invalid {1} for "{2}"'
+ '').format(_value, self._display_name,
+ self.impl_get_display_name())
+ return ValueError(msg)
+
+ if is_multi is None:
+ is_multi = self.impl_is_multi()
+
+ if not is_multi:
+ return do_validation(value, None, None)
+ elif force_index is not None:
+ if self.impl_is_submulti() and force_submulti_index is None:
+ err = _is_not_unique(value)
+ if err:
+ return err
+ if not isinstance(value, list):
+ return ValueError(_('invalid value "{0}" for "{1}" which'
+ ' must be a list').format(
+ value, self.impl_get_display_name()))
+ for idx, val in enumerate(value):
+ if isinstance(val, list): # pragma: no cover
+ return ValueError(_('invalid value "{}" for "{}" '
+ 'which must not be a list').format(val,
+ self.impl_get_display_name()))
+ err = do_validation(val, force_index, idx)
+ if err:
+ return err
+ else:
+ if multi is not None and self.impl_is_unique() and value in multi:
+ if not self.impl_is_submulti() and len(multi) - 1 >= force_index:
+ lst = list(multi)
+ lst.pop(force_index)
+ else:
+ lst = multi
+ if value in lst:
+ return ValueError(_('invalid value "{}", this value is already'
+ ' in "{}"').format(value,
+ self.impl_get_display_name()))
+ return do_validation(value, force_index, force_submulti_index)
+ elif not isinstance(value, list):
+ return ValueError(_('invalid value "{0}" for "{1}" which '
+ 'must be a list').format(value,
+ self.impl_getname()))
+ elif self.impl_is_submulti() and force_submulti_index is None:
+ for idx, val in enumerate(value):
+ err = _is_not_unique(val)
+ if err:
+ return err
+ if not isinstance(val, list):
+ return ValueError(_('invalid value "{0}" for "{1}" '
+ 'which must be a list of list'
+ '').format(val,
+ self.impl_getname()))
+ for slave_idx, slave_val in enumerate(val):
+ err = do_validation(slave_val, idx, slave_idx)
+ if err:
+ return err
+ else:
+ err = _is_not_unique(value)
+ if err:
+ return err
+ for idx, val in enumerate(value):
+ err = do_validation(val, idx, force_submulti_index)
+ if err:
+ return err
+ return self._valid_consistency(current_opt, None, context,
+ None, None, display_warnings, display_error)
+
+ def impl_is_dynsymlinkoption(self):
+ return False
+
+ def impl_is_master_slaves(self, type_='both'):
+ """FIXME
+ """
+ master_slaves = self.impl_get_master_slaves()
+ if master_slaves is not None:
+ if type_ in ('both', 'master') and \
+ master_slaves.is_master(self):
+ return True
+ if type_ in ('both', 'slave') and \
+ not master_slaves.is_master(self):
+ return True
+ return False
+
+ def impl_get_master_slaves(self):
+ return getattr(self, '_master_slaves', None)
+
+ def impl_getdoc(self):
+ "accesses the Option's doc"
+ return self.impl_get_information('doc')
+
+ def _valid_consistencies(self, other_opts, init=True, func=None):
+ if self._is_subdyn():
+ dynod = self._subdyn
+ else:
+ dynod = None
+ if self.impl_is_submulti():
+ raise ConfigError(_('cannot add consistency with submulti option'))
+ is_multi = self.impl_is_multi()
+ for opt in other_opts:
+ if opt.impl_is_submulti():
+ raise ConfigError(_('cannot add consistency with submulti option'))
+ if not isinstance(opt, Option):
+ raise ConfigError(_('consistency must be set with an option'))
+ if opt._is_subdyn():
+ if dynod is None:
+ raise ConfigError(_('almost one option in consistency is '
+ 'in a dynoptiondescription but not all'))
+ if dynod != opt._subdyn:
+ raise ConfigError(_('option in consistency must be in same'
+ ' dynoptiondescription'))
+ dynod = opt._subdyn
+ elif dynod is not None:
+ raise ConfigError(_('almost one option in consistency is in a '
+ 'dynoptiondescription but not all'))
+ if self is opt:
+ raise ConfigError(_('cannot add consistency with itself'))
+ if is_multi != opt.impl_is_multi():
+ raise ConfigError(_('every options in consistency must be '
+ 'multi or none'))
+ if init:
+ # FIXME
+ if func != 'not_equal':
+ opt._set_has_dependency()
+
+ def impl_add_consistency(self, func, *other_opts, **params):
+ """Add consistency means that value will be validate with other_opts
+ option's values.
+
+ :param func: function's name
+ :type func: `str`
+ :param other_opts: options used to validate value
+ :type other_opts: `list` of `tiramisu.option.Option`
+ :param params: extra params (warnings_only and transitive are allowed)
+ """
+ if self.impl_is_readonly():
+ raise AttributeError(_("'{0}' ({1}) cannot add consistency, option is"
+ " read-only").format(
+ self.__class__.__name__,
+ self.impl_getname()))
+ self._valid_consistencies(other_opts, func=func)
+ func = '_cons_{0}'.format(func)
+ if func not in dir(self):
+ raise ConfigError(_('consistency {0} not available for this option').format(func))
+ all_cons_opts = tuple([self] + list(other_opts))
+ unknown_params = set(params.keys()) - set(['warnings_only', 'transitive'])
+ if unknown_params != set():
+ raise ValueError(_('unknow parameter {0} in consistency').format(unknown_params))
+ self._add_consistency(func, all_cons_opts, params)
+ #validate default value when add consistency
+ err = self.impl_validate(self.impl_getdefault())
+ if err:
+ self._del_consistency()
+ raise err
+ if func in ALLOWED_CONST_LIST:
+ for opt in all_cons_opts:
+ if getattr(opt, '_unique', undefined) == undefined:
+ opt._unique = True
+ if func != '_cons_not_equal':
+ #consistency could generate warnings or errors
+ self._set_has_dependency()
+
+ def _valid_consistency(self, option, value, context, index, submulti_idx,
+ display_warnings, display_error):
+ if context is not undefined:
+ descr = context.cfgimpl_get_description()
+ if descr._cache_consistencies is None:
+ return
+ #consistencies is something like [('_cons_not_equal', (opt1, opt2))]
+ if isinstance(option, DynSymLinkOption):
+ consistencies = descr._cache_consistencies.get(option._impl_getopt())
+ else:
+ consistencies = descr._cache_consistencies.get(option)
+ else:
+ consistencies = option._get_consistencies()
+ 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):
+ transitive = params.get('transitive', True)
+ #all_cons_opts[0] is the option where func is set
+ if isinstance(option, DynSymLinkOption):
+ subpath = '.'.join(option._dyn.split('.')[:-1])
+ namelen = len(option._impl_getopt().impl_getname())
+ suffix = option.impl_getname()[namelen:]
+ opts = []
+ for opt in all_cons_opts:
+ name = opt.impl_getname() + suffix
+ path = subpath + '.' + name
+ opts.append(opt._impl_to_dyn(name, path))
+ else:
+ opts = all_cons_opts
+ err = opts[0]._launch_consistency(self, func, option, value,
+ context, index, submulti_idx,
+ opts, warnings_only,
+ transitive)
+ if err:
+ return err
+
+ def _cons_not_equal(self, current_opt, opts, vals, warnings_only):
+ equal = set()
+ is_current = False
+ for idx_inf, val_inf in enumerate(vals):
+ for idx_sup, val_sup in enumerate(vals[idx_inf + 1:]):
+ if val_inf == val_sup is not None:
+ for opt_ in [opts[idx_inf], opts[idx_inf + idx_sup + 1]]:
+ if opt_ == current_opt:
+ is_current = True
+ else:
+ equal.add(opt_)
+ if equal:
+ if debug: # pragma: no cover
+ log.debug(_('_cons_not_equal: {} are not different').format(display_list(list(equal))))
+ if is_current:
+ if warnings_only:
+ msg = _('should be different from the value of {}')
+ else:
+ msg = _('must be different from the value of {}')
+ else:
+ if warnings_only:
+ msg = _('value for {} should be different')
+ else:
+ msg = _('value for {} must be different')
+ equal_name = []
+ for opt in equal:
+ equal_name.append(opt.impl_get_display_name())
+ return ValueError(msg.format(display_list(list(equal_name))))
+
+ def _second_level_validation(self, value, warnings_only):
+ pass
+
+ def _impl_to_dyn(self, name, path):
+ return DynSymLinkOption(name, self, dyn=path)
+
+ def impl_getdefault_multi(self):
+ "accessing the default value for a multi"
+ return getattr(self, '_default_multi', None)
+
+ def _validate_callback(self, callback, callback_params):
+ """callback_params:
+ * None
+ * {'': ((option, permissive),), 'ip': ((None,), (option, permissive))
+ """
+ if callback is None:
+ return
+ default_multi = self.impl_getdefault_multi()
+ is_multi = self.impl_is_multi()
+ default = self.impl_getdefault()
+ if (not is_multi and (default is not None or default_multi is not None)) or \
+ (is_multi and (default != [] or default_multi is not None)):
+ raise ValueError(_("default value not allowed if option: {0} "
+ "is calculated").format(self.impl_getname()))
+
+ def impl_getdefault(self):
+ "accessing the default value"
+ is_multi = self.impl_is_multi()
+ default = getattr(self, '_default', undefined)
+ if default is undefined:
+ if is_multi:
+ default = []
+ else:
+ default = None
+ else:
+ if is_multi:
+ default = list(default)
+ return default
+
+ def _get_extra(self, key):
+ extra = self._extra
+ if isinstance(extra, tuple):
+ return extra[1][extra[0].index(key)]
+ else:
+ return extra[key]
+
+ def impl_is_submulti(self):
+ return getattr(self, '_multi', 1) == 2
+
+ def impl_allow_empty_list(self):
+ return getattr(self, '_allow_empty_list', undefined)
+
+ #____________________________________________________________
+ # consistency
+ def _add_consistency(self, func, all_cons_opts, params):
+ cons = (func, all_cons_opts, params)
+ consistencies = getattr(self, '_consistencies', None)
+ if consistencies is None:
+ self._consistencies = [cons]
+ else:
+ consistencies.append(cons)
+
+ def _del_consistency(self):
+ self._consistencies.pop(-1)
+
+ def _get_consistencies(self):
+ return getattr(self, '_consistencies', STATIC_TUPLE)
+
+ def _has_consistencies(self):
+ return hasattr(self, '_consistencies')
class _RegexpOption(Option):
from ..i18n import _
from ..setting import groups, undefined, owners # , log
-from .baseoption import BaseOption, SymLinkOption, Option, ALLOWED_CONST_LIST
+from .baseoption import BaseOption
+from .option import Option, ALLOWED_CONST_LIST
from . import MasterSlaves
from ..error import ConfigError, ConflictError
from ..autolib import carry_out_calculation
-name_regexp = re.compile(r'^[a-zA-Z\d\-_]*$')
+NAME_REGEXP = re.compile(r'^[a-zA-Z\d\-_]*$')
import sys
if sys.version_info[0] >= 3: # pragma: no cover
option._dependencies = tuple(options)
option._set_readonly(True)
is_multi = option.impl_is_multi()
- if not isinstance(option, SymLinkOption) and 'force_store_value' in option.impl_getproperties():
+ if not option._is_symlinkoption() and 'force_store_value' in option.impl_getproperties():
force_store_values.append((subpath, option))
for func, all_cons_opts, params in option._get_consistencies():
option._valid_consistencies(all_cons_opts[1:], init=False)
if isinstance(group_type, groups.MasterGroupType):
children = self.impl_getchildren()
for child in children:
- if isinstance(child, SymLinkOption): # pragma: optional cover
+ if child._is_symlinkoption(): # pragma: optional cover
raise ValueError(_("master group {0} shall not have "
"a symlinkoption").format(self.impl_getname()))
if not isinstance(child, Option): # pragma: optional cover
if len(values) > len(set(values)):
raise ConfigError(_('DynOptionDescription callback return not unique value'))
for val in values:
- if not isinstance(val, str) or re.match(name_regexp, val) is None:
+ if not isinstance(val, str) or re.match(NAME_REGEXP, val) is None:
raise ValueError(_("invalid suffix: {0} for option").format(val))
return values
'dynoptiondescription'))
for chld in child._impl_getchildren():
chld._impl_setsubdyn(self)
- if isinstance(child, SymLinkOption):
+ if child._is_symlinkoption():
raise ConfigError(_('cannot set symlinkoption in a '
'dynoptiondescription'))
child._impl_setsubdyn(self)
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class PasswordOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class PortOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
class StrOption(Option):
from ..setting import undefined
from ..i18n import _
-from .baseoption import Option
+from .option import Option
from .domainnameoption import DomainnameOption
from .setting import owners, expires_time, undefined
from .autolib import carry_out_calculation
from .i18n import _
-from .option import SymLinkOption, DynSymLinkOption, Option
-i_i = 0
+from .option import DynSymLinkOption, Option
class Values(object):
was present
:returns: a `setting.owners.Owner` object
"""
- if isinstance(opt, SymLinkOption) and \
+ if opt._is_symlinkoption() and \
not isinstance(opt, DynSymLinkOption):
opt = opt._impl_getopt()
path = opt.impl_getpath(self._getcontext())
for path in _mandatory_warnings(opt, currpath + [name]):
yield path
else:
- if isinstance(opt, SymLinkOption) and \
+ if opt._is_symlinkoption() and \
not isinstance(opt, DynSymLinkOption):
continue
self_properties = settings._getproperties(opt, path,