simplify tiramisu/option/optiondescription.py

This commit is contained in:
Emmanuel Garette 2018-11-13 22:10:01 +01:00
parent f04169d5a6
commit 974a178d4b
17 changed files with 302 additions and 360 deletions

View File

@ -50,7 +50,7 @@ def _is_same_opt(opt1, opt2):
def test_od_not_list(): def test_od_not_list():
b = BoolOption('bool', '', multi=True) b = BoolOption('bool', '', multi=True)
raises(ValueError, "OptionDescription('od', '', b)") raises(AssertionError, "OptionDescription('od', '', b)")
def test_str(): def test_str():

View File

@ -88,7 +88,7 @@ def test_deref_option_cache():
return return
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
o._build_cache_option() o._build_cache()
w = weakref.ref(b) w = weakref.ref(b)
del(b) del(b)
assert w() is not None assert w() is not None
@ -101,7 +101,7 @@ def test_deref_optiondescription_cache():
return return
b = BoolOption('b', '') b = BoolOption('b', '')
o = OptionDescription('od', '', [b]) o = OptionDescription('od', '', [b])
o._build_cache_option() o._build_cache()
w = weakref.ref(o) w = weakref.ref(o)
del(b) del(b)
assert w() is not None assert w() is not None

View File

@ -342,7 +342,8 @@ def test_meta_unconsistent():
i4 = IntOption('i4', '', default=2) i4 = IntOption('i4', '', default=2)
od1 = OptionDescription('od1', '', [i1, i2, i3, i4]) od1 = OptionDescription('od1', '', [i1, i2, i3, i4])
od2 = OptionDescription('od2', '', [od1]) od2 = OptionDescription('od2', '', [od1])
od3 = OptionDescription('od3', '', [od1]) i5 = IntOption('i5', '')
od3 = OptionDescription('od3', '', [i5])
conf1 = Config(od2, session_id='conf1') conf1 = Config(od2, session_id='conf1')
conf2 = Config(od2, session_id='conf2') conf2 = Config(od2, session_id='conf2')
conf3 = Config(od2, session_id='conf3') conf3 = Config(od2, session_id='conf3')

View File

@ -291,7 +291,9 @@ def test_mix_unconsistent():
conf1 = Config(od2, session_id='conf1') conf1 = Config(od2, session_id='conf1')
conf2 = Config(od2, session_id='conf2') conf2 = Config(od2, session_id='conf2')
conf3 = Config(od2, session_id='conf3') conf3 = Config(od2, session_id='conf3')
conf4 = Config(od3, session_id='conf4') i5 = IntOption('i5', '')
od4 = OptionDescription('od4', '', [i5])
conf4 = Config(od4, session_id='conf4')
mix = MixConfig(od2, [conf1, conf2]) mix = MixConfig(od2, [conf1, conf2])
mix.owner.set(owners.mix1) mix.owner.set(owners.mix1)
raises(TypeError, 'MixConfig(od2, "string")') raises(TypeError, 'MixConfig(od2, "string")')

View File

@ -45,7 +45,6 @@ def test_option_get_information():
raises(ValueError, "i.impl_get_information('noinfo')") raises(ValueError, "i.impl_get_information('noinfo')")
assert i.impl_get_information('noinfo', 'default') == 'default' assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description assert i.impl_get_information('doc') == description
assert i.impl_getdoc() == description
def test_option_get_information_config(): def test_option_get_information_config():
@ -61,7 +60,6 @@ def test_option_get_information_config():
raises(ValueError, "i.impl_get_information('noinfo')") raises(ValueError, "i.impl_get_information('noinfo')")
assert i.impl_get_information('noinfo', 'default') == 'default' assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description assert i.impl_get_information('doc') == description
assert i.impl_getdoc() == description
def test_option_get_information_config2(): def test_option_get_information_config2():
@ -77,7 +75,6 @@ def test_option_get_information_config2():
raises(ValueError, "i.impl_get_information('noinfo')") raises(ValueError, "i.impl_get_information('noinfo')")
assert i.impl_get_information('noinfo', 'default') == 'default' assert i.impl_get_information('noinfo', 'default') == 'default'
assert i.impl_get_information('doc') == description assert i.impl_get_information('doc') == description
assert i.impl_getdoc() == description
def test_optiondescription_get_information(): def test_optiondescription_get_information():
@ -89,7 +86,6 @@ def test_optiondescription_get_information():
raises(ValueError, "o.impl_get_information('noinfo')") raises(ValueError, "o.impl_get_information('noinfo')")
assert o.impl_get_information('noinfo', 'default') == 'default' assert o.impl_get_information('noinfo', 'default') == 'default'
assert o.impl_get_information('doc') == description assert o.impl_get_information('doc') == description
assert o.impl_getdoc() == description
def test_option_isoptiondescription(): def test_option_isoptiondescription():

View File

