better dynoption support

This commit is contained in:
2018-04-09 21:37:49 +02:00
parent c3be5e82ba
commit 9ea373efdf
17 changed files with 810 additions and 924 deletions

View File

@ -23,7 +23,7 @@ from copy import copy
from ..i18n import _
from ..setting import ConfigBag, groups, undefined, owners
from .baseoption import BaseOption
from .baseoption import BaseOption, OnlyOption
from .option import ALLOWED_CONST_LIST, DynSymLinkOption
from .syndynoptiondescription import SynDynOptionDescription
from ..error import ConfigError, ConflictError
@ -172,7 +172,7 @@ class CacheOptionDescription(BaseOption):
# problem with index
raise ConfigError(_('a slave ({0}) cannot have '
'force_store_value property').format(subpath))
if option._is_subdyn():
if option.issubdyn():
raise ConfigError(_('a dynoption ({0}) cannot have '
'force_store_value property').format(subpath))
if not values._p_.hasvalue(subpath):
@ -225,6 +225,31 @@ class CacheOptionDescription(BaseOption):
class OptionDescriptionWalk(CacheOptionDescription):
__slots__ = ('_children',)
def build_dynoptions(self,
option,
config_bag):
dynopt = option.getsubdyn()
rootpath = self.impl_get_path_by_opt(dynopt)
if rootpath == '':
ori_index = 0
else:
ori_index = len(rootpath) + 1
subpaths = option.impl_getpath(config_bag.config)[ori_index:].split('.')[:-1]
if subpaths != ['']:
subpaths = [rootpath] + subpaths
else:
subpaths = [rootpath]
for suffix in dynopt._impl_get_suffixes(config_bag):
subpath = '.'.join([subp + suffix for subp in subpaths])
if isinstance(option, OnlyOption):
yield DynSymLinkOption(option,
subpath,
suffix)
else:
yield SynDynOptionDescription(option,
subpath,
suffix)
def impl_get_options_paths(self,
bytype,
byname,
@ -233,51 +258,24 @@ class OptionDescriptionWalk(CacheOptionDescription):
config_bag):
find_results = []
def _rebuild_dynpath(path,
suffix,
dynopt):
found = False
spath = path.split('.')
for length in range(1, len(spath)):
subpath = '.'.join(spath[0:length])
subopt = self.impl_get_opt_by_path(subpath)
if dynopt == subopt:
found = True
break
if not found: # pragma: no cover
raise ConfigError(_('cannot find dynpath'))
subpath = subpath + suffix
for slength in range(length, len(spath)):
subpath = subpath + '.' + spath[slength] + suffix
return subpath
def _filter_by_name(path,
option):
name = option.impl_getname()
if option._is_subdyn():
if option.issubdyn():
found = False
if byname.startswith(name):
subdyn = option._subdyn()
for suffix in subdyn._impl_get_suffixes(config_bag):
if byname == name + suffix:
for doption in self.build_dynoptions(option, config_bag):
if byname == doption.impl_getname():
dpath = doption.impl_getpath(config_bag.config)
find_results.append((dpath, doption))
found = True
path = _rebuild_dynpath(path,
suffix,
subdyn)
if '.' in path:
subpath = path.rsplit('.', 1)[0]
else:
subpath = ''
option = DynSymLinkOption(option,
subpath,
suffix)
break
if not found:
return False
else:
if not byname == name:
return False
find_results.append((path, option))
find_results.append((path, option))
return True
def _filter_by_type(path,
@ -287,20 +285,10 @@ class OptionDescriptionWalk(CacheOptionDescription):
#if byname is not None, check option byname in _filter_by_name
#not here
if byname is None:
if option._is_subdyn():
name = option.impl_getname()
for suffix in option._subdyn._impl_get_suffixes(config_bag):
path = _rebuild_dynpath(path,
suffix,
option._subdyn)
if '.' in path:
subpath = path.rsplit('.', 1)[0]
else:
subpath = ''
doption = DynSymLinkOption(option,
subpath,
suffix)
find_results.append((subpath, doption))
if option.issubdyn():
for doption in self.build_dynoptions(option, config_bag):
dpath = doption.impl_getname(config_bag.config)
find_results.append((dpath, doption))
else:
find_results.append((path, option))
return True
@ -322,22 +310,12 @@ class OptionDescriptionWalk(CacheOptionDescription):
if _subpath is not None and not path.startswith(_subpath + '.'):
continue
if bytype == byname is None:
if option._is_subdyn():
name = option.impl_getname()
for suffix in option._subdyn._impl_get_suffixes(config_bag):
path = _rebuild_dynpath(path,
suffix,
option._subdyn)
if '.' in path:
subpath = path.rsplit('.', 1)[0]
else:
subpath = ''
doption = DynSymLinkOption(option,
subpath,
suffix)
find_results.append((path, doption))
if option.issubdyn():
for doption in self.build_dynoptions(option, config_bag):
dpath = doption.impl_getpath(config_bag.config)
find_results.append((dpath, doption))
else:
find_results.append((path, option))
find_results.append((dpath, option))
else:
if _filter(path, option) is False:
continue
@ -381,24 +359,23 @@ class OptionDescriptionWalk(CacheOptionDescription):
def impl_getchildren(self,
config_bag,
context=None,
dyn=True):
cname = None
subpath = None
for child in self._impl_st_getchildren():
if dyn and child.impl_is_dynoptiondescription():
if context is None:
if config_bag.config is None:
raise ConfigError(_('need context'))
if cname is None:
if context.cfgimpl_get_description() == self:
cname = ''
if subpath is None:
if config_bag.config.cfgimpl_get_description() == self:
subpath = ''
else:
cname = self.impl_getpath(context)
subpath = self.impl_getpath(config_bag.config)
sconfig_bag = config_bag.copy('nooption')
sconfig_bag.option = child
for value in child._impl_get_suffixes(sconfig_bag):
for suffix in child._impl_get_suffixes(sconfig_bag):
yield SynDynOptionDescription(child,
cname,
value)
subpath,
suffix)
else:
yield child