add PathConfig

This commit is contained in:
2018-10-31 08:00:19 +01:00
parent 69919535f6
commit f4bf3dc390
37 changed files with 1480 additions and 258 deletions

View File

@ -15,7 +15,7 @@
from .function import Params, ParamOption, ParamValue, ParamContext
from .option import *
from .error import APIError
from .api import Config, MetaConfig, GroupConfig
from .api import Config, MetaConfig, GroupConfig, PathConfig
from .option import __all__ as all_options
from .setting import owners, undefined
@ -25,6 +25,7 @@ allfuncs = ['Params',
'ParamValue',
'ParamContext',
'MetaConfig',
'PathConfig',
'GroupConfig',
'Config',
'APIError',

View File

@ -22,7 +22,7 @@ from typing import List, Any, Optional, Callable, Union, Dict
from .error import APIError, ConfigError, SlaveError, PropertiesOptionError
from .i18n import _
from .setting import ConfigBag, OptionBag, owners, groups, Undefined, undefined, FORBIDDEN_SET_PROPERTIES
from .config import KernelConfig, SubConfig, KernelGroupConfig, KernelMetaConfig
from .config import KernelConfig, SubConfig, KernelGroupConfig, KernelMetaConfig, KernelPathConfig
from .option import ChoiceOption, OptionDescription
@ -227,14 +227,9 @@ class TiramisuOptionOption(CommonTiramisuOption):
name,
subconfig,
option_bag):
cls._name = name
cls._subconfig = subconfig
cls._option_bag = option_bag
cls._get_option(cls)
option = option_bag.option
del cls._name
del cls._subconfig
del cls._option_bag
option = subconfig.cfgimpl_get_description().impl_getchild(name,
option_bag.config_bag,
subconfig.cfgimpl_get_path())
if option.impl_is_optiondescription():
return _TiramisuOptionOptionDescription(name=name,
subconfig=subconfig,
@ -396,7 +391,8 @@ class TiramisuOptionInformation(CommonTiramisuOption):
values = self._option_bag.config_bag.context.cfgimpl_get_values()
values.set_information(key, value, path=path)
def reset(self, key):
def reset(self,
key):
"""Remove information"""
path = self._option_bag.path
values = self._option_bag.config_bag.context.cfgimpl_get_values()
@ -541,7 +537,7 @@ class TiramisuOptionValue(CommonTiramisuOption):
types.append(_TiramisuOptionValueMaster)
elif option.impl_is_master_slaves('slave'):
types.append(_TiramisuOptionValueSlave)
if option_bag.config_bag.context.impl_type == 'meta':
if option_bag.config_bag.context.impl_type in ('meta', 'path'):
# only if not an optiondescription
types.insert(0, _TiramisuOptionValueMeta)
if option_bag.config_bag.context.impl_type == 'group':
@ -657,6 +653,24 @@ class _TiramisuOptionDescription(_TiramisuOption):
"""Get type for an optiondescription (only for optiondescription)"""
return self._get_option().impl_get_group_type()
def _filter(self,
opt,
subconfig):
if self._config_bag.properties:
name = opt.impl_getname()
path = subconfig._get_subpath(name)
option_bag = OptionBag()
option_bag.set_option(opt,
path,
None,
self._config_bag)
if opt.impl_is_optiondescription():
self._subconfig.get_subconfig(name,
option_bag)
else:
subconfig.getattr(name,
option_bag)
def list(self,
type='option',
group_type=None):
@ -664,22 +678,6 @@ class _TiramisuOptionDescription(_TiramisuOption):
assert type in ('all', 'option', 'optiondescription'), _('unknown list type {}').format(type)
assert group_type is None or isinstance(group_type, groups.GroupType), \
_("unknown group_type: {0}").format(group_type)
def _filter(opt):
if self._config_bag.properties:
name = opt.impl_getname()
path = subconfig._get_subpath(name)
option_bag = OptionBag()
option_bag.set_option(opt,
path,
None,
self._config_bag)
if opt.impl_is_optiondescription():
self._subconfig.get_subconfig(name,
option_bag)
else:
subconfig.getattr(name,
option_bag)
option = self._get_option()
name = option.impl_getname()
path = self._subconfig._get_subpath(name)
@ -692,7 +690,8 @@ class _TiramisuOptionDescription(_TiramisuOption):
option_bag)
for opt in option.impl_getchildren(self._config_bag):
try:
subsubconfig = _filter(opt)
subsubconfig = self._filter(opt,
subconfig)
except PropertiesOptionError:
continue
if opt.impl_is_optiondescription():
@ -998,52 +997,64 @@ class TiramisuContextOption(TiramisuContext):
return next(self._find(name, value, type))
return self._find(name, value, type)
def _filter(self,
opt):
if self._config_bag.properties:
name = opt.impl_getname()
option_bag = OptionBag()
option_bag.set_option(opt,
name,
None,
self._config_bag)
if opt.impl_is_optiondescription():
self._config_bag.context.cfgimpl_get_settings().validate_properties(option_bag)
else:
self._config_bag.context.getattr(name,
option_bag)
def _walk(self,
option,
recursive,
type_,
group_type):
for opt in option.impl_getchildren(self._config_bag):
try:
subsubconfig = self._filter(opt)
except PropertiesOptionError:
continue
if opt.impl_is_optiondescription():
if recursive:
for toption in self._walk(opt,
recursive,
type_,
group_type):
yield toption
if type_ == 'option' or (type_ == 'optiondescription' and \
group_type and opt.impl_get_group_type() != group_type):
continue
elif type_ == 'optiondescription':
continue
path = opt.impl_getpath()
subconfig, name = self._config_bag.context.cfgimpl_get_home_by_path(path,
self._config_bag)
yield TiramisuOption(name,
path,
None,
subconfig,
self._config_bag)
def list(self,
type='option',
group_type=None,
recursive=False):
"""List options (by default list only option)"""
def _filter(opt):
if self._config_bag.properties:
name = opt.impl_getname()
option_bag = OptionBag()
option_bag.set_option(opt,
name,
None,
self._config_bag)
if opt.impl_is_optiondescription():
self._config_bag.context.cfgimpl_get_settings().validate_properties(option_bag)
else:
self._config_bag.context.getattr(name,
option_bag)
def _walk(option):
for opt in option.impl_getchildren(self._config_bag):
try:
subsubconfig = _filter(opt)
except PropertiesOptionError:
continue
if opt.impl_is_optiondescription():
if recursive:
for toption in _walk(opt):
yield toption
if type == 'option' or (type == 'optiondescription' and \
group_type and opt.impl_get_group_type() != group_type):
continue
elif type == 'optiondescription':
continue
path = opt.impl_getpath()
subconfig, name = self._config_bag.context.cfgimpl_get_home_by_path(path,
self._config_bag)
yield TiramisuOption(name,
path,
None,
subconfig,
self._config_bag)
assert type in ('all', 'option', 'optiondescription'), _('unknown list type {}').format(type)
assert group_type is None or isinstance(group_type, groups.GroupType), \
_("unknown group_type: {0}").format(group_type)
option = self._config_bag.context.cfgimpl_get_description()
for toption in _walk(option):
for toption in self._walk(option,
recursive,
type,
group_type):
yield toption
@ -1138,6 +1149,11 @@ class _TiramisuContextGroupConfig(TiramisuContext):
return Config(config)
class _TiramisuContextPathConfig(_TiramisuContextGroupConfig, _TiramisuContextConfigReset):
"""Actions to PathConfig"""
pass
class _TiramisuContextMetaConfig(_TiramisuContextGroupConfig, _TiramisuContextConfigReset):
"""Actions to MetaConfig"""
def new(self,
@ -1150,7 +1166,7 @@ class _TiramisuContextMetaConfig(_TiramisuContextGroupConfig, _TiramisuContextCo
type_=type))
def pop(self,
session_id):
session_id):
"""Remove config from MetaConfig"""
return Config(self._config_bag.context.pop_config(session_id=session_id))
@ -1186,6 +1202,8 @@ class TiramisuAPI(TiramisuHelp):
config = _TiramisuContextGroupConfig
elif config_type == 'meta':
config = _TiramisuContextMetaConfig
elif config_type == 'path':
config = _TiramisuContextPathConfig
else:
config = _TiramisuContextConfig
return config(self._config_bag)
@ -1258,6 +1276,26 @@ class MetaConfig(TiramisuAPI):
super().__init__(config)
class PathConfig(TiramisuAPI):
"""MetaConfig object that enables us to handle the sub configuration's options"""
def __init__(self,
optiondescription: OptionDescription,
children: List[Config],
session_id: Optional[str]=None,
persistent: bool=False) -> None:
_children = []
for child in children:
if isinstance(child, TiramisuAPI):
_children.append(child._config_bag.context)
else:
_children.append(child)
config = KernelPathConfig(optiondescription,
_children,
session_id=session_id,
persistent=persistent)
super().__init__(config)
class GroupConfig(TiramisuAPI):
"""GroupConfig that enables us to access the Config"""