@ -81,9 +81,9 @@ class CommonTiramisu(TiramisuHelp):
def _get_option(self) -> Any: def _get_option(self) -> Any:
option = self._option_bag.option option = self._option_bag.option
if option is None: if option is None:
option = self._subconfig.cfgimpl_get_description().impl_getchild(self._name, option = self._subconfig.cfgimpl_get_description().get_child(self._name,
self._option_bag.config_bag, self._option_bag.config_bag,
self._subconfig.cfgimpl_get_path()) self._subconfig.cfgimpl_get_path())
self._option_bag.set_option(option, self._option_bag.set_option(option,
self._option_bag.path, self._option_bag.path,
self._option_bag.index, self._option_bag.index,
@ -227,9 +227,9 @@ class TiramisuOptionOption(CommonTiramisuOption):
name, name,
subconfig, subconfig,
option_bag): option_bag):
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
option_bag.config_bag, option_bag.config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
if option.impl_is_optiondescription(): if option.impl_is_optiondescription():
return _TiramisuOptionOptionDescription(name=name, return _TiramisuOptionOptionDescription(name=name,
subconfig=subconfig, subconfig=subconfig,
@ -523,9 +523,9 @@ class TiramisuOptionValue(CommonTiramisuOption):
subconfig, subconfig,
option_bag): option_bag):
if subconfig is not None: if subconfig is not None:
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
option_bag.config_bag, option_bag.config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
else: else:
option = None option = None
types = [CommonTiramisuOption] types = [CommonTiramisuOption]
@ -628,9 +628,9 @@ class _TiramisuOptionDescription(_TiramisuOption):
# #
# def get(self, name): # def get(self, name):
# self._get_option() # self._get_option()
# current_option = self._option_bag.option.impl_getchild(name, # current_option = self._option_bag.option.get_child(name,
# self._config_bag, # self._config_bag,
# self._subconfig.cfgimpl_get_path) # self._subconfig.cfgimpl_get_path)
# path = self._option_bag.path + '.' + name # path = self._option_bag.path + '.' + name
# option_bag= OptionBag() # option_bag= OptionBag()
# option_bag.set_option(current_option, # option_bag.set_option(current_option,
@ -688,7 +688,7 @@ class _TiramisuOptionDescription(_TiramisuOption):
self._config_bag) self._config_bag)
subconfig = self._subconfig.get_subconfig(name, subconfig = self._subconfig.get_subconfig(name,
option_bag) option_bag)
for opt in option.impl_getchildren(self._config_bag): for opt in option.get_children(self._config_bag):
try: try:
subsubconfig = self._filter(opt, subsubconfig = self._filter(opt,
subconfig) subconfig)
@ -717,9 +717,9 @@ class TiramisuOption(CommonTiramisuOption):
subconfig: Union[None, KernelConfig, SubConfig]=None, subconfig: Union[None, KernelConfig, SubConfig]=None,
config_bag: Optional[ConfigBag]=None) -> None: config_bag: Optional[ConfigBag]=None) -> None:
if subconfig: if subconfig:
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
config_bag, config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
if option.impl_is_optiondescription(): if option.impl_is_optiondescription():
return _TiramisuOptionDescription(name=name, return _TiramisuOptionDescription(name=name,
path=path, path=path,
@ -1024,7 +1024,7 @@ class TiramisuContextOption(TiramisuContext):
recursive, recursive,
type_, type_,
group_type): group_type):
for opt in option.impl_getchildren(self._config_bag): for opt in option.get_children(self._config_bag):
try: try:
subsubconfig = self._filter(opt) subsubconfig = self._filter(opt)
except PropertiesOptionError: except PropertiesOptionError:
@ -1269,7 +1269,7 @@ class MetaConfig(TiramisuAPI):
children, children,
session_id: Union[str, None]=None, session_id: Union[str, None]=None,
persistent: bool=False, persistent: bool=False,
optiondescription: Union[OptionDescription, None]=None) -> None: optiondescription: Optional[OptionDescription]=None) -> None:
_children = [] _children = []
for child in children: for child in children:
if isinstance(child, TiramisuAPI): if isinstance(child, TiramisuAPI):
@ -1309,7 +1309,7 @@ class GroupConfig(TiramisuAPI):
"""GroupConfig that enables us to access the Config""" """GroupConfig that enables us to access the Config"""
def __init__(self, def __init__(self,
children, children,
session_id: Union[str, None]=None) -> None: session_id: Optional[str]=None) -> None:
_children = [] _children = []
for child in children: for child in children:
if isinstance(child, TiramisuAPI): if isinstance(child, TiramisuAPI):

View File

@ -48,8 +48,8 @@ def manager_callback(callbk: Union[ParamOption, ParamValue],
force_settings=get_default_settings_storages()) force_settings=get_default_settings_storages())
opt = callbk.option opt = callbk.option
if opt.issubdyn(): if opt.issubdyn():
opt = opt.impl_get_dynoption(option._rootpath, opt = opt.to_dynoption(option._rootpath,
option.impl_getsuffix()) option.impl_getsuffix())
path = opt.impl_getpath() path = opt.impl_getpath()
if index is not None and opt.impl_is_master_slaves() and \ if index is not None and opt.impl_is_master_slaves() and \
opt.impl_get_master_slaves().in_same_group(option): opt.impl_get_master_slaves().in_same_group(option):

View File

