add __setstate__ to loads from a serialised object
This commit is contained in:
parent
cc3a33ef4f
commit
0212a15387
|
@ -98,7 +98,7 @@ class BaseOption(BaseInformation):
|
||||||
"""
|
"""
|
||||||
__slots__ = ('_name', '_requires', '_properties', '_readonly',
|
__slots__ = ('_name', '_requires', '_properties', '_readonly',
|
||||||
'_consistencies', '_calc_properties', '_state_consistencies',
|
'_consistencies', '_calc_properties', '_state_consistencies',
|
||||||
'_state_requires', '_stated')
|
'_state_readonly', '_state_requires', '_stated')
|
||||||
|
|
||||||
def __init__(self, name, doc, requires, properties):
|
def __init__(self, name, doc, requires, properties):
|
||||||
if not valid_name(name):
|
if not valid_name(name):
|
||||||
|
@ -133,7 +133,7 @@ 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)
|
||||||
"""
|
"""
|
||||||
if not name.startswith('_state'):
|
if not name.startswith('_state') and name not in ('_cache_paths', '_consistencies'):
|
||||||
is_readonly = False
|
is_readonly = False
|
||||||
# never change _name
|
# never change _name
|
||||||
if name == '_name':
|
if name == '_name':
|
||||||
|
@ -160,42 +160,58 @@ class BaseOption(BaseInformation):
|
||||||
name))
|
name))
|
||||||
object.__setattr__(self, name, value)
|
object.__setattr__(self, name, value)
|
||||||
|
|
||||||
def _impl_convert_consistencies(self, cache):
|
def _impl_convert_consistencies(self, descr, load=False):
|
||||||
# cache is a dico in import/not a dico in export
|
if not load and self._consistencies is None:
|
||||||
if self._consistencies is None:
|
|
||||||
self._state_consistencies = None
|
self._state_consistencies = None
|
||||||
|
elif load and self._state_consistencies is None:
|
||||||
|
self._consistencies = None
|
||||||
|
del(self._state_consistencies)
|
||||||
else:
|
else:
|
||||||
|
if load:
|
||||||
|
consistencies = self._state_consistencies
|
||||||
|
else:
|
||||||
|
consistencies = self._consistencies
|
||||||
new_value = []
|
new_value = []
|
||||||
for consistency in self._consistencies:
|
for consistency in consistencies:
|
||||||
if isinstance(cache, dict):
|
if load:
|
||||||
new_value.append((consistency[0], cache[consistency[1]]))
|
new_value.append((consistency[0],
|
||||||
|
descr.impl_get_opt_by_path(
|
||||||
|
consistency[1])))
|
||||||
else:
|
else:
|
||||||
new_value.append((consistency[0],
|
new_value.append((consistency[0],
|
||||||
cache.impl_get_path_by_opt(
|
descr.impl_get_path_by_opt(
|
||||||
consistency[1])))
|
consistency[1])))
|
||||||
if isinstance(cache, dict):
|
if load:
|
||||||
pass
|
del(self._state_consistencies)
|
||||||
|
self._consistencies = tuple(new_value)
|
||||||
else:
|
else:
|
||||||
self._state_consistencies = tuple(new_value)
|
self._state_consistencies = tuple(new_value)
|
||||||
|
|
||||||
def _impl_convert_requires(self, cache):
|
def _impl_convert_requires(self, descr, load=False):
|
||||||
# cache is a dico in import/not a dico in export
|
if not load and self._requires is None:
|
||||||
if self._requires is None:
|
|
||||||
self._state_requires = None
|
self._state_requires = None
|
||||||
|
elif load and self._state_requires is None:
|
||||||
|
self._requires = None
|
||||||
|
del(self._state_requires)
|
||||||
else:
|
else:
|
||||||
|
if load:
|
||||||
|
_requires = self._state_requires
|
||||||
|
else:
|
||||||
|
_requires = self._requires
|
||||||
new_value = []
|
new_value = []
|
||||||
for requires in self._requires:
|
for requires in _requires:
|
||||||
new_requires = []
|
new_requires = []
|
||||||
for require in requires:
|
for require in requires:
|
||||||
if isinstance(cache, dict):
|
if load:
|
||||||
new_require = [cache[require[0]]]
|
new_require = [descr.impl_get_opt_by_path(require[0])]
|
||||||
else:
|
else:
|
||||||
new_require = [cache.impl_get_path_by_opt(require[0])]
|
new_require = [descr.impl_get_path_by_opt(require[0])]
|
||||||
new_require.extend(require[1:])
|
new_require.extend(require[1:])
|
||||||
new_requires.append(tuple(new_require))
|
new_requires.append(tuple(new_require))
|
||||||
new_value.append(tuple(new_requires))
|
new_value.append(tuple(new_requires))
|
||||||
if isinstance(cache, dict):
|
if load:
|
||||||
pass
|
del(self._state_requires)
|
||||||
|
self._requires = new_value
|
||||||
else:
|
else:
|
||||||
self._state_requires = new_value
|
self._state_requires = new_value
|
||||||
|
|
||||||
|
@ -203,8 +219,12 @@ class BaseOption(BaseInformation):
|
||||||
self._stated = True
|
self._stated = True
|
||||||
self._impl_convert_consistencies(descr)
|
self._impl_convert_consistencies(descr)
|
||||||
self._impl_convert_requires(descr)
|
self._impl_convert_requires(descr)
|
||||||
|
try:
|
||||||
|
self._state_readonly = self._readonly
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def __getstate__(self, export=False):
|
def __getstate__(self, stated=True):
|
||||||
try:
|
try:
|
||||||
self._stated
|
self._stated
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -228,8 +248,24 @@ class BaseOption(BaseInformation):
|
||||||
states[slot] = getattr(self, slot)
|
states[slot] = getattr(self, slot)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
if not stated:
|
||||||
|
del(states['_stated'])
|
||||||
return states
|
return states
|
||||||
|
|
||||||
|
def _impl_setstate(self, descr):
|
||||||
|
self._impl_convert_consistencies(descr, load=True)
|
||||||
|
self._impl_convert_requires(descr, load=True)
|
||||||
|
try:
|
||||||
|
self._readonly = self._state_readonly
|
||||||
|
del(self._state_readonly)
|
||||||
|
del(self._stated)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __setstate__(self, state):
|
||||||
|
for key, value in state.items():
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
|
||||||
class Option(BaseOption):
|
class Option(BaseOption):
|
||||||
"""
|
"""
|
||||||
|
@ -596,6 +632,11 @@ class SymLinkOption(BaseOption):
|
||||||
super(SymLinkOption, self)._impl_getstate(descr)
|
super(SymLinkOption, self)._impl_getstate(descr)
|
||||||
self._state_opt = descr.impl_get_path_by_opt(self._opt)
|
self._state_opt = descr.impl_get_path_by_opt(self._opt)
|
||||||
|
|
||||||
|
def _impl_setstate(self, descr):
|
||||||
|
self._opt = descr.impl_get_opt_by_path(self._state_opt)
|
||||||
|
del(self._state_opt)
|
||||||
|
super(SymLinkOption, self)._impl_setstate(descr)
|
||||||
|
|
||||||
|
|
||||||
class IPOption(Option):
|
class IPOption(Option):
|
||||||
"represents the choice of an ip"
|
"represents the choice of an ip"
|
||||||
|
@ -885,14 +926,16 @@ class OptionDescription(BaseOption):
|
||||||
cache_path=None,
|
cache_path=None,
|
||||||
cache_option=None,
|
cache_option=None,
|
||||||
_currpath=None,
|
_currpath=None,
|
||||||
_consistencies=None):
|
_consistencies=None,
|
||||||
|
force_no_consistencies=False):
|
||||||
if _currpath is None and self._cache_paths is not None:
|
if _currpath is None and self._cache_paths is not None:
|
||||||
# cache already set
|
# cache already set
|
||||||
return
|
return
|
||||||
if _currpath is None:
|
if _currpath is None:
|
||||||
save = True
|
save = True
|
||||||
_currpath = []
|
_currpath = []
|
||||||
_consistencies = {}
|
if not force_no_consistencies:
|
||||||
|
_consistencies = {}
|
||||||
else:
|
else:
|
||||||
save = False
|
save = False
|
||||||
if cache_path is None:
|
if cache_path is None:
|
||||||
|
@ -904,10 +947,12 @@ class OptionDescription(BaseOption):
|
||||||
raise ConflictError(_('duplicate option: {0}').format(option))
|
raise ConflictError(_('duplicate option: {0}').format(option))
|
||||||
|
|
||||||
cache_option.append(option)
|
cache_option.append(option)
|
||||||
option._readonly = True
|
if not force_no_consistencies:
|
||||||
|
option._readonly = True
|
||||||
cache_path.append(str('.'.join(_currpath + [attr])))
|
cache_path.append(str('.'.join(_currpath + [attr])))
|
||||||
if not isinstance(option, OptionDescription):
|
if not isinstance(option, OptionDescription):
|
||||||
if option._consistencies is not None:
|
if not force_no_consistencies and \
|
||||||
|
option._consistencies is not None:
|
||||||
for consistency in option._consistencies:
|
for consistency in option._consistencies:
|
||||||
func, opt = consistency
|
func, opt = consistency
|
||||||
opts = (option, opt)
|
opts = (option, opt)
|
||||||
|
@ -920,12 +965,14 @@ class OptionDescription(BaseOption):
|
||||||
option.impl_build_cache(cache_path,
|
option.impl_build_cache(cache_path,
|
||||||
cache_option,
|
cache_option,
|
||||||
_currpath,
|
_currpath,
|
||||||
_consistencies)
|
_consistencies,
|
||||||
|
force_no_consistencies)
|
||||||
_currpath.pop()
|
_currpath.pop()
|
||||||
if save:
|
if save:
|
||||||
self._cache_paths = (tuple(cache_option), tuple(cache_path))
|
self._cache_paths = (tuple(cache_option), tuple(cache_path))
|
||||||
self._consistencies = _consistencies
|
if not force_no_consistencies:
|
||||||
self._readonly = True
|
self._consistencies = _consistencies
|
||||||
|
self._readonly = True
|
||||||
|
|
||||||
def impl_get_opt_by_path(self, path):
|
def impl_get_opt_by_path(self, path):
|
||||||
try:
|
try:
|
||||||
|
@ -1023,15 +1070,38 @@ class OptionDescription(BaseOption):
|
||||||
option._impl_getstate(descr)
|
option._impl_getstate(descr)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
|
stated = True
|
||||||
try:
|
try:
|
||||||
del(self._stated)
|
self._stated
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# if cannot delete, _impl_getstate never launch
|
# if cannot delete, _impl_getstate never launch
|
||||||
# launch it recursivement
|
# launch it recursivement
|
||||||
# _stated prevent __getstate__ launch more than one time
|
# _stated prevent __getstate__ launch more than one time
|
||||||
# _stated is delete, if re-serialize, re-lauch _impl_getstate
|
# _stated is delete, if re-serialize, re-lauch _impl_getstate
|
||||||
self._impl_getstate()
|
self._impl_getstate()
|
||||||
return super(OptionDescription, self).__getstate__()
|
stated = False
|
||||||
|
return super(OptionDescription, self).__getstate__(stated)
|
||||||
|
|
||||||
|
def _impl_setstate(self, descr=None):
|
||||||
|
"""enables us to import from a dict
|
||||||
|
:param descr: parent :class:`tiramisu.option.OptionDescription`
|
||||||
|
"""
|
||||||
|
if descr is None:
|
||||||
|
self._cache_paths = None
|
||||||
|
self.impl_build_cache(force_no_consistencies=True)
|
||||||
|
descr = self
|
||||||
|
self._group_type = getattr(groups, self._state_group_type)
|
||||||
|
del(self._state_group_type)
|
||||||
|
super(OptionDescription, self)._impl_setstate(descr)
|
||||||
|
for option in self.impl_getchildren():
|
||||||
|
option._impl_setstate(descr)
|
||||||
|
|
||||||
|
def __setstate__(self, state):
|
||||||
|
super(OptionDescription, self).__setstate__(state)
|
||||||
|
try:
|
||||||
|
self._stated
|
||||||
|
except AttributeError:
|
||||||
|
self._impl_setstate()
|
||||||
|
|
||||||
|
|
||||||
def validate_requires_arg(requires, name):
|
def validate_requires_arg(requires, name):
|
||||||
|
|
Loading…
Reference in New Issue