better support for sqlalchemy storage
This commit is contained in:
parent
3cc2d9ca3d
commit
71f8926fca
|
@ -37,6 +37,14 @@ def return_list(val=None):
|
|||
return ['val1', 'val2']
|
||||
|
||||
|
||||
def return_same_list():
|
||||
return ['val1', 'val1']
|
||||
|
||||
|
||||
def return_wrong_list():
|
||||
return ['---', ' ']
|
||||
|
||||
|
||||
def test_build_dyndescription():
|
||||
st = StrOption('st', '')
|
||||
dod = DynOptionDescription('dod', '', [st], callback=return_list)
|
||||
|
@ -193,18 +201,18 @@ def test_prop_dyndescription():
|
|||
stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
|
||||
dodval1 = cfg.unwrap_from_path('od.dodval1')
|
||||
dodval2 = cfg.unwrap_from_path('od.dodval2')
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) == str(['test'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) == str(['test'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test']), str([u'test'])]
|
||||
cfg.cfgimpl_get_settings()[stval2].append('test2')
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) == str(['test'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) == str(['test', 'test2'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test', 'test2']), str([u'test', 'test2'])]
|
||||
cfg.cfgimpl_get_settings()[stval1].remove('test')
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) == str([])
|
||||
#
|
||||
assert str(cfg.cfgimpl_get_settings()[dodval1]) == str([])
|
||||
assert str(cfg.cfgimpl_get_settings()[dodval2]) == str([])
|
||||
cfg.cfgimpl_get_settings()[dodval1].append('test1')
|
||||
assert str(cfg.cfgimpl_get_settings()[dodval1]) == str(['test1'])
|
||||
assert str(cfg.cfgimpl_get_settings()[dodval1]) in [str(['test1']), str([u'test1'])]
|
||||
assert str(cfg.cfgimpl_get_settings()[dodval2]) == str([])
|
||||
cfg.cfgimpl_get_settings()[dodval1].remove('test1')
|
||||
assert str(cfg.cfgimpl_get_settings()[dodval1]) == str([])
|
||||
|
@ -402,11 +410,11 @@ def test_prop_dyndescription_context():
|
|||
cfg = Config(od2)
|
||||
stval1 = cfg.unwrap_from_path('od.dodval1.stval1')
|
||||
stval2 = cfg.unwrap_from_path('od.dodval2.stval2')
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) == str(['test'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) == str(['test'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test']), str([u'test'])]
|
||||
cfg.cfgimpl_get_settings()[stval2].append('test2')
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) == str(['test'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) == str(['test', 'test2'])
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) in [str(['test']), str([u'test'])]
|
||||
assert str(cfg.cfgimpl_get_settings()[stval2]) in [str(['test', 'test2']), str([u'test', 'test2'])]
|
||||
cfg.cfgimpl_get_settings()[stval1].remove('test')
|
||||
assert str(cfg.cfgimpl_get_settings()[stval1]) == str([])
|
||||
|
||||
|
@ -1293,13 +1301,11 @@ def test_invalid_symlink_dyndescription():
|
|||
|
||||
def test_nocallback_dyndescription():
|
||||
st = StrOption('st', '')
|
||||
st2 = StrOption('st2', st)
|
||||
st2 = StrOption('st2', '')
|
||||
raises(ConfigError, "DynOptionDescription('dod', '', [st, st2])")
|
||||
|
||||
|
||||
def test_invalid_samevalue_dyndescription():
|
||||
def return_same_list():
|
||||
return ['val1', 'val1']
|
||||
st = StrOption('st', '')
|
||||
dod = DynOptionDescription('dod', '', [st], callback=return_same_list)
|
||||
od = OptionDescription('od', '', [dod])
|
||||
|
@ -1308,10 +1314,8 @@ def test_invalid_samevalue_dyndescription():
|
|||
|
||||
|
||||
def test_invalid_name_dyndescription():
|
||||
def return_same_list():
|
||||
return ['---', ' ']
|
||||
st = StrOption('st', '')
|
||||
dod = DynOptionDescription('dod', '', [st], callback=return_same_list)
|
||||
dod = DynOptionDescription('dod', '', [st], callback=return_wrong_list)
|
||||
od = OptionDescription('od', '', [dod])
|
||||
cfg = Config(od)
|
||||
raises(ValueError, "print cfg")
|
||||
|
|
|
@ -382,4 +382,4 @@ def test_properties_cached():
|
|||
setting = c.cfgimpl_get_settings()
|
||||
option = c.cfgimpl_get_description().sub.b1
|
||||
c._setattr('sub.b1', True, force_permissive=True)
|
||||
assert str(setting[b1]) == "['test']"
|
||||
assert str(setting[b1]) in ["['test']", "[u'test']"]
|
||||
|
|
|
@ -149,7 +149,8 @@ def carry_out_calculation(option, config, callback, callback_params,
|
|||
if isinstance(callbk, tuple):
|
||||
if config is undefined:
|
||||
raise ContextError() # pragma: optional cover
|
||||
if len(callbk) == 1: # pragma: optional cover
|
||||
if callbk[0] is None: # pragma: optional cover
|
||||
#Not an option, set full context
|
||||
tcparams.setdefault(key, []).append((config, False))
|
||||
else:
|
||||
# callbk is something link (opt, True|False)
|
||||
|
|
|
@ -33,11 +33,7 @@ from tiramisu.storage import get_storages_option
|
|||
StorageBase = get_storages_option('base')
|
||||
|
||||
|
||||
class SubMulti(object):
|
||||
pass
|
||||
|
||||
|
||||
submulti = SubMulti()
|
||||
submulti = 2
|
||||
|
||||
|
||||
allowed_character = '[a-z\d\-_]'
|
||||
|
@ -115,7 +111,10 @@ class Base(StorageBase):
|
|||
if callback is not None:
|
||||
validate_callback(callback, callback_params, 'callback')
|
||||
self._callback = callback
|
||||
self._callback_params = callback_params
|
||||
if callback_params is None:
|
||||
self._callback_params = {}
|
||||
else:
|
||||
self._callback_params = callback_params
|
||||
|
||||
def __init__(self, name, doc, default=None, default_multi=None,
|
||||
requires=None, multi=False, callback=None,
|
||||
|
@ -143,8 +142,13 @@ class Base(StorageBase):
|
|||
raise ValueError(_("invalid default_multi value {0} "
|
||||
"for option {1}: {2}").format(
|
||||
str(default_multi), name, err))
|
||||
self._multi = multi
|
||||
if self._multi is not False:
|
||||
if multi is True:
|
||||
self._multi = 0
|
||||
elif multi is False:
|
||||
self._multi = 1
|
||||
elif multi is submulti:
|
||||
self._multi = submulti
|
||||
if self._multi != 1:
|
||||
if default is None:
|
||||
default = []
|
||||
self._default_multi = default_multi
|
||||
|
@ -260,10 +264,10 @@ class BaseOption(Base):
|
|||
return
|
||||
if not load and self._callback is None:
|
||||
self._state_callback = None
|
||||
self._state_callback_params = None
|
||||
self._state_callback_params = {}
|
||||
elif load and self._state_callback is None:
|
||||
self._callback = None
|
||||
self._callback_params = None
|
||||
self._callback_params = {}
|
||||
del(self._state_callback)
|
||||
del(self._state_callback_params)
|
||||
else:
|
||||
|
@ -273,7 +277,7 @@ class BaseOption(Base):
|
|||
else:
|
||||
callback = self._callback
|
||||
callback_params = self._callback_params
|
||||
self._state_callback_params = None
|
||||
self._state_callback_params = {}
|
||||
if callback_params is not None:
|
||||
cllbck_prms = {}
|
||||
for key, values in callback_params.items():
|
||||
|
@ -429,6 +433,19 @@ class BaseOption(Base):
|
|||
def impl_get_callback(self):
|
||||
return self._callback, self._callback_params
|
||||
|
||||
def impl_has_callback(self):
|
||||
"to know if a callback has been defined or not"
|
||||
return self._callback is not None
|
||||
|
||||
def _is_subdyn(self):
|
||||
try:
|
||||
return self._subdyn is not None
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
def impl_getproperties(self):
|
||||
return self._properties
|
||||
|
||||
|
||||
class OnlyOption(BaseOption):
|
||||
__slots__ = tuple()
|
||||
|
@ -713,18 +730,11 @@ class Option(OnlyOption):
|
|||
"accesses the Option's doc"
|
||||
return self.impl_get_information('doc')
|
||||
|
||||
def impl_has_callback(self):
|
||||
"to know if a callback has been defined or not"
|
||||
if self._callback is None:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
#def impl_getkey(self, value):
|
||||
# return value
|
||||
|
||||
def impl_is_multi(self):
|
||||
return self._multi is True or self._multi is submulti
|
||||
return self._multi == 0 or self._multi is submulti
|
||||
|
||||
def impl_is_submulti(self):
|
||||
return self._multi is submulti
|
||||
|
@ -746,7 +756,7 @@ class Option(OnlyOption):
|
|||
self._name))
|
||||
warnings_only = params.get('warnings_only', False)
|
||||
if self._is_subdyn():
|
||||
dynod = self._subdyn
|
||||
dynod = self._impl_getsubdyn()
|
||||
else:
|
||||
dynod = None
|
||||
for opt in other_opts:
|
||||
|
@ -756,10 +766,10 @@ class Option(OnlyOption):
|
|||
if dynod is None:
|
||||
raise ConfigError(_('almost one option in consistency is '
|
||||
'in a dynoptiondescription but not all'))
|
||||
if dynod != opt._subdyn:
|
||||
if dynod != opt._impl_getsubdyn():
|
||||
raise ConfigError(_('option in consistency must be in same'
|
||||
' dynoptiondescription'))
|
||||
dynod = opt._subdyn
|
||||
dynod = opt._impl_getsubdyn()
|
||||
elif dynod is not None:
|
||||
raise ConfigError(_('almost one option in consistency is in a '
|
||||
'dynoptiondescription but not all'))
|
||||
|
@ -847,10 +857,10 @@ class Option(OnlyOption):
|
|||
default_multi = self._default_multi
|
||||
except AttributeError:
|
||||
default_multi = None
|
||||
if callback is not None and ((not self._multi and
|
||||
if callback is not None and ((self._multi == 1 and
|
||||
(self._default is not None or
|
||||
default_multi is not None))
|
||||
or (self._multi and
|
||||
or (self._multi != 1 and
|
||||
(self._default != [] or
|
||||
default_multi is not None))
|
||||
): # pragma: optional cover
|
||||
|
@ -983,6 +993,23 @@ class SymLinkOption(OnlyOption):
|
|||
def impl_get_information(self, key, default=undefined):
|
||||
return self._opt.impl_get_information(key, default)
|
||||
|
||||
#FIXME utile tout ca ? c'est un peu de la duplication ...
|
||||
def impl_getproperties(self):
|
||||
return self._opt._properties
|
||||
|
||||
def impl_get_callback(self):
|
||||
return self._opt._callback, self._opt._callback_params
|
||||
|
||||
def impl_has_callback(self):
|
||||
"to know if a callback has been defined or not"
|
||||
return self._opt._callback is not None
|
||||
|
||||
def _is_subdyn(self):
|
||||
try:
|
||||
return self._opt._subdyn is not None
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
|
||||
class DynSymLinkOption(SymLinkOption):
|
||||
__slots__ = ('_dyn',)
|
||||
|
|
|
@ -55,7 +55,7 @@ class MasterSlaves(object):
|
|||
).format(name))
|
||||
if validate:
|
||||
callback, callback_params = self.master.impl_get_callback()
|
||||
if callback is not None and callback_params is not None: # pragma: optional cover
|
||||
if callback is not None and callback_params != {}: # pragma: optional cover
|
||||
for key, callbacks in callback_params.items():
|
||||
for callbk in callbacks:
|
||||
if isinstance(callbk, tuple):
|
||||
|
|
|
@ -48,11 +48,14 @@ class ChoiceOption(Option):
|
|||
"""
|
||||
if isinstance(values, FunctionType):
|
||||
validate_callback(values, values_params, 'values')
|
||||
elif not isinstance(values, tuple): # pragma: optional cover
|
||||
raise TypeError(_('values must be a tuple or a function for {0}'
|
||||
).format(name))
|
||||
self._extra = {'_choice_values': values,
|
||||
'_choice_values_params': values_params}
|
||||
else:
|
||||
if values_params is not None:
|
||||
raise ValueError(_('values is not a function, so values_params must be None'))
|
||||
if not isinstance(values, tuple): # pragma: optional cover
|
||||
raise TypeError(_('values must be a tuple or a function for {0}'
|
||||
).format(name))
|
||||
self._choice_values = values
|
||||
self._choice_values_params = values_params
|
||||
super(ChoiceOption, self).__init__(name, doc, default=default,
|
||||
default_multi=default_multi,
|
||||
callback=callback,
|
||||
|
@ -66,9 +69,9 @@ class ChoiceOption(Option):
|
|||
|
||||
def impl_get_values(self, context):
|
||||
#FIXME cache? but in context...
|
||||
values = self._extra['_choice_values']
|
||||
values = self._choice_values
|
||||
if isinstance(values, FunctionType):
|
||||
values_params = self._extra['_choice_values_params']
|
||||
values_params = self._choice_values_params
|
||||
if values_params is None:
|
||||
values_params = {}
|
||||
values = carry_out_calculation(self, config=context,
|
||||
|
|
|
@ -74,7 +74,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
|||
'dynoptiondescription'))
|
||||
old = child
|
||||
self._add_children(child_names, children)
|
||||
self._cache_paths = None
|
||||
self._cache_consistencies = None
|
||||
# the group_type is useful for filtering OptionDescriptions in a config
|
||||
self._group_type = groups.default
|
||||
|
@ -167,9 +166,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
|||
raise ValueError(_('group_type: {0}'
|
||||
' not allowed').format(group_type))
|
||||
|
||||
def impl_get_group_type(self):
|
||||
return self._group_type
|
||||
|
||||
def _valid_consistency(self, option, value, context, index, submulti_idx):
|
||||
if self._cache_consistencies is None:
|
||||
return True
|
||||
|
@ -239,7 +235,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
|||
:param descr: parent :class:`tiramisu.option.OptionDescription`
|
||||
"""
|
||||
if descr is None:
|
||||
self._cache_paths = None
|
||||
self._cache_consistencies = None
|
||||
self.impl_build_cache_option()
|
||||
descr = self
|
||||
|
@ -261,8 +256,6 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
|||
|
||||
def _impl_get_suffixes(self, context):
|
||||
callback, callback_params = self.impl_get_callback()
|
||||
if callback_params is None:
|
||||
callback_params = {}
|
||||
values = carry_out_calculation(self, config=context,
|
||||
callback=callback,
|
||||
callback_params=callback_params)
|
||||
|
@ -275,10 +268,9 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
|||
|
||||
def _impl_search_dynchild(self, name=undefined, context=undefined):
|
||||
ret = []
|
||||
for child in self._impl_st_getchildren():
|
||||
for child in self._impl_st_getchildren(context, only_dyn=True):
|
||||
cname = child.impl_getname()
|
||||
if isinstance(child, DynOptionDescription) and \
|
||||
(name is undefined or name.startswith(cname)):
|
||||
if name is undefined or name.startswith(cname):
|
||||
path = cname
|
||||
for value in child._impl_get_suffixes(context):
|
||||
if name is undefined:
|
||||
|
@ -296,7 +288,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
|||
return child._impl_to_dyn(name, path)
|
||||
|
||||
def _impl_getchildren(self, dyn=True, context=undefined):
|
||||
for child in self._impl_st_getchildren():
|
||||
for child in self._impl_st_getchildren(context):
|
||||
cname = child._name
|
||||
if dyn and child.impl_is_dynoptiondescription():
|
||||
path = cname
|
||||
|
@ -310,24 +302,30 @@ class OptionDescription(BaseOption, StorageOptionDescription):
|
|||
def impl_getchildren(self):
|
||||
return list(self._impl_getchildren())
|
||||
|
||||
def __getattr__(self, name, context=undefined):
|
||||
if name.startswith('_'): # or name.startswith('impl_'):
|
||||
return object.__getattribute__(self, name)
|
||||
return self._getattr(name, context=context)
|
||||
|
||||
|
||||
class DynOptionDescription(OptionDescription):
|
||||
def __init__(self, name, doc, children, requires=None, properties=None,
|
||||
callback=None, callback_params=None):
|
||||
super(DynOptionDescription, self).__init__(name, doc, children,
|
||||
requires, properties)
|
||||
for child in children:
|
||||
if isinstance(child, OptionDescription):
|
||||
if child.impl_get_group_type() != groups.master:
|
||||
raise ConfigError(_('cannot set optiondescription in an '
|
||||
'dynoptiondescription'))
|
||||
for chld in child._impl_getchildren():
|
||||
chld._subdyn = self
|
||||
chld._impl_setsubdyn(self)
|
||||
if isinstance(child, SymLinkOption):
|
||||
raise ConfigError(_('cannot set symlinkoption in an '
|
||||
'dynoptiondescription'))
|
||||
child._subdyn = self
|
||||
super(DynOptionDescription, self).__init__(name, doc, children,
|
||||
requires, properties)
|
||||
child._impl_setsubdyn(self)
|
||||
self.impl_set_callback(callback, callback_params)
|
||||
self.commit()
|
||||
|
||||
def _validate_callback(self, callback, callback_params):
|
||||
if callback is None:
|
||||
|
@ -346,7 +344,7 @@ class SynDynOptionDescription(object):
|
|||
def __getattr__(self, name, context=undefined):
|
||||
if name in dir(self._opt):
|
||||
return getattr(self._opt, name)
|
||||
return self._opt._getattr(name, self._name, self._suffix, context)
|
||||
return self._opt._getattr(name, suffix=self._suffix, context=context)
|
||||
|
||||
def impl_getname(self):
|
||||
return self._name
|
||||
|
|
|
@ -100,6 +100,9 @@ rw_append = set(['frozen', 'disabled', 'validator', 'hidden'])
|
|||
rw_remove = set(['permissive', 'everything_frozen', 'mandatory'])
|
||||
|
||||
|
||||
forbidden_set_properties = set(['force_store_value'])
|
||||
|
||||
|
||||
log = getLogger('tiramisu')
|
||||
#FIXME
|
||||
#import logging
|
||||
|
@ -253,7 +256,7 @@ class Property(object):
|
|||
'this property is calculated').format(
|
||||
propname, self._opt.impl_getname()))
|
||||
self._properties.add(propname)
|
||||
self._setting._setproperties(self._properties, self._opt, self._path)
|
||||
self._setting._setproperties(self._properties, self._path)
|
||||
|
||||
def remove(self, propname):
|
||||
"""Removes a property named propname
|
||||
|
@ -263,8 +266,7 @@ class Property(object):
|
|||
"""
|
||||
if propname in self._properties:
|
||||
self._properties.remove(propname)
|
||||
self._setting._setproperties(self._properties, self._opt,
|
||||
self._path)
|
||||
self._setting._setproperties(self._properties, self._path)
|
||||
|
||||
def extend(self, propnames):
|
||||
"""Extends properties to the existing properties
|
||||
|
@ -347,7 +349,7 @@ class Settings(object):
|
|||
else:
|
||||
if opt is not None and _path is None:
|
||||
_path = opt.impl_getpath(self._getcontext())
|
||||
self._p_.reset_properties(_path)
|
||||
self._p_.delproperties(_path)
|
||||
self._getcontext().cfgimpl_reset_cache()
|
||||
|
||||
def _getproperties(self, opt=None, path=None, _is_apply_req=True):
|
||||
|
@ -367,7 +369,7 @@ class Settings(object):
|
|||
is_cached, props = self._p_.getcache(path, ntime)
|
||||
if is_cached:
|
||||
return copy(props)
|
||||
props = self._p_.getproperties(path, opt._properties)
|
||||
props = self._p_.getproperties(path, opt.impl_getproperties())
|
||||
if _is_apply_req:
|
||||
props = copy(props)
|
||||
props |= self.apply_requires(opt, path)
|
||||
|
@ -383,33 +385,28 @@ class Settings(object):
|
|||
"puts property propname in the Config's properties attribute"
|
||||
props = self._p_.getproperties(None, default_properties)
|
||||
props.add(propname)
|
||||
self._setproperties(props, None, None)
|
||||
self._setproperties(props, None)
|
||||
|
||||
def remove(self, propname):
|
||||
"deletes property propname in the Config's properties attribute"
|
||||
props = self._p_.getproperties(None, default_properties)
|
||||
if propname in props:
|
||||
props.remove(propname)
|
||||
self._setproperties(props, None, None)
|
||||
self._setproperties(props, None)
|
||||
|
||||
def extend(self, propnames):
|
||||
for propname in propnames:
|
||||
self.append(propname)
|
||||
|
||||
def _setproperties(self, properties, opt, path):
|
||||
"""save properties for specified opt
|
||||
def _setproperties(self, properties, path):
|
||||
"""save properties for specified path
|
||||
(never save properties if same has option properties)
|
||||
"""
|
||||
if opt is None:
|
||||
self._p_.setproperties(None, properties)
|
||||
else:
|
||||
#if opt._calc_properties is not None:
|
||||
# properties -= opt._calc_properties
|
||||
#if set(opt._properties) == properties:
|
||||
# self._p_.reset_properties(path)
|
||||
#else:
|
||||
# self._p_.setproperties(path, properties)
|
||||
self._p_.setproperties(path, properties)
|
||||
forbidden_properties = forbidden_set_properties & properties
|
||||
if forbidden_properties:
|
||||
raise ConfigError(_('cannot add those properties: {0}').format(
|
||||
' '.join(forbidden_properties)))
|
||||
self._p_.setproperties(path, properties)
|
||||
self._getcontext().cfgimpl_reset_cache()
|
||||
|
||||
#____________________________________________________________
|
||||
|
@ -622,15 +619,6 @@ class Settings(object):
|
|||
def get_modified_permissives(self):
|
||||
return self._p_.get_modified_permissives()
|
||||
|
||||
def get_with_property(self, propname):
|
||||
opts, paths = self._getcontext().cfgimpl_get_description(
|
||||
)._cache_paths
|
||||
for index in range(0, len(paths)):
|
||||
opt = opts[index]
|
||||
path = paths[index]
|
||||
if propname in self._getproperties(opt, path, False):
|
||||
yield (opt, path)
|
||||
|
||||
def __getstate__(self):
|
||||
return {'_p_': self._p_, '_owner': str(self._owner)}
|
||||
|
||||
|
|
|
@ -117,15 +117,20 @@ def get_storages(context, session_id, persistent):
|
|||
session_id = gen_id(context)
|
||||
imp = storage_type.get()
|
||||
storage = imp.Storage(session_id, persistent)
|
||||
return imp.Settings(storage), imp.Values(storage)
|
||||
try:
|
||||
return imp.Settings(storage), imp.Values(storage)
|
||||
except:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
raise Exception('rah')
|
||||
|
||||
|
||||
def get_storages_option(type_):
|
||||
imp = storage_option_type.get()
|
||||
if type_ == 'base':
|
||||
return imp.Base
|
||||
return imp.StorageBase
|
||||
else:
|
||||
return imp.OptionDescription
|
||||
return imp.StorageOptionDescription
|
||||
|
||||
|
||||
def list_sessions(type_): # pragma: optional cover
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
@ -25,7 +25,7 @@ use it. But if something goes wrong, you will lost your modifications.
|
|||
from .value import Values
|
||||
from .setting import Settings
|
||||
from .storage import setting, Storage, list_sessions, delete_session
|
||||
from .option import Base, OptionDescription
|
||||
from .option import StorageBase, StorageOptionDescription
|
||||
|
||||
__all__ = (setting, Values, Settings, Storage, list_sessions, delete_session,
|
||||
Base, OptionDescription)
|
||||
StorageBase, StorageOptionDescription)
|
||||
|
|
|
@ -18,14 +18,14 @@
|
|||
#
|
||||
# ____________________________________________________________
|
||||
from tiramisu.i18n import _
|
||||
from tiramisu.setting import groups, undefined
|
||||
from tiramisu.setting import undefined
|
||||
from tiramisu.error import ConfigError
|
||||
|
||||
|
||||
#____________________________________________________________
|
||||
#
|
||||
# Base
|
||||
class Base(object):
|
||||
class StorageBase(object):
|
||||
__slots__ = ('_name', '_requires', '_properties', '_readonly',
|
||||
'_calc_properties', '_informations',
|
||||
'_state_readonly', '_state_requires', '_stated',
|
||||
|
@ -34,13 +34,14 @@ class Base(object):
|
|||
'_state_callback_params', '_callback_params', '_multitype',
|
||||
'_consistencies', '_warnings_only', '_master_slaves',
|
||||
'_state_consistencies', '_extra', '_subdyn', '__weakref__',
|
||||
'_state_master_slaves')
|
||||
'_state_master_slaves', '_choice_values',
|
||||
'_choice_values_params')
|
||||
|
||||
def __init__(self):
|
||||
try:
|
||||
self._subdyn
|
||||
except AttributeError:
|
||||
self._subdyn = False
|
||||
self._subdyn = None
|
||||
try:
|
||||
self._consistencies
|
||||
except AttributeError:
|
||||
|
@ -52,7 +53,7 @@ class Base(object):
|
|||
try:
|
||||
self._callback_params
|
||||
except AttributeError:
|
||||
self._callback_params = None
|
||||
self._callback_params = {}
|
||||
try:
|
||||
self._validator
|
||||
except AttributeError:
|
||||
|
@ -71,19 +72,22 @@ class Base(object):
|
|||
def _get_id(self):
|
||||
return id(self)
|
||||
|
||||
def _is_subdyn(self):
|
||||
try:
|
||||
return self._subdyn is not False
|
||||
except AttributeError:
|
||||
return False
|
||||
def _impl_getsubdyn(self):
|
||||
return self._subdyn
|
||||
|
||||
def _impl_setsubdyn(self, subdyn):
|
||||
self._subdyn = subdyn
|
||||
|
||||
def commit(self):
|
||||
pass
|
||||
|
||||
|
||||
class OptionDescription(Base):
|
||||
class StorageOptionDescription(StorageBase):
|
||||
__slots__ = ('_children', '_cache_paths', '_cache_consistencies',
|
||||
'_group_type', '_is_build_cache', '_state_group_type')
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
self._cache_paths = None
|
||||
|
||||
def _add_children(self, child_names, children):
|
||||
self._children = (tuple(child_names), tuple(children))
|
||||
|
@ -104,10 +108,14 @@ class OptionDescription(Base):
|
|||
raise AttributeError(_('no option {0} found').format(opt))
|
||||
|
||||
def impl_get_group_type(self): # pragma: optional cover
|
||||
return getattr(groups, self._group_type)
|
||||
return self._group_type
|
||||
|
||||
def impl_build_cache_option(self, _currpath=None, cache_path=None,
|
||||
cache_option=None):
|
||||
try:
|
||||
self._cache_paths
|
||||
except AttributeError:
|
||||
self._cache_paths = None
|
||||
if _currpath is None and self._cache_paths is not None: # pragma: optional cover
|
||||
# cache already set
|
||||
return
|
||||
|
@ -145,8 +153,7 @@ class OptionDescription(Base):
|
|||
found = True
|
||||
break
|
||||
if not found:
|
||||
#FIXME
|
||||
raise ConfigError(_('hu?'))
|
||||
raise ConfigError(_('cannot find dynpath'))
|
||||
subpath = subpath + suffix
|
||||
for slength in xrange(length, len(spath)):
|
||||
subpath = subpath + '.' + spath[slength] + suffix
|
||||
|
@ -226,21 +233,17 @@ class OptionDescription(Base):
|
|||
return find_results[0]
|
||||
return find_results
|
||||
|
||||
def _impl_st_getchildren(self):
|
||||
return self._children[1]
|
||||
def _impl_st_getchildren(self, context, only_dyn=False):
|
||||
for child in self._children[1]:
|
||||
if only_dyn is False or child.impl_is_dynoptiondescription():
|
||||
yield(child)
|
||||
|
||||
def __getattr__(self, name, context=undefined):
|
||||
if name == '_name':
|
||||
return object.__getattribute__(self, name)
|
||||
return self._getattr(name, context=context)
|
||||
|
||||
def _getattr(self, name, dyn_od=undefined, suffix=undefined,
|
||||
context=undefined, dyn=True):
|
||||
def _getattr(self, name, suffix=undefined, context=undefined, dyn=True):
|
||||
error = False
|
||||
if suffix is not undefined:
|
||||
try:
|
||||
if undefined in [dyn_od, suffix, context]: # pragma: optional cover
|
||||
raise ConfigError(_("dyn_od, suffix and context needed if "
|
||||
if undefined in [suffix, context]: # pragma: optional cover
|
||||
raise ConfigError(_("suffix and context needed if "
|
||||
"it's a dyn option"))
|
||||
if name.endswith(suffix):
|
||||
oname = name[:-len(suffix)]
|
||||
|
@ -270,3 +273,13 @@ class OptionDescription(Base):
|
|||
raise AttributeError(_('unknown Option {0} '
|
||||
'in OptionDescription {1}'
|
||||
'').format(name, self._name))
|
||||
|
||||
def _get_force_store_value(self):
|
||||
#FIXME faire des tests (notamment pas ajouter à un config)
|
||||
#FIXME devrait faire un cache !
|
||||
opts, paths = self._cache_paths
|
||||
for index in range(0, len(paths)):
|
||||
opt = opts[index]
|
||||
path = paths[index]
|
||||
if 'force_store_value' in opt._properties:
|
||||
yield (opt, path)
|
||||
|
|
|
@ -42,13 +42,12 @@ class Settings(Cache):
|
|||
def reset_all_properties(self):
|
||||
self._properties.clear()
|
||||
|
||||
def reset_properties(self, path):
|
||||
def delproperties(self, path):
|
||||
try:
|
||||
del(self._properties[path])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# permissive
|
||||
def setpermissive(self, path, permissive):
|
||||
self._permissives[path] = frozenset(permissive)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"default plugin for value: set it in a simple dictionary"
|
||||
# Copyright (C) 2013 Team tiramisu (see AUTHORS for all contributors)
|
||||
# Copyright (C) 2013-2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright (C) 2014 Team tiramisu (see AUTHORS for all contributors)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
# ____________________________________________________________
|
||||
"""Default plugin for storage. All informations are store in a simple
|
||||
dictionary in memory.
|
||||
|
||||
You cannot have persistente informations with this kind of storage.
|
||||
|
||||
The advantage of this solution is that you can easily create a Config and
|
||||
use it. But if something goes wrong, you will lost your modifications.
|
||||
"""
|
||||
from .value import Values
|
||||
from .setting import Settings
|
||||
from .storage import Storage, list_sessions, delete_session, setting
|
||||
from .option import StorageBase, StorageOptionDescription
|
||||
from .util import load
|
||||
|
||||
|
||||
load()
|
||||
|
||||
|
||||
__all__ = (setting, Values, Settings, Storage, list_sessions, delete_session,
|
||||
StorageBase, StorageOptionDescription)
|
||||
# Base, OptionDescription)
|
|
@ -18,28 +18,20 @@
|
|||
#
|
||||
# ____________________________________________________________
|
||||
from tiramisu.i18n import _
|
||||
from tiramisu.setting import groups
|
||||
from tiramisu.setting import groups, undefined
|
||||
from tiramisu.error import ConfigError
|
||||
from .util import SqlAlchemyBase
|
||||
import util
|
||||
|
||||
from sqlalchemy import not_, or_
|
||||
from sqlalchemy.ext.declarative import declarative_base, declared_attr
|
||||
from sqlalchemy.ext.declarative import declared_attr
|
||||
from sqlalchemy.ext.associationproxy import association_proxy
|
||||
from sqlalchemy import create_engine, Column, Integer, String, Boolean, \
|
||||
PickleType, ForeignKey, Table
|
||||
from sqlalchemy import Column, Integer, String, Boolean, PickleType, \
|
||||
ForeignKey, Table
|
||||
from sqlalchemy.orm import relationship, backref
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.orm.collections import attribute_mapped_collection
|
||||
|
||||
|
||||
#FIXME
|
||||
engine = create_engine('sqlite:///:memory:')
|
||||
SqlAlchemyBase = declarative_base()
|
||||
#FIXME a voir:
|
||||
# # Organization.members will be a Query object - no loading
|
||||
# # of the entire collection occurs unless requested
|
||||
# lazy="dynamic",
|
||||
#____________________________________________________________
|
||||
#
|
||||
# require
|
||||
from itertools import chain
|
||||
|
||||
|
||||
def load_requires(collection_type, proxy):
|
||||
|
@ -49,7 +41,7 @@ def load_requires(collection_type, proxy):
|
|||
ret = []
|
||||
requires = getattr(obj, proxy.value_attr)
|
||||
for require in requires:
|
||||
option = session.query(_Base).filter_by(id=require.option).first()
|
||||
option = util.session.query(_Base).filter_by(id=require.option).first()
|
||||
ret.append(tuple([option, require.expected, require.action, require.inverse, require.transitive, require.same_action]))
|
||||
return tuple(ret)
|
||||
|
||||
|
@ -158,7 +150,7 @@ def load_callback_parm(collection_type, proxy):
|
|||
if require.value is not None:
|
||||
ret.append(require.value)
|
||||
else:
|
||||
option = session.query(_Base).filter_by(id=require.option).first()
|
||||
option = util.session.query(_Base).filter_by(id=require.option).first()
|
||||
ret.append((option, require.force_permissive))
|
||||
return tuple(ret)
|
||||
|
||||
|
@ -175,10 +167,10 @@ class _CallbackParamOption(SqlAlchemyBase):
|
|||
force_permissive = Column(Boolean)
|
||||
value = Column(PickleType)
|
||||
|
||||
def __init__(self, option=None, force_permissive=None, value=None):
|
||||
if value is not None:
|
||||
def __init__(self, option=undefined, force_permissive=undefined, value=undefined):
|
||||
if value is not undefined:
|
||||
self.value = value
|
||||
else:
|
||||
elif option is not undefined:
|
||||
self.option = option.id
|
||||
self.force_permissive = force_permissive
|
||||
|
||||
|
@ -194,8 +186,11 @@ class _CallbackParam(SqlAlchemyBase):
|
|||
self.key = key
|
||||
for param in params:
|
||||
if isinstance(param, tuple):
|
||||
self.params.append(_CallbackParamOption(option=param[0],
|
||||
force_permissive=param[1]))
|
||||
if param == (None,):
|
||||
self.params.append(_CallbackParamOption())
|
||||
else:
|
||||
self.params.append(_CallbackParamOption(option=param[0],
|
||||
force_permissive=param[1]))
|
||||
else:
|
||||
self.params.append(_CallbackParamOption(value=param))
|
||||
|
||||
|
@ -215,7 +210,7 @@ class _Consistency(SqlAlchemyBase):
|
|||
func = Column(PickleType)
|
||||
params = Column(PickleType)
|
||||
|
||||
def __init__(self, func, all_cons_opts):
|
||||
def __init__(self, func, all_cons_opts, params):
|
||||
self.func = func
|
||||
for option in all_cons_opts:
|
||||
option._consistencies.append(self)
|
||||
|
@ -249,9 +244,16 @@ class _Base(SqlAlchemyBase):
|
|||
_informations = association_proxy("_infos", "value")
|
||||
_default = Column(PickleType)
|
||||
_default_multi = Column(PickleType)
|
||||
_subdyn = Column(Integer)
|
||||
_choice_values = Column(PickleType)
|
||||
_cho_params = relationship('_CallbackParam',
|
||||
collection_class=
|
||||
attribute_mapped_collection('key'))
|
||||
_choice_params = association_proxy("_cho_params", "params",
|
||||
getset_factory=load_callback_parm)
|
||||
_reqs = relationship("_Require", collection_class=list)
|
||||
_requires = association_proxy("_reqs", "requires", getset_factory=load_requires)
|
||||
_multi = Column(Boolean)
|
||||
_multi = Column(Integer)
|
||||
_multitype = Column(String)
|
||||
######
|
||||
_callback = Column(PickleType)
|
||||
|
@ -264,7 +266,7 @@ class _Base(SqlAlchemyBase):
|
|||
_val_params = relationship('_CallbackParam',
|
||||
collection_class=
|
||||
attribute_mapped_collection('key'))
|
||||
_validator_params = association_proxy("_call_params", "params",
|
||||
_validator_params = association_proxy("_val_params", "params",
|
||||
getset_factory=load_callback_parm)
|
||||
######
|
||||
#FIXME pas 2 fois la meme properties dans la base ...
|
||||
|
@ -290,11 +292,11 @@ class _Base(SqlAlchemyBase):
|
|||
_is_build_cache = Column(Boolean, default=False)
|
||||
|
||||
def __init__(self):
|
||||
util.session.add(self)
|
||||
self.commit()
|
||||
|
||||
def commit(self):
|
||||
session.add(self)
|
||||
session.commit()
|
||||
util.session.commit()
|
||||
|
||||
def _add_consistency(self, func, all_cons_opts, params):
|
||||
_Consistency(func, all_cons_opts, params)
|
||||
|
@ -306,52 +308,35 @@ class _Base(SqlAlchemyBase):
|
|||
def _get_id(self):
|
||||
return self.id
|
||||
|
||||
# ____________________________________________________________
|
||||
# information
|
||||
#def impl_set_information(self, key, value):
|
||||
# """updates the information's attribute
|
||||
# (which is a dictionary)
|
||||
def _impl_getsubdyn(self):
|
||||
return self._subdyn
|
||||
|
||||
# :param key: information's key (ex: "help", "doc"
|
||||
# :param value: information's value (ex: "the help string")
|
||||
# """
|
||||
# info = session.query(_Information).filter_by(option=self.id, key=key).first()
|
||||
# #FIXME pas append ! remplacer !
|
||||
# if info is None:
|
||||
# self._informations.append(_Information(key, value))
|
||||
# else:
|
||||
# info.value = value
|
||||
|
||||
#def impl_get_information(self, key, default=None):
|
||||
# """retrieves one information's item
|
||||
|
||||
# :param key: the item string (ex: "help")
|
||||
# """
|
||||
# info = session.query(_Information).filter_by(option=self.id, key=key).first()
|
||||
# if info is not None:
|
||||
# return info.value
|
||||
# return self._informations[key]
|
||||
# elif default is not None:
|
||||
# return default
|
||||
# else:
|
||||
# raise ValueError(_("information's item not found: {0}").format(
|
||||
# key))
|
||||
def _impl_setsubdyn(self, subdyn):
|
||||
self._subdyn = subdyn.id
|
||||
|
||||
|
||||
class Cache(SqlAlchemyBase):
|
||||
__tablename__ = 'cache'
|
||||
id = Column(Integer, primary_key=True)
|
||||
#FIXME indexer ... les 3
|
||||
path = Column(String, nullable=False)
|
||||
descr = Column(Integer, nullable=False)
|
||||
option = Column(Integer, nullable=False)
|
||||
opt_type = Column(String, nullable=False)
|
||||
path = Column(String, nullable=False, index=True)
|
||||
descr = Column(Integer, nullable=False, index=True)
|
||||
parent = Column(Integer, nullable=False, index=True)
|
||||
option = Column(Integer, nullable=False, index=True)
|
||||
opt_type = Column(String, nullable=False, index=True)
|
||||
is_subdyn = Column(Boolean, nullable=False, index=True)
|
||||
subdyn_path = Column(String)
|
||||
|
||||
def __init__(self, descr, option, path):
|
||||
def __init__(self, descr, parent, option, path, subdyn_path):
|
||||
self.descr = descr.id
|
||||
self.parent = parent.id
|
||||
self.option = option.id
|
||||
self.path = path
|
||||
self.opt_type = option.__class__.__name__
|
||||
#is_subdyn = option._is_subdyn()
|
||||
is_subdyn = option.impl_is_dynoptiondescription()
|
||||
self.is_subdyn = is_subdyn
|
||||
if is_subdyn:
|
||||
self.subdyn_path = subdyn_path
|
||||
|
||||
|
||||
class StorageOptionDescription(object):
|
||||
|
@ -359,14 +344,14 @@ class StorageOptionDescription(object):
|
|||
return self._is_build_cache
|
||||
|
||||
def impl_get_opt_by_path(self, path):
|
||||
ret = session.query(Cache).filter_by(descr=self.id, path=path).first()
|
||||
ret = util.session.query(Cache).filter_by(descr=self.id, path=path).first()
|
||||
if ret is None:
|
||||
raise AttributeError(_('no option for path {0}').format(path))
|
||||
return session.query(_Base).filter_by(id=ret.option).first()
|
||||
return util.session.query(_Base).filter_by(id=ret.option).first()
|
||||
|
||||
def impl_get_path_by_opt(self, opt):
|
||||
ret = session.query(Cache).filter_by(descr=self.id,
|
||||
option=opt.id).first()
|
||||
ret = util.session.query(Cache).filter_by(descr=self.id,
|
||||
option=opt.id).first()
|
||||
if ret is None:
|
||||
raise AttributeError(_('no option {0} found').format(opt))
|
||||
return ret.path
|
||||
|
@ -374,30 +359,36 @@ class StorageOptionDescription(object):
|
|||
def impl_get_group_type(self):
|
||||
return getattr(groups, self._group_type)
|
||||
|
||||
def impl_build_cache_option(self, descr=None, _currpath=None):
|
||||
def impl_build_cache_option(self, descr=None, _currpath=None,
|
||||
subdyn_path=None):
|
||||
if descr is None:
|
||||
save = True
|
||||
descr = self
|
||||
_currpath = []
|
||||
else:
|
||||
save = False
|
||||
for option in self.impl_getchildren():
|
||||
for option in self._impl_getchildren(dyn=False):
|
||||
attr = option.impl_getname()
|
||||
session.add(Cache(descr, option,
|
||||
str('.'.join(_currpath + [attr]))))
|
||||
util.session.add(Cache(descr, self, option,
|
||||
str('.'.join(_currpath + [attr])), subdyn_path))
|
||||
if isinstance(option, StorageOptionDescription):
|
||||
if option.impl_is_dynoptiondescription():
|
||||
subdyn_path = '.'.join(_currpath)
|
||||
_currpath.append(attr)
|
||||
option.impl_build_cache_option(descr,
|
||||
_currpath)
|
||||
_currpath,
|
||||
subdyn_path)
|
||||
_currpath.pop()
|
||||
if save:
|
||||
self._is_build_cache = True
|
||||
session.commit()
|
||||
util.session.commit()
|
||||
|
||||
def impl_get_options_paths(self, bytype, byname, _subpath, only_first):
|
||||
sqlquery = session.query(Cache).filter_by(descr=self.id)
|
||||
def impl_get_options_paths(self, bytype, byname, _subpath, only_first,
|
||||
context):
|
||||
sqlquery = util.session.query(Cache).filter_by(descr=self.id)
|
||||
if bytype is None:
|
||||
sqlquery = sqlquery.filter(not_(Cache.opt_type == 'OptionDescription'))
|
||||
sqlquery = sqlquery.filter(not_(
|
||||
Cache.opt_type == 'OptionDescription'))
|
||||
else:
|
||||
sqlquery = sqlquery.filter_by(opt_type=bytype.__name__)
|
||||
|
||||
|
@ -413,46 +404,111 @@ class StorageOptionDescription(object):
|
|||
if or_query != '':
|
||||
filter_query = or_(Cache.path == or_query, filter_query)
|
||||
sqlquery = sqlquery.filter(filter_query)
|
||||
if only_first:
|
||||
opt = sqlquery.first()
|
||||
if opt is None:
|
||||
return tuple()
|
||||
option = session.query(_Base).filter_by(id=opt.option).first()
|
||||
return ((opt.path, option),)
|
||||
else:
|
||||
ret = []
|
||||
for opt in sqlquery.all():
|
||||
option = session.query(_Base).filter_by(id=opt.option).first()
|
||||
ret.append((opt.path, option))
|
||||
return ret
|
||||
#if only_first:
|
||||
# opt = sqlquery.first()
|
||||
# if opt is None:
|
||||
# return tuple()
|
||||
# option = util.session.query(_Base).filter_by(id=opt.option).first()
|
||||
# return ((opt.path, option),)
|
||||
#else:
|
||||
ret = []
|
||||
for opt in sqlquery.all():
|
||||
option = util.session.query(_Base).filter_by(id=opt.option).first()
|
||||
if opt.is_subdyn:
|
||||
name = option.impl_getname()
|
||||
if byname is not None and byname.startswith(name):
|
||||
found = False
|
||||
for suffix in option._subdyn._impl_get_suffixes(
|
||||
context):
|
||||
if byname == name + suffix:
|
||||
found = True
|
||||
subdyn_path = opt.subdyn_path
|
||||
dynpaths = opt.path[len(subdyn_path):].split('.')
|
||||
|
||||
path = subdyn_path
|
||||
for dynpath in dynpaths:
|
||||
path += '.' + dynpath + suffix
|
||||
option = option._impl_to_dyn(
|
||||
name + suffix, path)
|
||||
break
|
||||
if not found:
|
||||
break
|
||||
else:
|
||||
ret_opt = (opt.path, option)
|
||||
if only_first:
|
||||
return ret_opt
|
||||
ret.append(ret_opt)
|
||||
return ret
|
||||
|
||||
def _add_children(self, child_names, children):
|
||||
for child in children:
|
||||
session.add(_Parent(self, child))
|
||||
util.session.add(_Parent(self, child))
|
||||
|
||||
def impl_getchildren(self):
|
||||
for child in session.query(_Parent).filter_by(parent_id=self.id).all():
|
||||
yield(session.query(_Base).filter_by(id=child.child_id).first())
|
||||
#return
|
||||
def _impl_st_getchildren(self, context, only_dyn=False):
|
||||
if only_dyn is False or context is undefined:
|
||||
for child in util.session.query(_Parent).filter_by(
|
||||
parent_id=self.id).all():
|
||||
yield(util.session.query(_Base).filter_by(id=child.child_id
|
||||
).first())
|
||||
else:
|
||||
descr = context.cfgimpl_get_description().id
|
||||
for child in util.session.query(Cache).filter_by(descr=descr,
|
||||
parent=self.id
|
||||
).filter_by(
|
||||
is_subdyn=True).all():
|
||||
yield(util.session.query(_Base).filter_by(id=child.option).first())
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name.startswith('_') or name.startswith('impl_'):
|
||||
return object.__getattribute__(self, name)
|
||||
child = session.query(_Parent).filter_by(parent_id=self.id, child_name=name).first()
|
||||
if child is None:
|
||||
raise AttributeError(_('unknown Option {0} '
|
||||
'in OptionDescription {1}'
|
||||
'').format(name, self.impl_getname()))
|
||||
return session.query(_Base).filter_by(id=child.child_id).first()
|
||||
def _getattr(self, name, suffix=undefined, context=undefined, dyn=True):
|
||||
error = False
|
||||
if suffix is not undefined:
|
||||
try:
|
||||
if undefined in [suffix, context]: # pragma: optional cover
|
||||
raise ConfigError(_("suffix and context needed if "
|
||||
"it's a dyn option"))
|
||||
if name.endswith(suffix):
|
||||
oname = name[:-len(suffix)]
|
||||
#child = self._children[1][self._children[0].index(oname)]
|
||||
child = util.session.query(_Parent).filter_by(
|
||||
parent_id=self.id, child_name=oname).first()
|
||||
if child is None:
|
||||
error = True
|
||||
else:
|
||||
opt = util.session.query(_Base).filter_by(
|
||||
id=child.child_id).first()
|
||||
return self._impl_get_dynchild(opt, suffix)
|
||||
else:
|
||||
error = True
|
||||
except ValueError: # pragma: optional cover
|
||||
error = True
|
||||
else:
|
||||
child = util.session.query(_Parent).filter_by(parent_id=self.id,
|
||||
child_name=name
|
||||
).first()
|
||||
if child is None:
|
||||
child = self._impl_search_dynchild(name, context=context)
|
||||
if child != []:
|
||||
return child
|
||||
error = True
|
||||
if error is False:
|
||||
return util.session.query(_Base).filter_by(id=child.child_id
|
||||
).first()
|
||||
if error:
|
||||
raise AttributeError(_('unknown Option {0} in OptionDescription {1}'
|
||||
'').format(name, self.impl_getname()))
|
||||
|
||||
def _get_force_store_value(self):
|
||||
#only option in current tree
|
||||
current_ids = tuple(chain(*util.session.query(Cache.option).filter_by(
|
||||
descr=self.id).all()))
|
||||
for prop in util.session.query(_PropertyOption).filter(
|
||||
_PropertyOption.option.in_(current_ids),
|
||||
_PropertyOption.name == 'force_store_value').all():
|
||||
opt = util.session.query(_Base).filter_by(id=prop.option).first()
|
||||
path = self.impl_get_path_by_opt(opt)
|
||||
yield (opt, path)
|
||||
|
||||
|
||||
class StorageBase(_Base):
|
||||
@declared_attr
|
||||
def __mapper_args__(self):
|
||||
return {'polymorphic_identity': self.__name__.lower()}
|
||||
|
||||
|
||||
#engine.echo = True
|
||||
SqlAlchemyBase.metadata.create_all(engine)
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
|
|
@ -80,8 +80,6 @@ class Values(object):
|
|||
# if value has callback and is not set
|
||||
if opt.impl_has_callback():
|
||||
callback, callback_params = opt.impl_get_callback()
|
||||
if callback_params is None:
|
||||
callback_params = {}
|
||||
value = carry_out_calculation(opt, config=self._getcontext(),
|
||||
callback=callback,
|
||||
callback_params=callback_params,
|
||||
|
@ -126,8 +124,8 @@ class Values(object):
|
|||
def get_modified_values(self):
|
||||
context = self._getcontext()
|
||||
if context._impl_descr is not None:
|
||||
for opt, path in context.cfgimpl_get_settings(
|
||||
).get_with_property('force_store_value'):
|
||||
for opt, path in context.cfgimpl_get_description(
|
||||
)._get_force_store_value():
|
||||
self._getowner(opt, path, force_permissive=True)
|
||||
return self._p_.get_modified_values()
|
||||
|
||||
|
@ -554,7 +552,6 @@ class Multi(list):
|
|||
self)
|
||||
|
||||
#def __repr__(self, *args, **kwargs):
|
||||
# print args, kwargs
|
||||
# return super(Multi, self).__repr__(*args, **kwargs)
|
||||
|
||||
#def __getitem__(self, y):
|
||||
|
|
Loading…
Reference in New Issue