@ -130,13 +130,13 @@ class SubConfig(object):
resetted_opts, resetted_opts,
doption_bag) doption_bag)
elif option.issubdyn(): elif option.issubdyn():
doption_bag = OptionBag() dynopt = option.getsubdyn()
doption_path = option.impl_getpath() rootpath = dynopt.impl_getpath()
doption_bag.set_option(option, subpaths = [rootpath] + option.impl_getpath()[len(rootpath) + 1:].split('.')[:-1]
doption_path, for suffix in dynopt.impl_get_suffixes(option_bag.config_bag):
option_bag.index, subpath = '.'.join([subp + suffix for subp in subpaths])
option_bag.config_bag) doption = option.to_dynoption(subpath,
for doption in desc.get_dynoptions(doption_bag): suffix)
doption_path = doption.impl_getpath() doption_path = doption.impl_getpath()
doption_bag = OptionBag() doption_bag = OptionBag()
doption_bag.set_option(doption, doption_bag.set_option(doption,
@ -197,9 +197,9 @@ class SubConfig(object):
path = path.split('.') path = path.split('.')
for step in path[:-1]: for step in path[:-1]:
option_bag = OptionBag() option_bag = OptionBag()
option = self.cfgimpl_get_description().impl_getchild(step, option = self.cfgimpl_get_description().get_child(step,
config_bag, config_bag,
self.cfgimpl_get_path()) self.cfgimpl_get_path())
subpath = self._get_subpath(step) subpath = self._get_subpath(step)
option_bag.set_option(option, option_bag.set_option(option,
subpath, subpath,
@ -236,9 +236,10 @@ class SubConfig(object):
raise ConfigError(_("can't assign to a SymLinkOption")) raise ConfigError(_("can't assign to a SymLinkOption"))
context = option_bag.config_bag.context context = option_bag.config_bag.context
context.cfgimpl_get_settings().validate_properties(option_bag) context.cfgimpl_get_settings().validate_properties(option_bag)
self.cfgimpl_get_description().impl_validate_value(option_bag.option, if option_bag.option.impl_is_master_slaves('master'):
value, self.cfgimpl_get_description().impl_validate_value(option_bag.option,
self) value,
self)
return context.cfgimpl_get_values().setvalue(value, return context.cfgimpl_get_values().setvalue(value,
option_bag, option_bag,
_commit) _commit)
@ -346,7 +347,8 @@ class SubConfig(object):
_subpath=None, _subpath=None,
raise_if_not_found=True, raise_if_not_found=True,
only_path=undefined, only_path=undefined,
only_option=undefined): only_option=undefined,
with_option=False):
""" """
convenience method for finding an option that lives only in the subtree convenience method for finding an option that lives only in the subtree
@ -368,9 +370,9 @@ class SubConfig(object):
if only_path is not undefined: if only_path is not undefined:
options = [only_option] options = [only_option]
else: else:
options = self.cfgimpl_get_description().impl_get_options(bytype, options = self.cfgimpl_get_description().get_children_recursively(bytype,
byname, byname,
config_bag) config_bag)
context = self.cfgimpl_get_context() context = self.cfgimpl_get_context()
for option in options: for option in options:
option_bag = OptionBag() option_bag = OptionBag()
@ -390,14 +392,17 @@ class SubConfig(object):
else: else:
subconfig = self subconfig = self
subpath = path subpath = path
subconfig.cfgimpl_get_description().impl_getchild(subpath, subconfig.cfgimpl_get_description().get_child(subpath,
config_bag, config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
self.cfgimpl_get_settings().validate_properties(option_bag) self.cfgimpl_get_settings().validate_properties(option_bag)
except PropertiesOptionError: except PropertiesOptionError:
continue continue
found = True found = True
yield path if not with_option:
yield path
else:
yield path, option
self._find_return_results(found, self._find_return_results(found,
raise_if_not_found) raise_if_not_found)
@ -491,9 +496,9 @@ class SubConfig(object):
else: else:
subconfig = context subconfig = context
subpath = path subpath = path
opt = subconfig.cfgimpl_get_description().impl_getchild(subpath, opt = subconfig.cfgimpl_get_description().get_child(subpath,
config_bag, config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
soption_bag = OptionBag() soption_bag = OptionBag()
soption_bag.set_option(opt, soption_bag.set_option(opt,
path, path,
@ -521,7 +526,8 @@ class SubConfig(object):
#withoption can be set to None below ! #withoption can be set to None below !
if withoption is None: if withoption is None:
for opt in self.cfgimpl_get_description().impl_getchildren(config_bag, context): for opt in self.cfgimpl_get_description().get_children(config_bag,
context):
name = opt.impl_getname() name = opt.impl_getname()
path = self._get_subpath(name) path = self._get_subpath(name)
soption_bag = OptionBag() soption_bag = OptionBag()
@ -618,9 +624,9 @@ class _CommonConfig(SubConfig):
def _impl_build_all_caches(self): def _impl_build_all_caches(self):
descr = self.cfgimpl_get_description() descr = self.cfgimpl_get_description()
if not descr.impl_already_build_caches(): if not descr.impl_already_build_caches():
descr._build_cache_option() descr._build_cache()
descr._build_cache(self) config_bag = ConfigBag(context=self)
descr.impl_build_force_store_values(self) descr.impl_build_force_store_values(config_bag)
def cfgimpl_get_path(self, dyn=True): def cfgimpl_get_path(self, dyn=True):
return None return None
@ -849,9 +855,9 @@ class KernelGroupConfig(_CommonConfig):
try: try:
subconfig, name = child.cfgimpl_get_home_by_path(path, subconfig, name = child.cfgimpl_get_home_by_path(path,
cconfig_bag) cconfig_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
cconfig_bag, cconfig_bag,
child.cfgimpl_get_path()) child.cfgimpl_get_path())
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(option, option_bag.set_option(option,
path, path,
@ -885,19 +891,18 @@ class KernelGroupConfig(_CommonConfig):
_sub=False): _sub=False):
"""Find first not in current KernelGroupConfig, but in each children """Find first not in current KernelGroupConfig, but in each children
""" """
#if KernelMetaConfig, all children have same OptionDescription in context # if KernelMetaConfig, all children have same OptionDescription in
#so search only one time the option for all children # context so search only one time the option for all children
if bypath is undefined and byname is not None and \ if bypath is undefined and byname is not None and \
isinstance(self, isinstance(self,
KernelMixConfig): KernelMixConfig):
bypath = next(self.find(bytype=None, bypath, byoption = next(self.find(bytype=None,
byvalue=undefined, byvalue=undefined,
byname=byname, byname=byname,
config_bag=config_bag, config_bag=config_bag,
raise_if_not_found=raise_if_not_found)) raise_if_not_found=raise_if_not_found,
with_option=True))
byname = None byname = None
byoption = self.cfgimpl_get_description().impl_get_opt_by_path(bypath,
config_bag)
ret = [] ret = []
for child in self._impl_children: for child in self._impl_children:
@ -939,9 +944,9 @@ class KernelGroupConfig(_CommonConfig):
config_bag.remove_validation() config_bag.remove_validation()
subconfig, name = child.cfgimpl_get_home_by_path(path, subconfig, name = child.cfgimpl_get_home_by_path(path,
config_bag) config_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
config_bag, config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(option, option_bag.set_option(option,
path, path,
@ -1024,9 +1029,9 @@ class KernelMixConfig(KernelGroupConfig):
ret = [] ret = []
subconfig, name = self.cfgimpl_get_home_by_path(path, subconfig, name = self.cfgimpl_get_home_by_path(path,
config_bag) config_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
config_bag, config_bag,
self.cfgimpl_get_path()) self.cfgimpl_get_path())
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(option, option_bag.set_option(option,
path, path,
@ -1040,17 +1045,17 @@ class KernelMixConfig(KernelGroupConfig):
cconfig_bag = config_bag.copy() cconfig_bag = config_bag.copy()
cconfig_bag.context = child cconfig_bag.context = child
try: try:
subconfig2, name = child.cfgimpl_get_home_by_path(path,
cconfig_bag)
if self.impl_type == 'meta': if self.impl_type == 'meta':
moption_bag = option_bag moption_bag = option_bag
del moption_bag.properties del moption_bag.properties
del moption_bag.permissives del moption_bag.permissives
moption_bag.config_bag = cconfig_bag moption_bag.config_bag = cconfig_bag
else: else:
subconfig, name = child.cfgimpl_get_home_by_path(path, option = subconfig2.cfgimpl_get_description().get_child(name,
cconfig_bag) cconfig_bag,
option = subconfig.cfgimpl_get_description().impl_getchild(name, child.cfgimpl_get_path())
cconfig_bag,
child.cfgimpl_get_path())
moption_bag = OptionBag() moption_bag = OptionBag()
moption_bag.set_option(option, moption_bag.set_option(option,
path, path,
@ -1060,8 +1065,8 @@ class KernelMixConfig(KernelGroupConfig):
if not child.cfgimpl_get_values()._p_.hasvalue(path): if not child.cfgimpl_get_values()._p_.hasvalue(path):
child_value = undefined child_value = undefined
else: else:
child_value = child.getattr(name, child_value = subconfig2.getattr(name,
moption_bag) moption_bag)
if force_default or (force_default_if_same and value == child_value): if force_default or (force_default_if_same and value == child_value):
child.cfgimpl_get_values().reset(moption_bag, child.cfgimpl_get_values().reset(moption_bag,
_commit=False) _commit=False)
@ -1070,9 +1075,9 @@ class KernelMixConfig(KernelGroupConfig):
child_value = child.getattr(name, child_value = child.getattr(name,
moption_bag) moption_bag)
if value != child_value: if value != child_value:
child.setattr(child_value, subconfig2.setattr(child_value,
moption_bag, moption_bag,
_commit=False) _commit=False)
except PropertiesOptionError as err: except PropertiesOptionError as err:
ret.append(PropertiesOptionError(err._option_bag, ret.append(PropertiesOptionError(err._option_bag,
err.proptype, err.proptype,
@ -1089,9 +1094,9 @@ class KernelMixConfig(KernelGroupConfig):
del option_bag.properties del option_bag.properties
del option_bag.permissives del option_bag.permissives
option_bag.config_bag = config_bag option_bag.config_bag = config_bag
self.setattr(value, subconfig.setattr(value,
option_bag, option_bag,
_commit=False) _commit=False)
except (PropertiesOptionError, ValueError, SlaveError) as err: except (PropertiesOptionError, ValueError, SlaveError) as err:
ret.append(err) ret.append(err)
return ret return ret
@ -1106,9 +1111,9 @@ class KernelMixConfig(KernelGroupConfig):
if self.impl_type == 'meta': if self.impl_type == 'meta':
subconfig, name = self.cfgimpl_get_home_by_path(path, subconfig, name = self.cfgimpl_get_home_by_path(path,
config_bag) config_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
config_bag, config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(option, option_bag.set_option(option,
path, path,
@ -1118,9 +1123,9 @@ class KernelMixConfig(KernelGroupConfig):
try: try:
subconfig, name = self.cfgimpl_get_home_by_path(path, subconfig, name = self.cfgimpl_get_home_by_path(path,
config_bag) config_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
config_bag, config_bag,
subconfig.cfgimpl_get_path()) subconfig.cfgimpl_get_path())
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(option, option_bag.set_option(option,
path, path,
@ -1137,9 +1142,9 @@ class KernelMixConfig(KernelGroupConfig):
else: else:
subconfig, name = child.cfgimpl_get_home_by_path(path, subconfig, name = child.cfgimpl_get_home_by_path(path,
rconfig_bag) rconfig_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name, option = subconfig.cfgimpl_get_description().get_child(name,
rconfig_bag, rconfig_bag,
child.cfgimpl_get_path()) child.cfgimpl_get_path())
moption_bag = OptionBag() moption_bag = OptionBag()
moption_bag.set_option(option, moption_bag.set_option(option,
path, path,

View File

@ -23,12 +23,15 @@ from types import FunctionType
import weakref import weakref
from inspect import signature from inspect import signature
from itertools import chain from itertools import chain
from typing import Union
from ..i18n import _ from ..i18n import _
from ..setting import undefined from ..setting import undefined
from ..error import ConfigError, display_list from ..error import ConfigError, display_list
from ..function import Params, ParamContext, ParamOption, ParamIndex from ..function import Params, ParamContext, ParamOption, ParamIndex
from .dynsymlinkoption import DynSymLinkOption from .dynsymlinkoption import DynSymLinkOption
from .syndynoptiondescription import SynDynOptionDescription
STATIC_TUPLE = frozenset() STATIC_TUPLE = frozenset()
@ -425,7 +428,7 @@ class BaseOption(Base):
def impl_get_display_name(self, def impl_get_display_name(self,
dyn_name=None): dyn_name=None):
name = self.impl_getdoc() name = self.impl_get_information('doc')
if name is None or name == '': if name is None or name == '':
if dyn_name is not None: if dyn_name is not None:
name = dyn_name name = dyn_name
@ -446,13 +449,13 @@ class BaseOption(Base):
def impl_is_symlinkoption(self): def impl_is_symlinkoption(self):
return False return False
def to_dynoption(self,
class OnlyOption(BaseOption): rootpath: str,
__slots__ = tuple() suffix: str) -> Union[SynDynOptionDescription, DynSymLinkOption]:
if self.impl_is_optiondescription():
def impl_get_dynoption(self, return SynDynOptionDescription(self,
rootpath, rootpath,
suffix): suffix)
return DynSymLinkOption(self, return DynSymLinkOption(self,
rootpath, rootpath,
suffix) suffix)

View File

@ -54,7 +54,7 @@ class DynOptionDescription(OptionDescription):
if child.impl_get_group_type() != groups.master: if child.impl_get_group_type() != groups.master:
raise ConfigError(_('cannot set optiondescription in a ' raise ConfigError(_('cannot set optiondescription in a '
'dynoptiondescription')) 'dynoptiondescription'))
for chld in child.impl_getchildren(config_bag=undefined): for chld in child.get_children(config_bag=undefined):
chld._setsubdyn(self) chld._setsubdyn(self)
if child.impl_is_symlinkoption(): if child.impl_is_symlinkoption():
raise ConfigError(_('cannot set symlinkoption in a ' raise ConfigError(_('cannot set symlinkoption in a '
@ -111,3 +111,6 @@ class DynOptionDescription(OptionDescription):
yield SynDynOptionDescription(self, yield SynDynOptionDescription(self,
subpath, subpath,
suffix) suffix)
def impl_is_dynoptiondescription(self):
return True

View File

@ -219,10 +219,9 @@ class MasterSlaves(OptionDescription):
option, option,
value, value,
context): context):
if option.impl_is_master_slaves('master') and isinstance(value, list): if isinstance(value, list) and len(value) < context._impl_length:
if len(value) < context._impl_length: raise SlaveError(_('cannot reduce length of the master "{}"'
raise SlaveError(_('cannot reduce length of the master "{}"' '').format(option.impl_get_display_name()))
'').format(option.impl_get_display_name()))
def impl_is_master_slaves(self, *args, **kwargs): def impl_is_master_slaves(self, *args, **kwargs):
return True return True

View File

@ -23,7 +23,7 @@ import warnings
import weakref import weakref
from typing import Any, List, Callable, Optional from typing import Any, List, Callable, Optional
from .baseoption import OnlyOption, submulti, STATIC_TUPLE from .baseoption import BaseOption, submulti, STATIC_TUPLE
from ..i18n import _ from ..i18n import _
from ..setting import log, undefined, OptionBag from ..setting import log, undefined, OptionBag
from ..autolib import carry_out_calculation from ..autolib import carry_out_calculation
@ -33,7 +33,7 @@ from ..function import Params, ParamValue
ALLOWED_CONST_LIST = ['_cons_not_equal'] ALLOWED_CONST_LIST = ['_cons_not_equal']
class Option(OnlyOption): class Option(BaseOption):
""" """
Abstract base class for configuration option's. Abstract base class for configuration option's.
@ -179,10 +179,6 @@ class Option(OnlyOption):
def impl_is_dynsymlinkoption(self): def impl_is_dynsymlinkoption(self):
return False return False
def impl_getdoc(self):
"accesses the Option's doc"
return self.impl_get_information('doc')
def impl_getdefault(self): def impl_getdefault(self):
"accessing the default value" "accessing the default value"
is_multi = self.impl_is_multi() is_multi = self.impl_is_multi()
@ -472,7 +468,7 @@ class Option(OnlyOption):
def has_consistencies(self, context): def has_consistencies(self, context):
descr = context.cfgimpl_get_description() descr = context.cfgimpl_get_description()
if descr._cache_consistencies is None: if getattr(descr, '_cache_consistencies', None) is None:
return False return False
return self in descr._cache_consistencies return self in descr._cache_consistencies
@ -484,7 +480,7 @@ class Option(OnlyOption):
if option_bag.config_bag is not undefined: if option_bag.config_bag is not undefined:
descr = option_bag.config_bag.context.cfgimpl_get_description() descr = option_bag.config_bag.context.cfgimpl_get_description()
# no consistency found at all # no consistency found at all
if descr._cache_consistencies is None: if getattr(descr, '_cache_consistencies', None) is None:
return return
# get consistencies for this option # get consistencies for this option
consistencies = descr._cache_consistencies.get(option_bag.option) consistencies = descr._cache_consistencies.get(option_bag.option)
@ -515,8 +511,8 @@ class Option(OnlyOption):
if option_bag.ori_option.impl_is_dynsymlinkoption(): if option_bag.ori_option.impl_is_dynsymlinkoption():
opts = [] opts = []
for opt in all_cons_opts: for opt in all_cons_opts:
opts.append(opt().impl_get_dynoption(option_bag.ori_option._rootpath, opts.append(opt().to_dynoption(option_bag.ori_option._rootpath,
option_bag.ori_option._suffix)) option_bag.ori_option._suffix))
wopt = opts[0] wopt = opts[0]
else: else:
opts = all_cons_opts opts = all_cons_opts
@ -571,12 +567,12 @@ class Option(OnlyOption):
opt._has_dependency = True opt._has_dependency = True
def launch_consistency(self, def launch_consistency(self,
current_opt: OnlyOption, current_opt: BaseOption,
func: Callable, func: Callable,
cons_id: int, cons_id: int,
option_bag: OptionBag, option_bag: OptionBag,
value: Any, value: Any,
opts: List[OnlyOption], opts: List[BaseOption],
warnings_only: bool, warnings_only: bool,
transitive: bool): transitive: bool):
"""Launch consistency now """Launch consistency now

View File

@ -19,72 +19,78 @@
# the whole pypy projet is under MIT licence # the whole pypy projet is under MIT licence
# ____________________________________________________________ # ____________________________________________________________
from copy import copy from copy import copy
from typing import Optional, Iterator, Union, List
from ..i18n import _ from ..i18n import _
from ..setting import ConfigBag, OptionBag, groups, undefined, owners from ..setting import ConfigBag, OptionBag, groups, undefined, owners, Undefined
from .baseoption import BaseOption, OnlyOption from .baseoption import BaseOption
from .option import ALLOWED_CONST_LIST from .option import ALLOWED_CONST_LIST
from .syndynoptiondescription import SynDynOptionDescription from .syndynoptiondescription import SynDynOptionDescription
from ..error import ConfigError, ConflictError from ..error import ConfigError, ConflictError
class CacheOptionDescription(BaseOption): class CacheOptionDescription(BaseOption):
__slots__ = ('_cache_consistencies', '_cache_force_store_values') __slots__ = ('_cache_consistencies',
'_cache_force_store_values')
def impl_already_build_caches(self) -> bool:
return self.impl_is_readonly()
def _build_cache(self, def _build_cache(self,
config,
path='', path='',
_consistencies=None, _consistencies=None,
_consistencies_id=0, _consistencies_id=0,
currpath: List[str]=None,
cache_option=None, cache_option=None,
force_store_values=None): force_store_values=None) -> None:
"""validate duplicate option and set option has readonly option """validate options and set option has readonly option
""" """
# cache_option is None only when we start to build cache # _consistencies is None only when we start to build cache
if cache_option is None: if _consistencies is None:
if self.impl_is_readonly():
raise ConfigError(_('option description seems to be part of an other '
'config'))
init = True init = True
_consistencies = {} _consistencies = {}
cache_option = [] if __debug__:
cache_option = []
force_store_values = [] force_store_values = []
currpath = []
else: else:
init = False init = False
for option in self.impl_getchildren(config_bag=undefined, if self.impl_is_readonly():
dyn=False): # cache already set
cache_option.append(option) raise ConfigError(_('option description seems to be part of an other '
if path == '': 'config'))
subpath = option.impl_getname() for option in self.get_children(config_bag=undefined,
else: dyn=False):
subpath = path + '.' + option.impl_getname() if __debug__:
cache_option.append(option)
sub_currpath = currpath + [option.impl_getname()]
subpath = '.'.join(sub_currpath)
if isinstance(option, OptionDescription): if isinstance(option, OptionDescription):
option._set_readonly() option._build_cache(subpath,
option._build_cache(config,
subpath,
_consistencies, _consistencies,
_consistencies_id, _consistencies_id,
sub_currpath,
cache_option, cache_option,
force_store_values) force_store_values)
else: else:
option._set_readonly()
is_multi = option.impl_is_multi() is_multi = option.impl_is_multi()
if not option.impl_is_symlinkoption(): if not option.impl_is_symlinkoption():
properties = option.impl_getproperties() properties = option.impl_getproperties()
if 'force_store_value' in properties: if 'force_store_value' in properties:
if option.impl_is_master_slaves('slave'): if __debug__:
# problem with index if option.impl_is_master_slaves('slave'):
raise ConfigError(_('the slave "{0}" cannot have ' # problem with index
'"force_store_value" property').format( raise ConfigError(_('the slave "{0}" cannot have '
option.impl_get_display_name())) '"force_store_value" property').format(
if option.issubdyn(): option.impl_get_display_name()))
raise ConfigError(_('the dynoption "{0}" cannot have ' if option.issubdyn():
'"force_store_value" property').format( raise ConfigError(_('the dynoption "{0}" cannot have '
option.impl_get_display_name())) '"force_store_value" property').format(
option.impl_get_display_name()))
force_store_values.append((subpath, option)) force_store_values.append((subpath, option))
if 'force_default_on_freeze' in properties and \ if __debug__ and 'force_default_on_freeze' in properties and \
'frozen' not in properties and \ 'frozen' not in properties and \
option.impl_is_master_slaves('master'): option.impl_is_master_slaves('master'):
raise ConfigError(_('a master ({0}) cannot have ' raise ConfigError(_('a master ({0}) cannot have '
@ -93,15 +99,14 @@ class CacheOptionDescription(BaseOption):
for cons_id, func, all_cons_opts, params in option.get_consistencies(): for cons_id, func, all_cons_opts, params in option.get_consistencies():
option._valid_consistencies(all_cons_opts[1:], init=False) option._valid_consistencies(all_cons_opts[1:], init=False)
if func not in ALLOWED_CONST_LIST and is_multi: if func not in ALLOWED_CONST_LIST and is_multi:
is_masterslaves = option.impl_is_master_slaves() if __debug__ and not option.impl_is_master_slaves():
if not is_masterslaves:
raise ConfigError(_('malformed consistency option "{0}" ' raise ConfigError(_('malformed consistency option "{0}" '
'must be a masterslaves').format( 'must be a masterslaves').format(
option.impl_getname())) option.impl_getname()))
masterslaves = option.impl_get_master_slaves() masterslaves = option.impl_get_master_slaves()
for weak_opt in all_cons_opts: for weak_opt in all_cons_opts:
opt = weak_opt() opt = weak_opt()
if func not in ALLOWED_CONST_LIST and is_multi: if __debug__ and func not in ALLOWED_CONST_LIST and is_multi:
if not opt.impl_is_master_slaves(): if not opt.impl_is_master_slaves():
raise ConfigError(_('malformed consistency option "{0}" ' raise ConfigError(_('malformed consistency option "{0}" '
'must not be a multi for "{1}"').format( 'must not be a multi for "{1}"').format(
@ -119,10 +124,11 @@ class CacheOptionDescription(BaseOption):
# if context is set to callback, must be reset each time a value change # if context is set to callback, must be reset each time a value change
if hasattr(option, '_has_calc_context'): if hasattr(option, '_has_calc_context'):
self._add_dependency(option) self._add_dependency(option)
is_slave = None
if is_multi: if __debug__:
all_requires = option.impl_getrequires() is_slave = None
if all_requires != tuple(): if is_multi:
all_requires = option.impl_getrequires()
for requires in all_requires: for requires in all_requires:
for require in requires: for require in requires:
#if option in require is a multi: #if option in require is a multi:
@ -144,8 +150,11 @@ class CacheOptionDescription(BaseOption):
raise ValueError(_('malformed requirements option "{0}" ' raise ValueError(_('malformed requirements option "{0}" '
'must not be a multi for "{1}"').format( 'must not be a multi for "{1}"').format(
require_opt.impl_getname(), option.impl_getname())) require_opt.impl_getname(), option.impl_getname()))
if not hasattr(option, '_path'):
option._path = subpath
option._set_readonly()
if init: if init:
if len(cache_option) != len(set(cache_option)): if __debug__ and len(cache_option) != len(set(cache_option)):
for idx in range(1, len(cache_option) + 1): for idx in range(1, len(cache_option) + 1):
opt = cache_option.pop(0) opt = cache_option.pop(0)
if opt in cache_option: if opt in cache_option:
@ -154,7 +163,7 @@ class CacheOptionDescription(BaseOption):
self._cache_consistencies = {} self._cache_consistencies = {}
for weak_opt, cons in _consistencies.items(): for weak_opt, cons in _consistencies.items():
opt = weak_opt() opt = weak_opt()
if opt not in cache_option: if __debug__ and opt not in cache_option:
raise ConfigError(_('consistency with option {0} ' raise ConfigError(_('consistency with option {0} '
'which is not in Config').format( 'which is not in Config').format(
opt.impl_getname())) opt.impl_getname()))
@ -162,69 +171,43 @@ class CacheOptionDescription(BaseOption):
self._cache_force_store_values = force_store_values self._cache_force_store_values = force_store_values
self._set_readonly() self._set_readonly()
def impl_already_build_caches(self):
if hasattr(self, '_cache_consistencies'):
return True
return False
def impl_build_force_store_values(self, def impl_build_force_store_values(self,
context): config_bag: ConfigBag) -> None:
value_setted = False commit = False
values = context.cfgimpl_get_values() if not hasattr(self, '_cache_force_store_values'):
raise ConfigError(_('option description seems to be part of an other '
'config'))
values = config_bag.context.cfgimpl_get_values()
for subpath, option in self._cache_force_store_values: for subpath, option in self._cache_force_store_values:
if not values._p_.hasvalue(subpath): if not values._p_.hasvalue(subpath):
config_bag = ConfigBag(context=context)
option_bag = OptionBag() option_bag = OptionBag()
option_bag.set_option(option, option_bag.set_option(option,
subpath, subpath,
None, None,
config_bag) config_bag)
option_bag.properties = frozenset() option_bag.properties = frozenset()
value = values.getvalue(option_bag)
value_setted = True
values._p_.setvalue(subpath, values._p_.setvalue(subpath,
value, values.getvalue(option_bag),
owners.forced, owners.forced,
None, None,
False) False)
commit = True
if value_setted: if commit:
values._p_.commit() values._p_.commit()
def _build_cache_option(self,
_currpath=None):
if self.impl_is_readonly() or \
(_currpath is None and getattr(self, '_cache_consistencies', None) is not None):
# cache already set
return
if _currpath is None:
save = True
_currpath = []
else:
save = False
for option in self.impl_getchildren(config_bag=undefined,
dyn=False):
attr = option.impl_getname()
path = str('.'.join(_currpath + [attr]))
option._path = path
if option.impl_is_optiondescription():
_currpath.append(attr)
option._build_cache_option(_currpath)
_currpath.pop()
if save and not hasattr(self, '_cache_consistencies'):
self._cache_consistencies = None
class OptionDescriptionWalk(CacheOptionDescription): class OptionDescriptionWalk(CacheOptionDescription):
__slots__ = ('_children',) __slots__ = ('_children',)
def impl_getchild(self, def get_child(self,
name, name: str,
config_bag, config_bag: ConfigBag,
subpath): subpath: str) -> Union[BaseOption, SynDynOptionDescription]:
# if not dyn
if name in self._children[0]: if name in self._children[0]:
return self._children[1][self._children[0].index(name)] return self._children[1][self._children[0].index(name)]
# if dyn
for child in self._children[1]: for child in self._children[1]:
if child.impl_is_dynoptiondescription(): if child.impl_is_dynoptiondescription():
cname = child.impl_getname() cname = child.impl_getname()
@ -238,17 +221,16 @@ class OptionDescriptionWalk(CacheOptionDescription):
'in optiondescription "{1}"' 'in optiondescription "{1}"'
'').format(name, self.impl_getname())) '').format(name, self.impl_getname()))
def impl_getchildren(self, def get_children(self,
config_bag, config_bag: Union[ConfigBag, Undefined],
dyn=True): dyn: bool=True) -> Iterator[Union[BaseOption, SynDynOptionDescription]]:
subpath = None if not dyn or config_bag is undefined or \
config_bag.context.cfgimpl_get_description() == self:
subpath = ''
else:
subpath = self.impl_getpath()
for child in self._children[1]: for child in self._children[1]:
if dyn and child.impl_is_dynoptiondescription(): if dyn and child.impl_is_dynoptiondescription():
if subpath is None:
if config_bag.context.cfgimpl_get_description() == self:
subpath = ''
else:
subpath = self.impl_getpath()
for suffix in child.impl_get_suffixes(config_bag): for suffix in child.impl_get_suffixes(config_bag):
yield SynDynOptionDescription(child, yield SynDynOptionDescription(child,
subpath, subpath,
@ -256,69 +238,22 @@ class OptionDescriptionWalk(CacheOptionDescription):
else: else:
yield child yield child
def impl_get_opt_by_path(self, def get_children_recursively(self,
path, bytype: Optional[BaseOption],
config_bag): byname: Optional[str],
opt = self config_bag: ConfigBag,
subpath = None self_opt: BaseOption=None) -> Iterator[Union[BaseOption, SynDynOptionDescription]]:
for step in path.split('.'):
opt = opt.impl_getchild(step,
config_bag,
subpath)
if subpath is None:
subpath = step
else:
subpath += '.' + step
return opt
def impl_get_options(self,
bytype,
byname,
config_bag,
self_opt=None):
if self_opt is None: if self_opt is None:
self_opt = self self_opt = self
def _filter_by_name(option): for option in self_opt.get_children(config_bag):
return byname is None or option.impl_getname() == byname
for option in self_opt.impl_getchildren(config_bag):
if option.impl_is_optiondescription(): if option.impl_is_optiondescription():
for subopt in option.impl_get_options(bytype, for subopt in option.get_children_recursively(bytype,
byname, byname,
config_bag): config_bag):
yield subopt yield subopt
else: elif (byname is None or option.impl_getname() == byname) and \
if bytype is not None: (bytype is None or isinstance(option, bytype)):
if isinstance(option, bytype) and \ yield option
_filter_by_name(option):
yield option
elif _filter_by_name(option):
yield option
def get_dynoptions(self,
option_bag):
option = option_bag.option
dynopt = option.getsubdyn()
rootpath = dynopt.impl_getpath()
ori_index = len(rootpath) + 1
subpaths = [rootpath] + option.impl_getpath()[ori_index:].split('.')[:-1]
for suffix in dynopt.impl_get_suffixes(option_bag.config_bag):
subpath = '.'.join([subp + suffix for subp in subpaths])
yield self.impl_get_dynchild(option,
suffix,
subpath)
def impl_get_dynchild(self,
child,
suffix,
subpath):
if isinstance(child, OptionDescription):
return SynDynOptionDescription(child,
subpath,
suffix)
else:
return child.impl_get_dynoption(subpath,
suffix)
class OptionDescription(OptionDescriptionWalk): class OptionDescription(OptionDescriptionWalk):
@ -328,68 +263,65 @@ class OptionDescription(OptionDescriptionWalk):
__slots__ = ('_group_type',) __slots__ = ('_group_type',)
def __init__(self, def __init__(self,
name, name: str,
doc, doc: str,
children, children: List[BaseOption],
requires=None, requires=None,
properties=None): properties=None) -> None:
""" """
:param children: a list of options (including optiondescriptions) :param children: a list of options (including optiondescriptions)
""" """
if not isinstance(children, list): assert isinstance(children, list), _('children in optiondescription "{}" '
raise ValueError(_('children in optiondescription "{}" must be a list').format(name)) 'must be a list').format(name)
super().__init__(name, super().__init__(name,
doc=doc, doc=doc,
requires=requires, requires=requires,
properties=properties) properties=properties)
child_names = [] child_names = []
dynopt_names = [] if __debug__:
dynopt_names = []
for child in children: for child in children:
name = child.impl_getname() name = child.impl_getname()
child_names.append(name) child_names.append(name)
if child.impl_is_dynoptiondescription(): if __debug__ and child.impl_is_dynoptiondescription():
dynopt_names.append(name) dynopt_names.append(name)
# before sorting
children_ = (tuple(child_names), tuple(children)) children_ = (tuple(child_names), tuple(children))
# better performance like this if __debug__:
child_names.sort() # better performance like this
old = None child_names.sort()
for child in child_names: old = None
if child == old: for child in child_names:
raise ConflictError(_('duplicate option name: ' if child == old:
'"{0}"').format(child)) raise ConflictError(_('duplicate option name: '
if dynopt_names: '"{0}"').format(child))
for dynopt in dynopt_names: if dynopt_names:
if child != dynopt and child.startswith(dynopt): for dynopt in dynopt_names:
raise ConflictError(_('the option\'s name "{}" start as ' if child != dynopt and child.startswith(dynopt):
'the dynoptiondescription\'s name "{}"').format(child, dynopt)) raise ConflictError(_('the option\'s name "{}" start as '
old = child 'the dynoptiondescription\'s name "{}"').format(child, dynopt))
old = child
self._children = children_ self._children = children_
#self._cache_consistencies = None
# the group_type is useful for filtering OptionDescriptions in a config # the group_type is useful for filtering OptionDescriptions in a config
self._group_type = groups.default self._group_type = groups.default
def impl_is_optiondescription(self): def impl_is_optiondescription(self) -> bool:
return self.__class__.__name__ in ['OptionDescription', return True
'DynOptionDescription',
'SynDynOptionDescription',
'MasterSlaves']
def impl_is_dynoptiondescription(self): def impl_is_dynoptiondescription(self) -> bool:
return self.__class__.__name__ in ['DynOptionDescription',
'SynDynOptionDescription']
def impl_is_master_slaves(self, *args, **kwargs):
return False return False
def impl_getdoc(self): def impl_is_master_slaves(self,
return self.impl_get_information('doc') *args,
**kwargs) -> bool:
return False
# ____________________________________________________________ # ____________________________________________________________
def impl_set_group_type(self, def impl_set_group_type(self,
group_type): group_type: groups.GroupType) -> None:
"""sets a given group object to an OptionDescription """sets a given group object to an OptionDescription
:param group_type: an instance of `GroupType` or `MasterGroupType` :param group_type: an instance of `GroupType` or `MasterGroupType`
@ -406,10 +338,5 @@ class OptionDescription(OptionDescriptionWalk):
raise ConfigError('please use MasterSlaves object instead of OptionDescription') raise ConfigError('please use MasterSlaves object instead of OptionDescription')
self._group_type = group_type self._group_type = group_type
def impl_get_group_type(self): def impl_get_group_type(self) -> groups.GroupType:
return self._group_type return self._group_type
def impl_validate_value(self,
*args,
**kwargs):
pass

View File

@ -18,21 +18,21 @@
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/ # the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
# the whole pypy projet is under MIT licence # the whole pypy projet is under MIT licence
# ____________________________________________________________ # ____________________________________________________________
from .baseoption import OnlyOption from .baseoption import BaseOption
from ..i18n import _ from ..i18n import _
class SymLinkOption(OnlyOption): class SymLinkOption(BaseOption):
__slots__ = ('_opt',) __slots__ = ('_opt',)
def __init__(self, def __init__(self,
name, name: str,
opt): opt: BaseOption) -> None:
if not isinstance(opt, OnlyOption) or \ if not isinstance(opt, BaseOption) or \
opt.impl_is_optiondescription() or \
opt.impl_is_symlinkoption(): opt.impl_is_symlinkoption():
raise ValueError(_('malformed symlinkoption ' raise ValueError(_('malformed symlinkoption must be an option for symlink {0}'
'must be an option ' '').format(name))
'for symlink {0}').format(name))
_setattr = object.__setattr__ _setattr = object.__setattr__
_setattr(self, '_name', name) _setattr(self, '_name', name)
_setattr(self, '_opt', opt) _setattr(self, '_opt', opt)

View File

@ -18,8 +18,12 @@
# the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/ # the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
# the whole pypy projet is under MIT licence # the whole pypy projet is under MIT licence
# ____________________________________________________________ # ____________________________________________________________
from typing import Optional, Iterator, Union
from ..i18n import _ from ..i18n import _
from ..setting import groups, undefined from ..setting import ConfigBag, groups, undefined
#from .baseoption import BaseOption
class SynDynOptionDescription(object): class SynDynOptionDescription(object):
@ -41,20 +45,21 @@ class SynDynOptionDescription(object):
def impl_getopt(self): def impl_getopt(self):
return self._opt return self._opt
def impl_getchild(self, def get_child(self,
name, name: str,
config_bag, config_bag: ConfigBag,
subpath): subpath: str):
try: #FIXME -> Union[BaseOption, SynDynOptionDescription]:
if name.endswith(self._suffix): if name.endswith(self._suffix):
oname = name[:-len(self._suffix)] oname = name[:-len(self._suffix)]
try:
child = self._children[1][self._children[0].index(oname)] child = self._children[1][self._children[0].index(oname)]
return self.impl_get_dynchild(child, except ValueError:
self._suffix, # when oname not in self._children
subpath) pass
except ValueError: else:
# when oname not in self._children return child.to_dynoption(subpath,
pass self._suffix)
raise AttributeError(_('unknown option "{0}" ' raise AttributeError(_('unknown option "{0}" '
'in syndynoptiondescription "{1}"' 'in syndynoptiondescription "{1}"'
'').format(name, self.impl_getname())) '').format(name, self.impl_getname()))
@ -62,25 +67,29 @@ class SynDynOptionDescription(object):
def impl_getname(self): def impl_getname(self):
return self._opt.impl_getname() + self._suffix return self._opt.impl_getname() + self._suffix
def impl_getchildren(self, def impl_is_dynoptiondescription(self):
config_bag, return True
dyn=True):
def get_children(self,
config_bag,
dyn=True):
children = [] children = []
subpath = self.impl_getpath() subpath = self.impl_getpath()
for child in self._opt.impl_getchildren(config_bag): for child in self._opt.get_children(config_bag):
yield self._opt.impl_get_dynchild(child, yield child.to_dynoption(subpath,
self._suffix, self._suffix)
subpath)
def impl_get_options(self,
bytype,
byname,
config_bag):
return self._opt.impl_get_options(bytype,
byname,
config_bag,
self)
def get_children_recursively(self,
bytype, # FIXME : Optional[BaseOption],
byname: Optional[str],
config_bag: ConfigBag,
self_opt=None): # FIXME : BaseOption=None)
# FIXME -> Iterator[Union[BaseOption, SynDynOptionDescription]]:
return self._opt.get_children_recursively(bytype,
byname,
config_bag,
self)
def impl_getpath(self): def impl_getpath(self):
subpath = self._subpath subpath = self._subpath
if subpath != '': if subpath != '':
@ -89,14 +98,14 @@ class SynDynOptionDescription(object):
def getmaster(self): def getmaster(self):
master = self._opt.getmaster() master = self._opt.getmaster()
return master.impl_get_dynoption(self.impl_getpath(), return master.to_dynoption(self.impl_getpath(),
self._suffix) self._suffix)
def getslaves(self): def getslaves(self):
subpath = self.impl_getpath() subpath = self.impl_getpath()
for slave in self._opt.getslaves(): for slave in self._opt.getslaves():
yield slave.impl_get_dynoption(subpath, yield slave.to_dynoption(subpath,
self._suffix) self._suffix)
def impl_get_display_name(self): def impl_get_display_name(self):
return self._opt.impl_get_display_name() + self._suffix return self._opt.impl_get_display_name() + self._suffix

View File

@ -484,8 +484,8 @@ class Settings(object):
breaked = False breaked = False
for option, expected in exps: for option, expected in exps:
if option.issubdyn(): if option.issubdyn():
option = option.impl_get_dynoption(option_bag.option._rootpath, option = option.to_dynoption(option_bag.option._rootpath,
option_bag.option.impl_getsuffix()) option_bag.option.impl_getsuffix())
reqpath = option.impl_getpath() reqpath = option.impl_getpath()
#FIXME too later! #FIXME too later!
if reqpath.startswith(option_bag.path + '.'): if reqpath.startswith(option_bag.path + '.'):

View File

@ -524,7 +524,8 @@ class Values(object):
subconfig, subconfig,
od_config_bag): od_config_bag):
settings = context.cfgimpl_get_settings() settings = context.cfgimpl_get_settings()
for option in description.impl_getchildren(config_bag, context): for option in description.get_children(config_bag,
context):
name = option.impl_getname() name = option.impl_getname()
path = '.'.join(currpath + [name]) path = '.'.join(currpath + [name])