View File

@ -300,4 +300,5 @@ def calculate(option,
'').format(str(error),
callback.__name__,
option.impl_get_display_name())
del error
raise ConfigError(msg)

View File

@ -668,7 +668,7 @@ class _CommonConfig(SubConfig):
metaconfig_prefix=None,
child=None,
deep=False):
assert isinstance(self, (KernelConfig, KernelMetaConfig)), _('cannot duplicate {}').format(self.__class__.__name__)
assert isinstance(self, (KernelConfig, KernelPathConfig)), _('cannot duplicate {}').format(self.__class__.__name__)
if isinstance(self, KernelConfig):
duplicated_config = KernelConfig(self._impl_descr,
_duplicate=True,
@ -677,7 +677,7 @@ class _CommonConfig(SubConfig):
force_settings=force_settings,
persistent=persistent,
storage=storage)
elif isinstance(self, KernelMetaConfig):
else:
if session_id is None and metaconfig_prefix is not None:
session_id = metaconfig_prefix + self.impl_getname()
duplicated_config = KernelMetaConfig([],
@ -809,7 +809,7 @@ class KernelGroupConfig(_CommonConfig):
resetted_opts=None):
if resetted_opts is None:
resetted_opts = []
if isinstance(self, KernelMetaConfig):
if isinstance(self, KernelPathConfig):
super().cfgimpl_reset_cache(option_bag,
resetted_opts=copy(resetted_opts))
for child in self._impl_children:
@ -834,15 +834,15 @@ class KernelGroupConfig(_CommonConfig):
for child in self._impl_children:
cconfig_bag = config_bag.copy()
cconfig_bag.context = child
try:
if isinstance(child, KernelGroupConfig):
ret.extend(child.set_value(path,
index,
value,
cconfig_bag,
only_config=only_config,
_commit=commit))
else:
if isinstance(child, KernelGroupConfig):
ret.extend(child.set_value(path,
index,
value,
cconfig_bag,
only_config=only_config,
_commit=commit))
else:
try:
subconfig, name = child.cfgimpl_get_home_by_path(path,
cconfig_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name,
@ -856,16 +856,16 @@ class KernelGroupConfig(_CommonConfig):
child.setattr(value,
option_bag,
_commit=commit)
except PropertiesOptionError as err:
ret.append(PropertiesOptionError(err._option_bag,
err.proptype,
err._settings,
err._opt_type,
err._requires,
err._name,
err._orig_opt))
except (ValueError, SlaveError) as err:
ret.append(err)
except PropertiesOptionError as err:
ret.append(PropertiesOptionError(err._option_bag,
err.proptype,
err._settings,
err._opt_type,
err._requires,
err._name,
err._orig_opt))
except (ValueError, SlaveError, AttributeError) as err:
ret.append(err)
if _commit and self.impl_type != 'group':
self.cfgimpl_get_values()._p_.commit()
return ret
@ -885,7 +885,7 @@ class KernelGroupConfig(_CommonConfig):
#so search only one time the option for all children
if bypath is undefined and byname is not None and \
isinstance(self,
KernelMetaConfig):
KernelPathConfig):
bypath = next(self.find(bytype=None,
byvalue=undefined,
byname=byname,
@ -954,47 +954,30 @@ class KernelGroupConfig(_CommonConfig):
raise ConfigError(_('unknown config "{}"').format(name))
class KernelMetaConfig(KernelGroupConfig):
class KernelPathConfig(KernelGroupConfig):
__slots__ = tuple()
impl_type = 'meta'
impl_type = 'path'
def __init__(self,
optiondescription,
children,
session_id=None,
persistent=False,
optiondescription=None,
storage=None,
_duplicate=False):
descr = None
if optiondescription is not None:
if not _duplicate:
new_children = []
for child_session_id in children:
assert isinstance(child_session_id, str), _('MetaConfig with optiondescription'
' must have string has child, '
'not {}').format(child_session_id)
new_children.append(KernelConfig(optiondescription,
persistent=persistent,
session_id=child_session_id))
children = new_children
descr = optiondescription
# FIXME _duplicate
for child in children:
if not isinstance(child, _CommonConfig):
try:
child = child._config
except:
raise TypeError(_("metaconfig's children "
"should be config, not {0}"
).format(type(child)))
raise TypeError(_("{}config's children "
"should be config, not {}"
).format(self.impl_type,
type(child)))
if child.cfgimpl_get_meta() is not None:
raise ValueError(_("child has already a metaconfig's"))
if descr is None:
descr = child.cfgimpl_get_description()
elif not descr is child.cfgimpl_get_description():
raise ValueError(_('all config in metaconfig must '
'have the same optiondescription'))
raise ValueError(_("child has already a {}config's").format(self.impl_type))
child._impl_meta = weakref.ref(self)
properties, permissives, values, session_id = get_storages(self,
session_id,
persistent,
@ -1004,7 +987,7 @@ class KernelMetaConfig(KernelGroupConfig):
self._impl_values = Values(values)
super().__init__(children,
session_id=session_id,
_descr=descr)
_descr=optiondescription)
self._impl_build_all_caches()
def set_value(self,
@ -1036,41 +1019,49 @@ class KernelMetaConfig(KernelGroupConfig):
if force_default and force_dont_change_value:
raise ValueError(_('force_default and force_dont_change_value'
' cannot be set together'))
opt = self.cfgimpl_get_description().impl_get_opt_by_path(path,
config_bag)
#opt = self.cfgimpl_get_description().impl_get_opt_by_path(path,
# config_bag)
for child in self._impl_children:
cconfig_bag = config_bag.copy()
cconfig_bag.context = child
subconfig, name = child.cfgimpl_get_home_by_path(path,
cconfig_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name,
cconfig_bag,
child.cfgimpl_get_path())
option_bag = OptionBag()
option_bag.set_option(option,
path,
index,
cconfig_bag)
if force_default_if_same:
if not child.cfgimpl_get_values()._p_.hasvalue(path):
child_value = undefined
else:
child_value = child.getattr(name,
option_bag)
if force_default or (force_default_if_same and value == child_value):
child.cfgimpl_get_values().reset(option_bag,
_commit=False)
continue
if force_dont_change_value:
try:
try:
subconfig, name = child.cfgimpl_get_home_by_path(path,
cconfig_bag)
option = subconfig.cfgimpl_get_description().impl_getchild(name,
cconfig_bag,
child.cfgimpl_get_path())
option_bag = OptionBag()
option_bag.set_option(option,
path,
index,
cconfig_bag)
if force_default_if_same:
if not child.cfgimpl_get_values()._p_.hasvalue(path):
child_value = undefined
else:
child_value = child.getattr(name,
option_bag)
if force_default or (force_default_if_same and value == child_value):
child.cfgimpl_get_values().reset(option_bag,
_commit=False)
continue
if force_dont_change_value:
child_value = child.getattr(name,
option_bag)
if value != child_value:
child.setattr(child_value,
option_bag,
_commit=False)
except (PropertiesOptionError, ValueError, SlaveError) as err:
ret.append(err)
except PropertiesOptionError as err:
ret.append(PropertiesOptionError(err._option_bag,
err.proptype,
err._settings,
err._opt_type,
err._requires,
err._name,
err._orig_opt))
except (ValueError, SlaveError, AttributeError) as err:
ret.append(err)
try:
subconfig, name = self.cfgimpl_get_home_by_path(path,
@ -1109,6 +1100,51 @@ class KernelMetaConfig(KernelGroupConfig):
option_bag.config_bag.context = child
child.cfgimpl_get_values().reset(option_bag)
class KernelMetaConfig(KernelPathConfig):
__slots__ = tuple()
impl_type = 'meta'
def __init__(self,
children,
session_id=None,
persistent=False,
optiondescription=None,
storage=None,
_duplicate=False):
descr = None
if optiondescription is not None:
if not _duplicate:
new_children = []
for child_session_id in children:
assert isinstance(child_session_id, str), _('MetaConfig with optiondescription'
' must have string has child, '
'not {}').format(child_session_id)
new_children.append(KernelConfig(optiondescription,
persistent=persistent,
session_id=child_session_id))
children = new_children
descr = optiondescription
for child in children:
if not isinstance(child, _CommonConfig):
try:
child = child._config
except:
raise TypeError(_("{}config's children "
"should be config, not {}"
).format(self.impl_type,
type(child)))
if descr is None:
descr = child.cfgimpl_get_description()
elif descr is not child.cfgimpl_get_description():
raise ValueError(_('all config in metaconfig must '
'have the same optiondescription'))
super().__init__(descr,
children,
persistent=persistent,
storage=storage,
session_id=session_id)
def new_config(self,
session_id,
type_='config',

View File

@ -108,7 +108,7 @@ class ChoiceOption(Option):
current_opt=undefined):
values = self.impl_get_values(option_bag,
current_opt=current_opt)
if values is not undefined and not value in values:
if values is not undefined and value not in values:
if len(values) == 1:
raise ValueError(_('only "{0}" is allowed'
'').format(values[0]))

View File

@ -115,12 +115,9 @@ def get_default_settings_storages():
return properties, permissives
def list_sessions(type_):
def list_sessions():
"""List all available session (persistent or not persistent)
"""
#if type_ == 'option':
# return storage_option_type.get().list_sessions()
#else:
return storage_type.get().list_sessions()