better support for sqlalchemy storage
This commit is contained in:
@ -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
|
||||
|
Reference in New Issue
Block a user