add some tests for dynoptiondescription + correction

This commit is contained in:
Emmanuel Garette 2018-08-19 09:20:20 +02:00
parent 5f8cd546e7
commit 201f7d2592
12 changed files with 389 additions and 109 deletions

View file

@ -118,8 +118,8 @@ def test_getdoc_dyndescription():
assert api.option('od.dodval2').option.name() == 'dodval2'
assert api.option('od.dodval1.stval1').option.doc() == 'doc1'
assert api.option('od.dodval2.stval2').option.doc() == 'doc1'
assert api.option('od.dodval1').option.doc() == 'doc2'
assert api.option('od.dodval2').option.doc() == 'doc2'
assert api.option('od.dodval1').option.doc() == 'doc2val1'
assert api.option('od.dodval2').option.doc() == 'doc2val2'
def test_mod_dyndescription():
@ -542,6 +542,35 @@ def test_requires_dyndescription():
assert frozenset(props) == frozenset(['disabled'])
def test_requires_dyndescription_in_dyn():
boolean = BoolOption('boolean', '', True)
st = StrOption('st', '', requires=[{'option': boolean, 'expected': False,
'action': 'disabled'}])
dod = DynOptionDescription('dod', '', [boolean, st], callback=return_list)
od = OptionDescription('od', '', [dod])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
cfg.property.read_write()
assert cfg.option('od.dodval1.stval1').value.get() is None
assert cfg.option('od.dodval2.stval2').value.get() is None
#
cfg.option('od.dodval1.booleanval1').value.set(False)
props = []
try:
cfg.option('od.dodval1.stval1').value.get()
except PropertiesOptionError as err:
props = err.proptype
assert props == frozenset(['disabled'])
props = []
cfg.option('od.dodval2.stval2').value.get()
#
cfg.option('od.dodval1.booleanval1').value.set(True)
assert cfg.option('od.dodval1.stval1').value.get() is None
assert cfg.option('od.dodval2.stval2').value.get() is None
def test_requires_dyndescription2():
boolean = BoolOption('boolean', '', True)
st1 = StrOption('st', '')
@ -920,6 +949,219 @@ def test_masterslaves_dyndescription():
assert api.option('od.stval2.st1val2.st1val2').owner.isdefault()
def test_masterslaves_default_multi_dyndescription():
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True, default_multi='no')
stm = MasterSlaves('st1', '', [st1, st2])
st = DynOptionDescription('st', '', [stm], callback=return_list)
od = OptionDescription('od', '', [st])
od2 = OptionDescription('od', '', [od])
api = Config(od2)
owner = api.owner.get()
#
assert api.option('od.stval1.st1val1.st1val1').value.get() == []
assert api.option('od.stval2.st1val2.st1val2').value.get() == []
assert api.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert api.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
api.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert api.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert api.option('od.stval1.st1val1.st2val1', 0).value.get() == 'no'
assert api.option('od.stval2.st1val2.st1val2').value.get() == []
assert api.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert api.option('od.stval1.st1val1.st2val1', 0).owner.isdefault()
assert api.option('od.stval2.st1val2.st1val2').owner.isdefault()
def test_masterslaves_dyndescription_param():
val1 = StrOption('val1', '', ['val1', 'val2'], multi=True)
odval = OptionDescription('odval1', '', [val1])
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True)
stm = MasterSlaves('st1', '', [st1, st2])
st = DynOptionDescription('st', '', [stm], callback=return_list, callback_params=Params(ParamOption(val1)))
od = OptionDescription('od', '', [st, odval])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
owner = cfg.owner.get()
assert cfg.option.make_dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': [], 'od.odval1.val1': ['val1', 'val2']}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.option.make_dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes'], 'od.odval1.val1': ['val1', 'val2']}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == None
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('no')
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == 'no'
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owner
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.pop(0)
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('yes')
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owner
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st2val1', 0).value.reset()
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('yes')
cfg.option('od.stval1.st1val1.st1val1').value.reset()
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
def test_masterslaves_default_multi_dyndescription():
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True, default_multi='no')
stm = MasterSlaves('st1', '', [st1, st2])
st = DynOptionDescription('st', '', [stm], callback=return_list)
od = OptionDescription('od', '', [st])
od2 = OptionDescription('od', '', [od])
api = Config(od2)
owner = api.owner.get()
#
assert api.option('od.stval1.st1val1.st1val1').value.get() == []
assert api.option('od.stval2.st1val2.st1val2').value.get() == []
assert api.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert api.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
api.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert api.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert api.option('od.stval1.st1val1.st2val1', 0).value.get() == 'no'
assert api.option('od.stval2.st1val2.st1val2').value.get() == []
assert api.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert api.option('od.stval1.st1val1.st2val1', 0).owner.isdefault()
assert api.option('od.stval2.st1val2.st1val2').owner.isdefault()
def _test_masterslaves(cfg):
owner = cfg.owner.get()
cfg.option('od.val1.val1').value.set(['val1', 'val2'])
cfg.option('od.val1.val2', 0).value.set('val1')
cfg.option('od.val1.val2', 1).value.set('val2')
assert cfg.option.make_dict() == {'od.stval1.st1val1.st2val1': [], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': [], 'od.val1.val1': ['val1', 'val2'], 'od.val1.val2': ['val1', 'val2']}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert cfg.option.make_dict() == {'od.stval1.st1val1.st2val1': [None], 'od.stval2.st1val2.st2val2': [], 'od.stval2.st1val2.st1val2': [], 'od.stval1.st1val1.st1val1': ['yes'], 'od.val1.val1': ['val1', 'val2'], 'od.val1.val2': ['val1', 'val2']}
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == None
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('no')
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert cfg.option('od.stval1.st1val1.st2val1', 0).value.get() == 'no'
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owner
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.pop(0)
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('yes')
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owner
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st2val1', 0).value.reset()
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert cfg.option('od.stval1.st1val1.st2val1', 0).owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
#
cfg.option('od.stval1.st1val1.st1val1').value.set(['yes'])
cfg.option('od.stval1.st1val1.st2val1', 0).value.set('yes')
cfg.option('od.stval1.st1val1.st1val1').value.reset()
assert cfg.option('od.stval1.st1val1.st1val1').value.get() == []
assert cfg.option('od.stval2.st1val2.st1val2').value.get() == []
assert cfg.option('od.stval1.st1val1.st1val1').owner.get() == owners.default
assert cfg.option('od.stval2.st1val2.st1val2').owner.get() == owners.default
def test_masterslaves_dyndescription_param_master():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True)
odval = MasterSlaves('val1', '', [val1, val2])
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True)
stm = MasterSlaves('st1', '', [st1, st2])
st = DynOptionDescription('st', '', [stm], callback=return_list, callback_params=Params(ParamOption(val1)))
od = OptionDescription('od', '', [st, odval])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
_test_masterslaves(cfg)
def test_masterslaves_default_multi_dyndescription():
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True, default_multi='no')
stm = MasterSlaves('st1', '', [st1, st2])
st = DynOptionDescription('st', '', [stm], callback=return_list)
od = OptionDescription('od', '', [st])
od2 = OptionDescription('od', '', [od])
api = Config(od2)
owner = api.owner.get()
#
assert api.option('od.stval1.st1val1.st1val1').value.get() == []
assert api.option('od.stval2.st1val2.st1val2').value.get() == []
assert api.option('od.stval1.st1val1.st1val1').owner.isdefault()
assert api.option('od.stval2.st1val2.st1val2').owner.isdefault()
#
api.option('od.stval1.st1val1.st1val1').value.set(['yes'])
assert api.option('od.stval1.st1val1.st1val1').value.get() == ['yes']
assert api.option('od.stval1.st1val1.st2val1', 0).value.get() == 'no'
assert api.option('od.stval2.st1val2.st1val2').value.get() == []
assert api.option('od.stval1.st1val1.st1val1').owner.get() == owner
assert api.option('od.stval1.st1val1.st2val1', 0).owner.isdefault()
assert api.option('od.stval2.st1val2.st1val2').owner.isdefault()
def test_masterslaves_dyndescription_param_slave():
val1 = StrOption('val1', "", multi=True)
val2 = StrOption('val2', "", multi=True)
odval = MasterSlaves('val1', '', [val1, val2])
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True)
stm = MasterSlaves('st1', '', [st1, st2])
st = DynOptionDescription('st', '', [stm], callback=return_list, callback_params=Params(ParamOption(val2)))
od = OptionDescription('od', '', [st, odval])
od2 = OptionDescription('od', '', [od])
cfg = Config(od2)
_test_masterslaves(cfg)
def test_masterslaves_default_multi_dyndescription():
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True, default_multi='no')

