serialize metaconfig/groupconfig

This commit is contained in:
2013-09-30 16:22:08 +02:00
parent 6b7db20716
commit feeb9842f5
4 changed files with 227 additions and 105 deletions

View File

@@ -161,7 +161,7 @@ class SubConfig(object):
def cfgimpl_get_description(self):
if self._impl_descr is None:
raise ConfigError(_('no option description found for this config'
' (may be metaconfig without meta)'))
' (may be GroupConfig)'))
else:
return self._impl_descr
@@ -467,9 +467,9 @@ class SubConfig(object):
return context_descr.impl_get_path_by_opt(descr)
class CommonConfig(SubConfig):
"abstract base class for the Config and the MetaConfig"
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta')
class _CommonConfig(SubConfig):
"abstract base class for the Config, GroupConfig and the MetaConfig"
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta', '_impl_test')
def _impl_build_all_paths(self):
self.cfgimpl_get_description().impl_build_cache()
@@ -508,7 +508,8 @@ class CommonConfig(SubConfig):
return None
def cfgimpl_get_meta(self):
return self._impl_meta
if self._impl_meta is not None:
return self._impl_meta()
# information
def impl_set_information(self, key, value):
@@ -526,37 +527,12 @@ class CommonConfig(SubConfig):
"""
return self._impl_values.get_information(key, default)
# ____________________________________________________________
class Config(CommonConfig):
"main configuration management entry"
__slots__ = ('__weakref__', '_impl_test')
def __init__(self, descr, session_id=None, persistent=False):
""" Configuration option management master class
:param descr: describes the configuration schema
:type descr: an instance of ``option.OptionDescription``
:param context: the current root config
:type context: `Config`
:param session_id: session ID is import with persistent Config to
retrieve good session
:type session_id: `str`
:param persistent: if persistent, don't delete storage when leaving
:type persistent: `boolean`
"""
settings, values = get_storages(self, session_id, persistent)
self._impl_settings = Settings(self, settings)
self._impl_values = Values(self, values)
super(Config, self).__init__(descr, weakref.ref(self))
self._impl_build_all_paths()
self._impl_meta = None
#undocumented option used only in test script
self._impl_test = False
# ----- state
def __getstate__(self):
if self._impl_meta is not None:
raise ConfigError('cannot serialize Config with meta')
#FIXME _impl_meta est un weakref => faut pas sauvegarder mais faut bien savoir si c'est un méta ou pas au final ...
#en fait il faut ne pouvoir sérialisé que depuis une MetaConfig ... et pas directement comme pour les options
raise ConfigError('cannot serialize Config with MetaConfig')
slots = set()
for subclass in self.__class__.__mro__:
if subclass is not object:
@@ -589,6 +565,34 @@ class Config(CommonConfig):
self._impl_values._impl_setstate(storage)
self._impl_settings._impl_setstate(storage)
# ____________________________________________________________
class Config(_CommonConfig):
"main configuration management entry"
__slots__ = ('__weakref__',)
def __init__(self, descr, session_id=None, persistent=False):
""" Configuration option management master class
:param descr: describes the configuration schema
:type descr: an instance of ``option.OptionDescription``
:param context: the current root config
:type context: `Config`
:param session_id: session ID is import with persistent Config to
retrieve good session
:type session_id: `str`
:param persistent: if persistent, don't delete storage when leaving
:type persistent: `boolean`
"""
settings, values = get_storages(self, session_id, persistent)
self._impl_settings = Settings(self, settings)
self._impl_values = Values(self, values)
super(Config, self).__init__(descr, weakref.ref(self))
self._impl_build_all_paths()
self._impl_meta = None
#undocumented option used only in test script
self._impl_test = False
def cfgimpl_reset_cache(self,
only_expired=False,
only=('values', 'settings')):
@@ -598,42 +602,29 @@ class Config(CommonConfig):
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
class MetaConfig(CommonConfig):
class GroupConfig(_CommonConfig):
__slots__ = ('_impl_children', '__weakref__')
def __init__(self, children, meta=True, session_id=None, persistent=False):
def __init__(self, children, session_id=None, persistent=False,
_descr=None):
if not isinstance(children, list):
raise ValueError(_("metaconfig's children must be a list"))
descr = None
if meta:
for child in children:
if not isinstance(child, CommonConfig):
raise TypeError(_("metaconfig's children "
"must be config, not {0}"
).format(type(child)))
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'))
if child.cfgimpl_get_meta() is not None:
raise ValueError(_("child has already a metaconfig's"))
child._impl_meta = self
self._impl_children = children
settings, values = get_storages(self, session_id, persistent)
self._impl_settings = Settings(self, settings)
self._impl_values = Values(self, values)
super(MetaConfig, self).__init__(descr, weakref.ref(self))
super(GroupConfig, self).__init__(_descr, weakref.ref(self))
self._impl_meta = None
#undocumented option used only in test script
self._impl_test = False
def cfgimpl_get_children(self):
return self._impl_children
def cfgimpl_get_context(self):
"a meta config is a config wich has a setting, that is itself"
return self
#def cfgimpl_get_context(self):
# "a meta config is a config which has a setting, that is itself"
# return self
#
def cfgimpl_reset_cache(self,
only_expired=False,
only=('values', 'settings')):
@@ -644,38 +635,49 @@ class MetaConfig(CommonConfig):
for child in self._impl_children:
child.cfgimpl_reset_cache(only_expired=only_expired, only=only)
def set_contexts(self, path, value):
def setattrs(self, path, value):
"""Setattr not in current GroupConfig, but in each children
"""
for child in self._impl_children:
try:
if not isinstance(child, MetaConfig):
if not isinstance(child, GroupConfig):
setattr(child, path, value)
else:
child.set_contexts(path, value)
child.setattrs(path, value)
except PropertiesOptionError:
pass
def find_first_contexts(self, byname=None, bypath=None, byvalue=None,
type_='path', display_error=True):
def find_firsts(self, byname=None, bypath=None, byvalue=None,
type_='path', display_error=True):
"""Find first not in current GroupConfig, but in each children
"""
ret = []
#if MetaConfig, all children have same OptionDescription as context
#so search only one time for all children
try:
if bypath is None and byname is not None and \
self.cfgimpl_get_description() is not None:
isinstance(self, MetaConfig):
bypath = self._find(bytype=None, byvalue=None, byname=byname,
first=True, type_='path',
check_properties=False,
display_error=display_error)
except ConfigError:
byname = None
except AttributeError:
pass
for child in self._impl_children:
try:
if not isinstance(child, MetaConfig):
if bypath is not None:
#if byvalue is None, try if not raise
value = getattr(child, bypath)
if byvalue is not None:
if getattr(child, bypath) == byvalue:
ret.append(child)
if isinstance(value, Multi):
if byvalue in value:
ret.append(child)
else:
if value == byvalue:
ret.append(child)
else:
#not raise
getattr(child, bypath)
ret.append(child)
else:
ret.append(child.find_first(byname=byname,
@@ -683,16 +685,38 @@ class MetaConfig(CommonConfig):
type_=type_,
display_error=False))
else:
ret.extend(child.find_first_contexts(byname=byname,
bypath=bypath,
byvalue=byvalue,
type_=type_,
display_error=False))
ret.extend(child.find_firsts(byname=byname,
bypath=bypath,
byvalue=byvalue,
type_=type_,
display_error=False))
except AttributeError:
pass
return self._find_return_results(ret, display_error)
class MetaConfig(GroupConfig):
__slots__ = tuple()
def __init__(self, children, session_id=None, persistent=False):
descr = None
for child in children:
if not isinstance(child, _CommonConfig):
raise TypeError(_("metaconfig's children "
"should be config, not {0}"
).format(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'))
child._impl_meta = weakref.ref(self)
super(MetaConfig, self).__init__(children, session_id, persistent, descr)
def mandatory_warnings(config):
"""convenience function to trace Options that are mandatory and
where no value has been set