This commit is contained in:
gwen 2013-09-02 15:11:38 +02:00
commit 5624a69e41
1 changed files with 101 additions and 84 deletions

View File

@ -96,7 +96,7 @@ class BaseOption(BaseInformation):
in options that have to be set only once, it is of course done in the in options that have to be set only once, it is of course done in the
__setattr__ method __setattr__ method
""" """
__slots__ = ('_readonly',) __slots__ = ('_readonly', '_state_consistencies', '_state_requires')
def __setattr__(self, name, value): def __setattr__(self, name, value):
"""set once and only once some attributes in the option, """set once and only once some attributes in the option,
@ -107,79 +107,97 @@ class BaseOption(BaseInformation):
"frozen" (which has noting to do with the high level "freeze" "frozen" (which has noting to do with the high level "freeze"
propertie or "read_only" property) propertie or "read_only" property)
""" """
is_readonly = False if not name.startswith('_state'):
# never change _name is_readonly = False
if name == '_name': # never change _name
if name == '_name':
try:
self._name
#so _name is already set
is_readonly = True
except:
pass
try: try:
self._name if self._readonly is True:
#so _name is already set if value is True:
is_readonly = True # already readonly and try to re set readonly
# don't raise, just exit
return
is_readonly = True
except AttributeError: except AttributeError:
pass pass
try: if is_readonly:
if self._readonly is True: raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is"
if value is True: " read-only").format(
# already readonly and try to re set readonly self.__class__.__name__,
# don't raise, just exit self._name,
return name))
is_readonly = True
except AttributeError:
pass
if is_readonly:
raise AttributeError(_("'{0}' ({1}) object attribute '{2}' is"
" read-only").format(
self.__class__.__name__, self._name,
name))
object.__setattr__(self, name, value) object.__setattr__(self, name, value)
def _impl_convert_consistencies(self, value, cache): def _impl_convert_consistencies(self, cache):
# cache is a dico in import/not a dico in export # cache is a dico in import/not a dico in export
new_value = [] if self._consistencies is None:
for consistency in value: self._state_consistencies = None
if isinstance(cache, dict): else:
new_value = (consistency[0], cache[consistency[1]]) new_value = []
else: for consistency in self._consistencies:
new_value = (consistency[0], cache.impl_get_path_by_opt(
consistency[1]))
return tuple(new_value)
def _impl_convert_requires(self, value, cache):
# cache is a dico in import/not a dico in export
new_value = []
for requires in value:
new_requires = []
for require in requires:
if isinstance(cache, dict): if isinstance(cache, dict):
new_require = [cache[require[0]]] new_value.append((consistency[0], cache[consistency[1]]))
else: else:
new_require = [cache.impl_get_path_by_opt(require[0])] new_value.append((consistency[0],
new_require.extend(require[1:]) cache.impl_get_path_by_opt(
new_requires.append(tuple(new_require)) consistency[1])))
new_value.append(tuple(new_requires)) if isinstance(cache, dict):
return tuple(new_value) pass
else:
self._state_consistencies = tuple(new_value)
def impl_export(self, descr): def _impl_convert_requires(self, cache):
descr.impl_build_cache() # cache is a dico in import/not a dico in export
# add _opt_type (not in __slots__) if self._requires is None:
slots = set(['_opt_type']) self._state_requires = None
else:
new_value = []
for requires in self._requires:
new_requires = []
for require in requires:
if isinstance(cache, dict):
new_require = [cache[require[0]]]
else:
new_require = [cache.impl_get_path_by_opt(require[0])]
new_require.extend(require[1:])
new_requires.append(tuple(new_require))
new_value.append(tuple(new_requires))
if isinstance(cache, dict):
pass
else:
self._state_requires = new_value
def _impl_getstate(self, descr):
self._impl_convert_consistencies(descr)
self._impl_convert_requires(descr)
def __getstate__(self, export=False):
slots = set()
for subclass in self.__class__.__mro__: for subclass in self.__class__.__mro__:
if subclass is not object: if subclass is not object:
slots.update(subclass.__slots__) slots.update(subclass.__slots__)
slots -= frozenset(['_children', '_readonly', '_cache_paths', slots -= frozenset(['_children', '_cache_paths', '__weakref__'])
'__weakref__']) states = {}
exported_object = {} for slot in slots:
for attr in slots: # remove variable if save variable converted in _state_xxxx variable
try: if '_state' + slot not in slots:
value = getattr(self, attr) if slot.startswith('_state'):
if value is not None: # should exists
if attr == '_consistencies': states[slot] = getattr(self, slot)
value = self._impl_convert_consistencies(value, descr) # remove _state_xxx variable
elif attr == '_requires': self.__delattr__(slot)
value = self._impl_convert_requires(value, descr) else:
exported_object[attr] = value try:
except AttributeError: states[slot] = getattr(self, slot)
pass except AttributeError:
return exported_object pass
return states
class Option(BaseOption): class Option(BaseOption):
@ -542,7 +560,7 @@ else:
class SymLinkOption(BaseOption): class SymLinkOption(BaseOption):
__slots__ = ('_name', '_opt') __slots__ = ('_name', '_opt', '_state_opt')
_opt_type = 'symlink' _opt_type = 'symlink'
def __init__(self, name, opt): def __init__(self, name, opt):
@ -560,11 +578,9 @@ class SymLinkOption(BaseOption):
else: else:
return getattr(self._opt, name) return getattr(self._opt, name)
def impl_export(self, descr): def _impl_getstate(self, descr):
export = super(SymLinkOption, self).impl_export(descr) super(SymLinkOption, self)._impl_getstate(descr)
export['_opt'] = descr.impl_get_path_by_opt(self._opt) self._state_opt = descr.impl_get_path_by_opt(self._opt)
del(export['_impl_informations'])
return export
class IPOption(Option): class IPOption(Option):
@ -786,8 +802,9 @@ class OptionDescription(BaseOption):
The `OptionsDescription` objects lives in the `tiramisu.config.Config`. The `OptionsDescription` objects lives in the `tiramisu.config.Config`.
""" """
__slots__ = ('_name', '_requires', '_cache_paths', '_group_type', __slots__ = ('_name', '_requires', '_cache_paths', '_group_type',
'_properties', '_children', '_consistencies', '_state_group_type', '_properties', '_children',
'_calc_properties', '__weakref__', '_readonly', '_impl_informations') '_consistencies', '_calc_properties', '__weakref__',
'_readonly', '_impl_informations')
_opt_type = 'optiondescription' _opt_type = 'optiondescription'
def __init__(self, name, doc, children, requires=None, properties=None): def __init__(self, name, doc, children, requires=None, properties=None):
@ -992,26 +1009,26 @@ class OptionDescription(BaseOption):
return False return False
return True return True
def _impl_convert_group_type(self, value, cache): def _impl_getstate(self, descr=None):
if isinstance(cache, dict):
value = str(value)
else:
value = getattr(groups, value)
return value
def impl_export(self, descr=None):
"""enables us to export into a dict """enables us to export into a dict
:param descr: parent :class:`tiramisu.option.OptionDescription` :param descr: parent :class:`tiramisu.option.OptionDescription`
""" """
if descr is None: if descr is None:
self.impl_build_cache()
descr = self descr = self
export = super(OptionDescription, self).impl_export(descr) super(OptionDescription, self)._impl_getstate(descr)
export['_group_type'] = self._impl_convert_group_type( self._state_group_type = str(self._group_type)
export['_group_type'], descr)
export['options'] = []
for option in self.impl_getchildren(): for option in self.impl_getchildren():
export['options'].append(option.impl_export(descr)) option._impl_getstate(descr)
return export
def __getstate__(self, export=False):
if not export:
self._impl_getstate()
states = super(OptionDescription, self).__getstate__(True)
states['_state_children'] = []
for option in self.impl_getchildren():
states['_state_children'].append(option.__getstate__(True))
return states
def validate_requires_arg(requires, name): def validate_requires_arg(requires, name):