View file

@ -24,7 +24,6 @@ from typing import Any, Optional, Union, Callable, Dict, List
from .error import PropertiesOptionError, ConfigError, SlaveError
from .i18n import _
from .setting import undefined, ConfigBag, OptionBag, Undefined
from .option.symlinkoption import DynSymLinkOption
from .storage import get_default_values_storages, get_default_settings_storages
from .function import ParamValue, ParamContext, ParamIndex, ParamOption, Params
# ____________________________________________________________
@ -48,13 +47,7 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
return context.duplicate(force_values=get_default_values_storages(),
force_settings=get_default_settings_storages())
opt = callbk.option
if opt.issubdyn():
opt = DynSymLinkOption(opt,
option._rootpath,
option.impl_getsuffix())
path = opt.impl_getpath(context)
else:
path = context.cfgimpl_get_description().impl_get_path_by_opt(opt)
path = opt.impl_getpath(context)
if index is not None and opt.impl_is_master_slaves() and \
opt.impl_get_master_slaves().in_same_group(option):
if opt == option:

View file

@ -123,7 +123,8 @@ class SubConfig(object):
for woption in option_bag.option._get_dependencies(self):
option = woption()
if option.impl_is_dynoptiondescription():
for doption in option.get_syndynoptiondescriptions(option_bag):
for doption in option.get_syndynoptiondescriptions(option_bag,
remove_none=True):
doption_path = doption.impl_getpath(self)
doption_bag = OptionBag()
doption_bag.set_option(doption,

View file

@ -3,7 +3,8 @@ from .dynoptiondescription import DynOptionDescription
from .syndynoptiondescription import SynDynOptionDescription
from .masterslave import MasterSlaves
from .baseoption import submulti
from .symlinkoption import SymLinkOption, DynSymLinkOption
from .symlinkoption import SymLinkOption
from .dynsymlinkoption import DynSymLinkOption
from .option import Option, RegexpOption
from .choiceoption import ChoiceOption
from .booloption import BoolOption

View file

@ -28,6 +28,7 @@ from ..i18n import _
from ..setting import undefined
from ..error import ConfigError, display_list
from ..function import Params, ParamContext, ParamOption, ParamIndex
from .dynsymlinkoption import DynSymLinkOption
STATIC_TUPLE = frozenset()
@ -450,6 +451,13 @@ class BaseOption(Base):
class OnlyOption(BaseOption):
__slots__ = tuple()
def impl_get_dynoption(self,
rootpath,
suffix):
return DynSymLinkOption(self,
rootpath,
suffix)
def validate_requires_arg(new_option,
multi,

View file

@ -71,8 +71,9 @@ class DynOptionDescription(OptionDescription):
raise ConfigError(_('callback is mandatory for the dynoptiondescription "{}"'
'').format(self.impl_get_display_name()))
def _impl_get_suffixes(self,
option_bag):
def impl_get_suffixes(self,
option_bag,
remove_none=False):
callback, callback_params = self.impl_get_callback()
values = carry_out_calculation(self,
option_bag.config_bag.context,
@ -83,18 +84,30 @@ class DynOptionDescription(OptionDescription):
if not isinstance(values, list):
raise ValueError(_('DynOptionDescription callback for option "{}", is not a list ({})'
'').format(self.impl_get_display_name(), values))
if len(values) > len(set(values)):
raise ValueError(_('DynOptionDescription callback return not unique value'))
values_ = []
for val in values:
if not isinstance(val, str) or re.match(NAME_REGEXP, val) is None:
raise ValueError(_('invalid suffix "{}" for option "{}"'
'').format(val,
self.impl_get_display_name()))
return values
if not remove_none or val is not None:
raise ValueError(_('invalid suffix "{}" for option "{}"'
'').format(val,
self.impl_get_display_name()))
else:
values_.append(val)
values = values_
if len(values) > len(set(values)):
extra_values = values.copy()
for val in set(values):
extra_values.remove(val)
raise ValueError(_('DynOptionDescription callback return a list with multiple value '
'"{}"''').format(extra_values))
return values_
def get_syndynoptiondescriptions(self, option_bag):
def get_syndynoptiondescriptions(self,
option_bag,
remove_none=False):
subpath = self.impl_getpath(option_bag.config_bag.context).rsplit('.', 1)[0]
for suffix in self._impl_get_suffixes(option_bag):
for suffix in self.impl_get_suffixes(option_bag,
remove_none=remove_none):
yield SynDynOptionDescription(self,
subpath,
suffix)

View file

@ -0,0 +1,83 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Team tiramisu (see AUTHORS for all contributors)
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# The original `Config` design model is unproudly borrowed from
# 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, OptionBag
class DynSymLinkOption(object):
__slots__ = ('_rootpath',
'_opt',
'_suffix')
def __init__(self,
opt,
rootpath,
suffix):
self._opt = opt
self._rootpath = rootpath
self._suffix = suffix
def __getattr__(self,
name):
return getattr(self._opt, name)
def __eq__(self, left):
if not isinstance(left, DynSymLinkOption):
return False
return self._opt == left._opt and \
self._rootpath == left._rootpath and \
self._suffix == left._suffix
def impl_getname(self):
return self._opt.impl_getname() + self._suffix
def impl_get_display_name(self):
return self._opt.impl_get_display_name(dyn_name=self.impl_getname())
def impl_getopt(self):
return self._opt
def impl_getsuffix(self):
return self._suffix
def impl_getpath(self,
context):
return self._rootpath + '.' + self.impl_getname()
def impl_validate(self,
value,
option_bag,
context=undefined,
check_error=True):
context = option_bag.config_bag.context
soption_bag = OptionBag()
soption_bag.set_option(self._opt,
self.impl_getpath(context),
option_bag.index,
option_bag.config_bag)
soption_bag.ori_option = option_bag.option
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
self._opt.impl_validate(value,
soption_bag,
context=context,
check_error=check_error)
def impl_is_dynsymlinkoption(self):
return True

View file

@ -23,7 +23,6 @@ import warnings
import weakref
from .baseoption import OnlyOption, submulti, STATIC_TUPLE
from .symlinkoption import DynSymLinkOption
from ..i18n import _
from ..setting import log, undefined, debug, OptionBag
from ..autolib import carry_out_calculation
@ -457,7 +456,7 @@ class Option(OnlyOption):
if descr._cache_consistencies is None:
return
# get consistencies for this option
if isinstance(option_bag.option, DynSymLinkOption):
if option_bag.option.impl_is_dynsymlinkoption():
consistencies = descr._cache_consistencies.get(option_bag.option.impl_getopt())
else:
consistencies = descr._cache_consistencies.get(option_bag.option)
@ -475,12 +474,11 @@ class Option(OnlyOption):
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_bag.ori_option, DynSymLinkOption):
if option_bag.ori_option.impl_is_dynsymlinkoption():
opts = []
for opt in all_cons_opts:
opts.append(DynSymLinkOption(opt(),
option_bag.ori_option._rootpath,
option_bag.ori_option._suffix))
opts.append(opt().impl_get_dynoption(option_bag.ori_option._rootpath,
option_bag.ori_option._suffix))
wopt = opts[0]
else:
opts = all_cons_opts

View file

@ -24,7 +24,7 @@ from copy import copy
from ..i18n import _
from ..setting import ConfigBag, OptionBag, groups, undefined, owners
from .baseoption import BaseOption, OnlyOption
from .option import ALLOWED_CONST_LIST, DynSymLinkOption
from .option import ALLOWED_CONST_LIST
from .syndynoptiondescription import SynDynOptionDescription
from ..error import ConfigError, ConflictError
@ -234,12 +234,11 @@ class OptionDescriptionWalk(CacheOptionDescription):
ori_index = len(rootpath) + 1
subpaths = [rootpath] + option.impl_getpath(
option_bag.config_bag.context)[ori_index:].split('.')[:-1]
for suffix in dynopt._impl_get_suffixes(option_bag):
for suffix in dynopt.impl_get_suffixes(option_bag):
subpath = '.'.join([subp + suffix for subp in subpaths])
if isinstance(option, OnlyOption):
yield DynSymLinkOption(option,
subpath,
suffix)
yield option.impl_get_dynoption(subpath,
suffix)
else:
yield SynDynOptionDescription(option,
subpath,
@ -333,7 +332,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
subpath,
None,
config_bag)
for suffix in child._impl_get_suffixes(option_bag):
for suffix in child.impl_get_suffixes(option_bag):
yield SynDynOptionDescription(child,
subpath,
suffix)
@ -360,7 +359,7 @@ class OptionDescriptionWalk(CacheOptionDescription):
subconfig.cfgimpl_get_path(),
None,
config_bag)
for value in child._impl_get_suffixes(option_bag):
for value in child.impl_get_suffixes(option_bag):
if name == cname + value:
return SynDynOptionDescription(child,
subconfig.cfgimpl_get_path(),
@ -375,9 +374,8 @@ class OptionDescriptionWalk(CacheOptionDescription):
subpath,
suffix)
else:
return DynSymLinkOption(child,
subpath,
suffix)
return child.impl_get_dynoption(subpath,
suffix)
class OptionDescription(OptionDescriptionWalk):

View file

@ -20,7 +20,6 @@
# ____________________________________________________________
from .baseoption import OnlyOption
from ..i18n import _
from ..setting import undefined, OptionBag
class SymLinkOption(OnlyOption):
@ -60,65 +59,3 @@ class SymLinkOption(OnlyOption):
def get_consistencies(self):
return ()
class DynSymLinkOption(object):
__slots__ = ('_rootpath',
'_opt',
'_suffix')
def __init__(self,
opt,
rootpath,
suffix):
self._opt = opt
self._rootpath = rootpath
self._suffix = suffix
def __getattr__(self,
name):
return getattr(self._opt, name)
def __eq__(self, left):
if not isinstance(left, DynSymLinkOption):
return False
return self._opt == left._opt and \
self._rootpath == left._rootpath and \
self._suffix == left._suffix
def impl_getname(self):
return self._opt.impl_getname() + self._suffix
def impl_get_display_name(self):
return self._opt.impl_get_display_name(dyn_name=self.impl_getname())
def impl_getopt(self):
return self._opt
def impl_getsuffix(self):
return self._suffix
def impl_getpath(self,
context):
return self._rootpath + '.' + self.impl_getname()
def impl_validate(self,
value,
option_bag,
context=undefined,
check_error=True):
context = option_bag.config_bag.context
soption_bag = OptionBag()
soption_bag.set_option(self._opt,
self.impl_getpath(context),
option_bag.index,
option_bag.config_bag)
soption_bag.ori_option = option_bag.option
soption_bag.fromconsistency = option_bag.fromconsistency.copy()
self._opt.impl_validate(value,
soption_bag,
context=context,
check_error=check_error)
def impl_is_dynsymlinkoption(self):
return True

View file

@ -20,7 +20,6 @@
# ____________________________________________________________
from ..i18n import _
from ..setting import groups, undefined
from .symlinkoption import DynSymLinkOption
class SynDynOptionDescription(object):
@ -81,16 +80,20 @@ class SynDynOptionDescription(object):
def getmaster(self):
master = self._opt.getmaster()
return DynSymLinkOption(master,
self.impl_getpath(None),
self._suffix)
return master.impl_get_dynoption(self.impl_getpath(None),
self._suffix)
def getslaves(self):
subpath = self.impl_getpath(None)
for slave in self._opt.getslaves():
yield DynSymLinkOption(slave,
subpath,
self._suffix)
yield slave.impl_get_dynoption(subpath,
self._suffix)
def impl_get_display_name(self):
return self._opt.impl_get_display_name() + self._suffix
def impl_getdoc(self):
return self._opt.impl_getdoc() + self._suffix
def reset_cache(self,
path,

View file

@ -484,8 +484,11 @@ class Settings(object):
exps, action, inverse, transitive, same_action, operator = require
breaked = False
for option, expected in exps:
if option.issubdyn():
option = option.impl_get_dynoption(option_bag.option._rootpath,
option_bag.option.impl_getsuffix())
reqpath = option.impl_getpath(context)
#FIXME c'est un peu tard !
#FIXME too later!
if reqpath.startswith(option_bag.path + '.'):
raise RequirementError(_("malformed requirements "
"imbrication detected for option:"