serialize metaconfig/groupconfig
This commit is contained in:
parent
6b7db20716
commit
feeb9842f5
|
@ -2,8 +2,8 @@
|
||||||
import autopath
|
import autopath
|
||||||
#from py.test import raises
|
#from py.test import raises
|
||||||
|
|
||||||
from tiramisu.config import Config
|
from tiramisu.config import Config, GroupConfig, MetaConfig
|
||||||
from tiramisu.option import BoolOption, OptionDescription
|
from tiramisu.option import BoolOption, IntOption, OptionDescription
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,3 +109,31 @@ def test_deref_optiondescription_config():
|
||||||
assert w() is not None
|
assert w() is not None
|
||||||
del(c)
|
del(c)
|
||||||
assert w() is None
|
assert w() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_deref_groupconfig():
|
||||||
|
i1 = IntOption('i1', '')
|
||||||
|
od1 = OptionDescription('od1', '', [i1])
|
||||||
|
od2 = OptionDescription('od2', '', [od1])
|
||||||
|
conf1 = Config(od2)
|
||||||
|
conf2 = Config(od2)
|
||||||
|
meta = GroupConfig([conf1, conf2])
|
||||||
|
w = weakref.ref(conf1)
|
||||||
|
del(conf1)
|
||||||
|
assert w() is not None
|
||||||
|
del(meta)
|
||||||
|
assert w() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_deref_metaconfig():
|
||||||
|
i1 = IntOption('i1', '')
|
||||||
|
od1 = OptionDescription('od1', '', [i1])
|
||||||
|
od2 = OptionDescription('od2', '', [od1])
|
||||||
|
conf1 = Config(od2)
|
||||||
|
conf2 = Config(od2)
|
||||||
|
meta = MetaConfig([conf1, conf2])
|
||||||
|
w = weakref.ref(conf1)
|
||||||
|
del(conf1)
|
||||||
|
assert w() is not None
|
||||||
|
del(meta)
|
||||||
|
assert w() is None
|
||||||
|
|
|
@ -3,7 +3,7 @@ import autopath
|
||||||
from py.test import raises
|
from py.test import raises
|
||||||
|
|
||||||
from tiramisu.setting import owners
|
from tiramisu.setting import owners
|
||||||
from tiramisu.config import Config, MetaConfig
|
from tiramisu.config import Config, GroupConfig, MetaConfig
|
||||||
from tiramisu.option import IntOption, OptionDescription
|
from tiramisu.option import IntOption, OptionDescription
|
||||||
from tiramisu.error import ConfigError
|
from tiramisu.error import ConfigError
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ def make_description():
|
||||||
|
|
||||||
#FIXME ne pas mettre 2 meta dans une config
|
#FIXME ne pas mettre 2 meta dans une config
|
||||||
#FIXME ne pas mettre 2 OD differents dans un meta
|
#FIXME ne pas mettre 2 OD differents dans un meta
|
||||||
|
#FIXME serialization
|
||||||
def test_none():
|
def test_none():
|
||||||
meta = make_description()
|
meta = make_description()
|
||||||
conf1, conf2 = meta._impl_children
|
conf1, conf2 = meta._impl_children
|
||||||
|
@ -89,7 +90,7 @@ def test_contexts():
|
||||||
conf1, conf2 = meta._impl_children
|
conf1, conf2 = meta._impl_children
|
||||||
assert conf1.od1.i2 == conf2.od1.i2 == 1
|
assert conf1.od1.i2 == conf2.od1.i2 == 1
|
||||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.default
|
||||||
meta.set_contexts('od1.i2', 6)
|
meta.setattrs('od1.i2', 6)
|
||||||
assert meta.od1.i2 == 1
|
assert meta.od1.i2 == 1
|
||||||
assert conf1.od1.i2 == conf2.od1.i2 == 6
|
assert conf1.od1.i2 == conf2.od1.i2 == 6
|
||||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user
|
assert conf1.getowner(conf1.unwrap_from_path('od1.i2')) is conf2.getowner(conf2.unwrap_from_path('od1.i2')) is owners.user
|
||||||
|
@ -142,14 +143,14 @@ def test_meta_meta_set():
|
||||||
meta2 = MetaConfig([meta1])
|
meta2 = MetaConfig([meta1])
|
||||||
meta2.cfgimpl_get_settings().setowner(owners.meta)
|
meta2.cfgimpl_get_settings().setowner(owners.meta)
|
||||||
conf1, conf2 = meta1._impl_children
|
conf1, conf2 = meta1._impl_children
|
||||||
meta2.set_contexts('od1.i1', 7)
|
meta2.setattrs('od1.i1', 7)
|
||||||
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
||||||
assert [conf1, conf2] == meta2.find_first_contexts(byname='i1', byvalue=7)
|
assert [conf1, conf2] == meta2.find_firsts(byname='i1', byvalue=7)
|
||||||
conf1.od1.i1 = 8
|
conf1.od1.i1 = 8
|
||||||
assert [conf2] == meta2.find_first_contexts(byname='i1', byvalue=7)
|
assert [conf2] == meta2.find_firsts(byname='i1', byvalue=7)
|
||||||
assert [conf1] == meta2.find_first_contexts(byname='i1', byvalue=8)
|
assert [conf1] == meta2.find_firsts(byname='i1', byvalue=8)
|
||||||
raises(AttributeError, "meta2.find_first_contexts(byname='i1', byvalue=10)")
|
raises(AttributeError, "meta2.find_firsts(byname='i1', byvalue=10)")
|
||||||
|
|
||||||
|
|
||||||
def test_not_meta():
|
def test_not_meta():
|
||||||
|
@ -158,10 +159,10 @@ def test_not_meta():
|
||||||
od2 = OptionDescription('od2', '', [od1])
|
od2 = OptionDescription('od2', '', [od1])
|
||||||
conf1 = Config(od2)
|
conf1 = Config(od2)
|
||||||
conf2 = Config(od2)
|
conf2 = Config(od2)
|
||||||
meta = MetaConfig([conf1, conf2], False)
|
meta = GroupConfig([conf1, conf2])
|
||||||
raises(ConfigError, 'meta.od1.i1')
|
raises(ConfigError, 'meta.od1.i1')
|
||||||
conf1, conf2 = meta._impl_children
|
conf1, conf2 = meta._impl_children
|
||||||
meta.set_contexts('od1.i1', 7)
|
meta.setattrs('od1.i1', 7)
|
||||||
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
assert conf1.od1.i1 == conf2.od1.i1 == 7
|
||||||
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
assert conf1.getowner(conf1.unwrap_from_path('od1.i1')) is conf2.getowner(conf2.unwrap_from_path('od1.i1')) is owners.user
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
|
from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
|
||||||
OptionDescription
|
IntOption, OptionDescription
|
||||||
from tiramisu.config import Config
|
from tiramisu.config import Config, GroupConfig, MetaConfig
|
||||||
from tiramisu.setting import owners
|
from tiramisu.setting import owners
|
||||||
from tiramisu.storage import delete_session
|
from tiramisu.storage import delete_session
|
||||||
from tiramisu.error import ConfigError
|
from tiramisu.error import ConfigError
|
||||||
|
@ -90,6 +90,45 @@ def _diff_opt(opt1, opt2):
|
||||||
assert val1 == val2
|
assert val1 == val2
|
||||||
|
|
||||||
|
|
||||||
|
def _diff_conf(cfg1, cfg2):
|
||||||
|
attr1 = set(_get_slots(cfg1))
|
||||||
|
attr2 = set(_get_slots(cfg2))
|
||||||
|
diff1 = attr1 - attr2
|
||||||
|
diff2 = attr2 - attr1
|
||||||
|
if diff1 != set():
|
||||||
|
raise Exception('more attribute in cfg1 {0}'.format(list(diff1)))
|
||||||
|
if diff2 != set():
|
||||||
|
raise Exception('more attribute in cfg2 {0}'.format(list(diff2)))
|
||||||
|
for attr in attr1:
|
||||||
|
if attr in ('_impl_context', '__weakref__'):
|
||||||
|
continue
|
||||||
|
err1 = False
|
||||||
|
err2 = False
|
||||||
|
val1 = None
|
||||||
|
val2 = None
|
||||||
|
try:
|
||||||
|
val1 = getattr(cfg1, attr)
|
||||||
|
except:
|
||||||
|
err1 = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
val2 = getattr(cfg2, attr)
|
||||||
|
except:
|
||||||
|
err2 = True
|
||||||
|
assert err1 == err2
|
||||||
|
if val1 is None:
|
||||||
|
assert val1 == val2
|
||||||
|
elif attr == '_impl_values':
|
||||||
|
assert cfg1.cfgimpl_get_values().get_modified_values() == cfg2.cfgimpl_get_values().get_modified_values()
|
||||||
|
elif attr == '_impl_settings':
|
||||||
|
assert cfg1.cfgimpl_get_settings().get_modified_properties() == cfg2.cfgimpl_get_settings().get_modified_properties()
|
||||||
|
assert cfg1.cfgimpl_get_settings().get_modified_permissives() == cfg2.cfgimpl_get_settings().get_modified_permissives()
|
||||||
|
elif attr == '_impl_descr':
|
||||||
|
_diff_opt(cfg1.cfgimpl_get_description(), cfg2.cfgimpl_get_description())
|
||||||
|
else:
|
||||||
|
assert val1 == val2
|
||||||
|
|
||||||
|
|
||||||
def test_diff_opt():
|
def test_diff_opt():
|
||||||
b = BoolOption('b', '')
|
b = BoolOption('b', '')
|
||||||
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
|
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
|
||||||
|
@ -169,10 +208,7 @@ def test_state_config():
|
||||||
cfg._impl_test = True
|
cfg._impl_test = True
|
||||||
a = dumps(cfg)
|
a = dumps(cfg)
|
||||||
q = loads(a)
|
q = loads(a)
|
||||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
_diff_conf(cfg, q)
|
||||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
|
||||||
try:
|
try:
|
||||||
delete_session('29090931')
|
delete_session('29090931')
|
||||||
except ConfigError:
|
except ConfigError:
|
||||||
|
@ -191,12 +227,9 @@ def test_state_properties():
|
||||||
cfg.cfgimpl_get_settings()[val1].append('test')
|
cfg.cfgimpl_get_settings()[val1].append('test')
|
||||||
a = dumps(cfg)
|
a = dumps(cfg)
|
||||||
q = loads(a)
|
q = loads(a)
|
||||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
_diff_conf(cfg, q)
|
||||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
|
||||||
try:
|
try:
|
||||||
delete_session('29090931')
|
delete_session('29090932')
|
||||||
except ConfigError:
|
except ConfigError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -212,15 +245,12 @@ def test_state_values():
|
||||||
cfg.val1 = True
|
cfg.val1 = True
|
||||||
a = dumps(cfg)
|
a = dumps(cfg)
|
||||||
q = loads(a)
|
q = loads(a)
|
||||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
_diff_conf(cfg, q)
|
||||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
|
||||||
q.val1 = False
|
q.val1 = False
|
||||||
#assert cfg.val1 is True
|
#assert cfg.val1 is True
|
||||||
assert q.val1 is False
|
assert q.val1 is False
|
||||||
try:
|
try:
|
||||||
delete_session('29090931')
|
delete_session('29090933')
|
||||||
except ConfigError:
|
except ConfigError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -238,14 +268,53 @@ def test_state_values_owner():
|
||||||
cfg.val1 = True
|
cfg.val1 = True
|
||||||
a = dumps(cfg)
|
a = dumps(cfg)
|
||||||
q = loads(a)
|
q = loads(a)
|
||||||
_diff_opt(maconfig, q.cfgimpl_get_description())
|
_diff_conf(cfg, q)
|
||||||
assert cfg.cfgimpl_get_values().get_modified_values() == q.cfgimpl_get_values().get_modified_values()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_properties() == q.cfgimpl_get_settings().get_modified_properties()
|
|
||||||
assert cfg.cfgimpl_get_settings().get_modified_permissives() == q.cfgimpl_get_settings().get_modified_permissives()
|
|
||||||
q.val1 = False
|
q.val1 = False
|
||||||
nval1 = q.cfgimpl_get_description().val1
|
nval1 = q.cfgimpl_get_description().val1
|
||||||
assert q.getowner(nval1) == owners.newowner
|
assert q.getowner(nval1) == owners.newowner
|
||||||
try:
|
try:
|
||||||
delete_session('29090931')
|
delete_session('29090934')
|
||||||
|
except ConfigError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_state_metaconfig():
|
||||||
|
i1 = IntOption('i1', '')
|
||||||
|
od1 = OptionDescription('od1', '', [i1])
|
||||||
|
od2 = OptionDescription('od2', '', [od1])
|
||||||
|
conf1 = Config(od2, session_id='29090935')
|
||||||
|
conf1._impl_test = True
|
||||||
|
conf2 = Config(od2, session_id='29090936')
|
||||||
|
conf2._impl_test = True
|
||||||
|
meta = MetaConfig([conf1, conf2], session_id='29090937')
|
||||||
|
meta._impl_test = True
|
||||||
|
a = dumps(meta)
|
||||||
|
q = loads(a)
|
||||||
|
_diff_conf(meta, q)
|
||||||
|
try:
|
||||||
|
delete_session('29090935')
|
||||||
|
delete_session('29090936')
|
||||||
|
delete_session('29090937')
|
||||||
|
except ConfigError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_state_groupconfig():
|
||||||
|
i1 = IntOption('i1', '')
|
||||||
|
od1 = OptionDescription('od1', '', [i1])
|
||||||
|
od2 = OptionDescription('od2', '', [od1])
|
||||||
|
conf1 = Config(od2, session_id='29090935')
|
||||||
|
conf1._impl_test = True
|
||||||
|
conf2 = Config(od2, session_id='29090936')
|
||||||
|
conf2._impl_test = True
|
||||||
|
meta = GroupConfig([conf1, conf2], session_id='29090937')
|
||||||
|
meta._impl_test = True
|
||||||
|
a = dumps(meta)
|
||||||
|
q = loads(a)
|
||||||
|
_diff_conf(meta, q)
|
||||||
|
try:
|
||||||
|
delete_session('29090935')
|
||||||
|
delete_session('29090936')
|
||||||
|
delete_session('29090937')
|
||||||
except ConfigError:
|
except ConfigError:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -161,7 +161,7 @@ class SubConfig(object):
|
||||||
def cfgimpl_get_description(self):
|
def cfgimpl_get_description(self):
|
||||||
if self._impl_descr is None:
|
if self._impl_descr is None:
|
||||||
raise ConfigError(_('no option description found for this config'
|
raise ConfigError(_('no option description found for this config'
|
||||||
' (may be metaconfig without meta)'))
|
' (may be GroupConfig)'))
|
||||||
else:
|
else:
|
||||||
return self._impl_descr
|
return self._impl_descr
|
||||||
|
|
||||||
|
@ -467,9 +467,9 @@ class SubConfig(object):
|
||||||
return context_descr.impl_get_path_by_opt(descr)
|
return context_descr.impl_get_path_by_opt(descr)
|
||||||
|
|
||||||
|
|
||||||
class CommonConfig(SubConfig):
|
class _CommonConfig(SubConfig):
|
||||||
"abstract base class for the Config and the MetaConfig"
|
"abstract base class for the Config, GroupConfig and the MetaConfig"
|
||||||
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta')
|
__slots__ = ('_impl_values', '_impl_settings', '_impl_meta', '_impl_test')
|
||||||
|
|
||||||
def _impl_build_all_paths(self):
|
def _impl_build_all_paths(self):
|
||||||
self.cfgimpl_get_description().impl_build_cache()
|
self.cfgimpl_get_description().impl_build_cache()
|
||||||
|
@ -508,7 +508,8 @@ class CommonConfig(SubConfig):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def cfgimpl_get_meta(self):
|
def cfgimpl_get_meta(self):
|
||||||
return self._impl_meta
|
if self._impl_meta is not None:
|
||||||
|
return self._impl_meta()
|
||||||
|
|
||||||
# information
|
# information
|
||||||
def impl_set_information(self, key, value):
|
def impl_set_information(self, key, value):
|
||||||
|
@ -526,37 +527,12 @@ class CommonConfig(SubConfig):
|
||||||
"""
|
"""
|
||||||
return self._impl_values.get_information(key, default)
|
return self._impl_values.get_information(key, default)
|
||||||
|
|
||||||
|
# ----- state
|
||||||
# ____________________________________________________________
|
|
||||||
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
|
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
if self._impl_meta is not None:
|
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()
|
slots = set()
|
||||||
for subclass in self.__class__.__mro__:
|
for subclass in self.__class__.__mro__:
|
||||||
if subclass is not object:
|
if subclass is not object:
|
||||||
|
@ -589,6 +565,34 @@ class Config(CommonConfig):
|
||||||
self._impl_values._impl_setstate(storage)
|
self._impl_values._impl_setstate(storage)
|
||||||
self._impl_settings._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,
|
def cfgimpl_reset_cache(self,
|
||||||
only_expired=False,
|
only_expired=False,
|
||||||
only=('values', 'settings')):
|
only=('values', 'settings')):
|
||||||
|
@ -598,42 +602,29 @@ class Config(CommonConfig):
|
||||||
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
|
self.cfgimpl_get_settings().reset_cache(only_expired=only_expired)
|
||||||
|
|
||||||
|
|
||||||
class MetaConfig(CommonConfig):
|
class GroupConfig(_CommonConfig):
|
||||||
__slots__ = ('_impl_children', '__weakref__')
|
__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):
|
if not isinstance(children, list):
|
||||||
raise ValueError(_("metaconfig's children must be a 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
|
self._impl_children = children
|
||||||
settings, values = get_storages(self, session_id, persistent)
|
settings, values = get_storages(self, session_id, persistent)
|
||||||
self._impl_settings = Settings(self, settings)
|
self._impl_settings = Settings(self, settings)
|
||||||
self._impl_values = Values(self, values)
|
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
|
self._impl_meta = None
|
||||||
|
#undocumented option used only in test script
|
||||||
|
self._impl_test = False
|
||||||
|
|
||||||
def cfgimpl_get_children(self):
|
def cfgimpl_get_children(self):
|
||||||
return self._impl_children
|
return self._impl_children
|
||||||
|
|
||||||
def cfgimpl_get_context(self):
|
#def cfgimpl_get_context(self):
|
||||||
"a meta config is a config wich has a setting, that is itself"
|
# "a meta config is a config which has a setting, that is itself"
|
||||||
return self
|
# return self
|
||||||
|
#
|
||||||
def cfgimpl_reset_cache(self,
|
def cfgimpl_reset_cache(self,
|
||||||
only_expired=False,
|
only_expired=False,
|
||||||
only=('values', 'settings')):
|
only=('values', 'settings')):
|
||||||
|
@ -644,38 +635,49 @@ class MetaConfig(CommonConfig):
|
||||||
for child in self._impl_children:
|
for child in self._impl_children:
|
||||||
child.cfgimpl_reset_cache(only_expired=only_expired, only=only)
|
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:
|
for child in self._impl_children:
|
||||||
try:
|
try:
|
||||||
if not isinstance(child, MetaConfig):
|
if not isinstance(child, GroupConfig):
|
||||||
setattr(child, path, value)
|
setattr(child, path, value)
|
||||||
else:
|
else:
|
||||||
child.set_contexts(path, value)
|
child.setattrs(path, value)
|
||||||
except PropertiesOptionError:
|
except PropertiesOptionError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def find_first_contexts(self, byname=None, bypath=None, byvalue=None,
|
def find_firsts(self, byname=None, bypath=None, byvalue=None,
|
||||||
type_='path', display_error=True):
|
type_='path', display_error=True):
|
||||||
|
"""Find first not in current GroupConfig, but in each children
|
||||||
|
"""
|
||||||
ret = []
|
ret = []
|
||||||
|
#if MetaConfig, all children have same OptionDescription as context
|
||||||
|
#so search only one time for all children
|
||||||
try:
|
try:
|
||||||
if bypath is None and byname is not None and \
|
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,
|
bypath = self._find(bytype=None, byvalue=None, byname=byname,
|
||||||
first=True, type_='path',
|
first=True, type_='path',
|
||||||
check_properties=False,
|
check_properties=False,
|
||||||
display_error=display_error)
|
display_error=display_error)
|
||||||
except ConfigError:
|
byname = None
|
||||||
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
for child in self._impl_children:
|
for child in self._impl_children:
|
||||||
try:
|
try:
|
||||||
if not isinstance(child, MetaConfig):
|
if not isinstance(child, MetaConfig):
|
||||||
if bypath is not None:
|
if bypath is not None:
|
||||||
|
#if byvalue is None, try if not raise
|
||||||
|
value = getattr(child, bypath)
|
||||||
if byvalue is not None:
|
if byvalue is not None:
|
||||||
if getattr(child, bypath) == byvalue:
|
if isinstance(value, Multi):
|
||||||
|
if byvalue in value:
|
||||||
|
ret.append(child)
|
||||||
|
else:
|
||||||
|
if value == byvalue:
|
||||||
ret.append(child)
|
ret.append(child)
|
||||||
else:
|
else:
|
||||||
#not raise
|
|
||||||
getattr(child, bypath)
|
|
||||||
ret.append(child)
|
ret.append(child)
|
||||||
else:
|
else:
|
||||||
ret.append(child.find_first(byname=byname,
|
ret.append(child.find_first(byname=byname,
|
||||||
|
@ -683,7 +685,7 @@ class MetaConfig(CommonConfig):
|
||||||
type_=type_,
|
type_=type_,
|
||||||
display_error=False))
|
display_error=False))
|
||||||
else:
|
else:
|
||||||
ret.extend(child.find_first_contexts(byname=byname,
|
ret.extend(child.find_firsts(byname=byname,
|
||||||
bypath=bypath,
|
bypath=bypath,
|
||||||
byvalue=byvalue,
|
byvalue=byvalue,
|
||||||
type_=type_,
|
type_=type_,
|
||||||
|
@ -693,6 +695,28 @@ class MetaConfig(CommonConfig):
|
||||||
return self._find_return_results(ret, display_error)
|
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):
|
def mandatory_warnings(config):
|
||||||
"""convenience function to trace Options that are mandatory and
|
"""convenience function to trace Options that are mandatory and
|
||||||
where no value has been set
|
where no value has been set
|
||||||
|
|
Loading…
Reference in New Issue