remove pickle dump/load support

This commit is contained in:
Emmanuel Garette 2017-07-21 18:46:11 +02:00
parent ddaadb0701
commit 32e88299e2
13 changed files with 20 additions and 900 deletions

View file

@ -14,7 +14,6 @@ from tiramisu.storage import delete_session
from .test_state import _diff_opts, _diff_conf from .test_state import _diff_opts, _diff_conf
from py.test import raises from py.test import raises
from pickle import dumps, loads
def return_true(value, param=None, suffix=None): def return_true(value, param=None, suffix=None):
@ -1311,36 +1310,6 @@ def test_masterslaves_callback_samegroup_dyndescription():
#assert cfg.getowner(st3val2) == owners.default #assert cfg.getowner(st3val2) == owners.default
def test_state_config():
a = IPOption('a', '')
b = NetmaskOption('b', '')
dod1 = DynOptionDescription('dod1', '', [a, b], callback=return_list)
b.impl_add_consistency('ip_netmask', a)
od1 = OptionDescription('od1', '', [dod1])
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True)
st3 = StrOption('st3', "", multi=True, callback=return_dynval, callback_params={'': ((st2, False),)})
stm = OptionDescription('st1', '', [st1, st2, st3])
stm.impl_set_group_type(groups.master)
st = DynOptionDescription('st', '', [stm], callback=return_list)
od = OptionDescription('od', '', [st])
od2 = OptionDescription('od', '', [od, od1])
try:
cfg = Config(od2, persistent=True, session_id='c29090938')
except ValueError:
cfg = Config(od2, session_id='c29090938')
cfg._impl_test = True
a = dumps(cfg)
q = loads(a)
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
_diff_conf(cfg, q)
try:
delete_session('config', 'c29090938')
except ValueError:
pass
def test_invalid_conflict_dyndescription(): def test_invalid_conflict_dyndescription():
st = StrOption('st', '') st = StrOption('st', '')
dod = DynOptionDescription('dod', '', [st], callback=return_list) dod = DynOptionDescription('dod', '', [st], callback=return_list)

View file

@ -2,21 +2,13 @@
#do_autopath() #do_autopath()
# #
from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \ from tiramisu.option import BoolOption, UnicodeOption, SymLinkOption, \
IntOption, IPOption, NetmaskOption, StrOption, OptionDescription, \ OptionDescription, DynOptionDescription
DynOptionDescription, MasterSlaves from tiramisu.config import Config
from tiramisu.config import Config, GroupConfig, MetaConfig from pickle import dumps
from tiramisu.setting import groups, owners
from tiramisu.storage import delete_session
from tiramisu.error import ConfigError
from pickle import dumps, loads
from py.test import raises from py.test import raises
import sys import sys
def return_value(value=None):
return value
def _get_slots(opt): def _get_slots(opt):
slots = set() slots = set()
for subclass in opt.__class__.__mro__: for subclass in opt.__class__.__mro__:
@ -221,34 +213,7 @@ def test_diff_opt():
o = OptionDescription('o', '', [b, u, s]) o = OptionDescription('o', '', [b, u, s])
o1 = OptionDescription('o1', '', [o]) o1 = OptionDescription('o1', '', [o])
a = dumps(o1) raises(NotImplementedError, "dumps(o1)")
q = loads(a)
_diff_opts(o1, q)
def test_diff_optdesc():
u = UnicodeOption('u', '')
b = BoolOption('b', '')
od = OptionDescription('od', '', [b], requires=[{'option': u, 'expected': u'u', 'action': 'disabled', 'inverse': True}])
o = OptionDescription('o', '', [u, od])
o1 = OptionDescription('o1', '', [o])
a = dumps(o1)
q = loads(a)
_diff_opts(o1, q)
def test_diff_information():
b = BoolOption('b', '')
b.impl_set_information('doc', 'oh')
b.impl_set_information('doc1', 'oh')
b.impl_set_information('doc2', 'oh')
o = OptionDescription('o', '', [b])
o1 = OptionDescription('o1', '', [o])
a = dumps(o1)
q = loads(a)
_diff_opts(o1, q)
def test_diff_information_config(): def test_diff_information_config():
@ -258,328 +223,10 @@ def test_diff_information_config():
b.impl_set_information('info2', 'oh') b.impl_set_information('info2', 'oh')
o = OptionDescription('o', '', [b]) o = OptionDescription('o', '', [b])
o1 = OptionDescription('o1', '', [o]) o1 = OptionDescription('o1', '', [o])
try: raises(NotImplementedError, "dumps(Config(o1))")
cfg = Config(o1, persistent=True, session_id='c29090938')
except ValueError:
cfg = Config(o1, session_id='c29090938')
cfg._impl_test = True
cfg.impl_set_information('info', 'oh')
a = dumps(cfg)
q = loads(a)
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
_diff_conf(cfg, q)
assert cfg.impl_get_information('info') == 'oh'
assert q.impl_get_information('info') == 'oh'
try:
delete_session('config', 'c29090938')
except ValueError:
pass
def test_diff_opt_multi():
b = BoolOption('b', '', multi=True)
o = OptionDescription('o', '', [b])
o1 = OptionDescription('o1', '', [o])
a = dumps(o1)
q = loads(a)
_diff_opt(o1, q)
_diff_opt(o1.o, q.o)
_diff_opt(o1.o.b, q.o.b)
def test_only_optiondescription(): def test_only_optiondescription():
b = BoolOption('b', '') b = BoolOption('b', '')
b b
raises(SystemError, "a = dumps(b)") raises(NotImplementedError, "a = dumps(b)")
def test_diff_opt_cache():
b = BoolOption('b', '')
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
u.impl_add_consistency('not_equal', b)
s = SymLinkOption('s', u)
o = OptionDescription('o', '', [b, u, s])
o1 = OptionDescription('o1', '', [o])
o1.impl_build_cache_option()
a = dumps(o1)
q = loads(a)
_diff_opts(o1, q)
def test_diff_opt_callback():
b = BoolOption('b', '', callback=return_value)
b2 = BoolOption('b2', '', callback=return_value, callback_params={'': ('yes',)})
b3 = BoolOption('b3', '', callback=return_value, callback_params={'': ('yes', (b, False)), 'value': ('no',)})
b4 = BoolOption("b4", "", callback=return_value, callback_params={'': ((None,),), 'value': ('string',)})
o = OptionDescription('o', '', [b, b2, b3, b4])
o1 = OptionDescription('o1', '', [o])
o1.impl_build_cache_option()
a = dumps(o1)
q = loads(a)
_diff_opts(o1, q)
def test_no_state_attr():
# all _state_xxx attributes should be deleted
b = BoolOption('b', '')
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
s = SymLinkOption('s', u)
o = OptionDescription('o', '', [b, u, s])
o1 = OptionDescription('o1', '', [o])
a = dumps(o1)
q = loads(a)
_no_state(q)
_no_state(q.o)
_no_state(q.o.b)
_no_state(q.o.u)
_no_state(q.o.s)
def test_state_config():
val1 = BoolOption('val1', "")
maconfig = OptionDescription('rootconfig', '', [val1])
try:
cfg = Config(maconfig, persistent=True, session_id='c29090931')
except ValueError:
cfg = Config(maconfig, session_id='c29090931')
cfg._impl_test = True
a = dumps(cfg)
q = loads(a)
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
_diff_conf(cfg, q)
try:
delete_session('config', 'c29090931')
except ValueError:
pass
def test_state_config2():
a = IPOption('a', '')
b = NetmaskOption('b', '')
dod1 = OptionDescription('dod1', '', [a, b])
b.impl_add_consistency('ip_netmask', a)
od1 = OptionDescription('od1', '', [dod1])
st1 = StrOption('st1', "", multi=True)
st2 = StrOption('st2', "", multi=True)
st3 = StrOption('st3', "", multi=True, callback=return_value, callback_params={'': ((st2, False),)})
stm = OptionDescription('st1', '', [st1, st2, st3])
stm.impl_set_group_type(groups.master)
st = OptionDescription('st', '', [stm])
od = OptionDescription('od', '', [st])
od2 = OptionDescription('od', '', [od, od1])
try:
cfg = Config(od2, persistent=True, session_id='c29090939')
except ValueError:
cfg = Config(od2, session_id='c29090939')
cfg._impl_test = True
a = dumps(cfg)
q = loads(a)
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
_diff_conf(cfg, q)
try:
delete_session('config', 'c29090939')
except ValueError:
pass
def test_diff_opt_value():
b = BoolOption('b', '')
u = UnicodeOption('u', '', properties=('force_store_value',))
s = SymLinkOption('s', u)
o = OptionDescription('o', '', [b, u, s])
o1 = OptionDescription('o1', '', [o])
try:
cfg = Config(o1, persistent=True, session_id='c29090941')
except ValueError:
cfg = Config(o1, session_id='c29090941')
cfg._impl_test = True
a = dumps(cfg)
q = loads(a)
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
_diff_conf(cfg, q)
try:
delete_session('config', 'c29090941')
except ValueError:
pass
def test_diff_opt_config():
b = BoolOption('b', '')
u = UnicodeOption('u', '', requires=[{'option': b, 'expected': True, 'action': 'disabled', 'inverse': True}])
u.impl_set_information('info', 'oh')
u.impl_set_information('info1', 'oh')
u.impl_set_information('info2', 'oh')
s = SymLinkOption('s', u)
o = OptionDescription('o', '', [b, u, s])
o1 = OptionDescription('o1', '', [o])
try:
cfg = Config(o1, persistent=True, session_id='c29090940')
except ValueError:
cfg = Config(o1, session_id='c29090940')
cfg._impl_test = True
a = dumps(cfg)
q = loads(a)
_diff_opts(cfg.cfgimpl_get_description(), q.cfgimpl_get_description())
_diff_conf(cfg, q)
try:
delete_session('config', 'c29090940')
except ValueError:
pass
def test_state_properties():
val1 = BoolOption('val1', "")
maconfig = OptionDescription('rootconfig', '', [val1])
try:
cfg = Config(maconfig, persistent=True, session_id='c29090932')
except ValueError:
cfg = Config(maconfig, session_id='c29090932')
cfg._impl_test = True
cfg.read_write()
cfg.cfgimpl_get_settings()[val1].append('test')
a = dumps(cfg)
q = loads(a)
_diff_conf(cfg, q)
try:
delete_session('config', 'c29090932')
except ValueError:
pass
def test_state_values():
val1 = BoolOption('val1', "")
maconfig = OptionDescription('rootconfig', '', [val1])
try:
cfg = Config(maconfig, persistent=True, session_id='c29090933')
except ValueError:
cfg = Config(maconfig, session_id='c29090933')
cfg._impl_test = True
cfg.val1 = True
a = dumps(cfg)
q = loads(a)
_diff_conf(cfg, q)
q.val1 = False
assert cfg.val1 is True
assert q.val1 is False
try:
delete_session('config', 'c29090933')
except ValueError:
pass
def test_state_values_owner():
val1 = BoolOption('val1', "")
maconfig = OptionDescription('rootconfig', '', [val1])
try:
cfg = Config(maconfig, persistent=True, session_id='c29090934')
except ValueError:
cfg = Config(maconfig, session_id='c29090934')
cfg._impl_test = True
owners.addowner('newowner')
cfg.cfgimpl_get_settings().setowner(owners.newowner)
cfg.val1 = True
a = dumps(cfg)
q = loads(a)
_diff_conf(cfg, q)
q.val1 = False
nval1 = q.cfgimpl_get_description().val1
assert q.getowner(nval1) == owners.newowner
try:
delete_session('config', 'c29090934')
except ValueError:
pass
def test_state_metaconfig():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
try:
cfg = Config(od2, persistent=True, session_id='c29090935')
except ValueError:
conf1 = Config(od2, session_id='c29090935')
conf1._impl_test = True
conf2 = Config(od2, session_id='c29090936')
conf2._impl_test = True
meta = MetaConfig([conf1, conf2], session_id='c29090937')
meta._impl_test = True
raises(ConfigError, "dumps(meta)")
try:
delete_session('config', 'c29090935')
except ValueError:
pass
def test_state_groupconfig():
i1 = IntOption('i1', '')
od1 = OptionDescription('od1', '', [i1])
od2 = OptionDescription('od2', '', [od1])
try:
cfg = Config(od2, persistent=True, session_id='c29090938')
except ValueError:
conf1 = Config(od2, session_id='c29090938')
conf1._impl_test = True
conf2 = Config(od2, session_id='c29090939')
conf2._impl_test = True
meta = GroupConfig([conf1, conf2], session_id='c29090940')
meta._impl_test = True
a = dumps(meta)
q = loads(a)
_diff_conf(meta, q)
try:
delete_session('config', 'c29090938')
except ValueError:
pass
#def test_state_unkown_setting_owner():
# """load an unknow _owner, should create it"""
# assert not 'supernewuser' in owners.__dict__
# val = """ccopy_reg
#_reconstructor
#p0
#(ctiramisu.setting
#Settings
#p1
#c__builtin__
#object
#p2
#Ntp3
#Rp4
#(dp5
#S'_owner'
#p6
#S'supernewuser'
#p7
#sS'_p_'
#p8
#g0
#(ctiramisu.storage.dictionary.setting
#Properties
#p9
#g2
#Ntp10
#Rp11
#(dp12
#S'_cache'
#p13
#(dp14
#sS'_permissives'
#p15
#(dp16
#sS'_properties'
#p17
#(dp18
#sbsb.
#."""
# if sys.version_info[0] >= 3: # pragma: optional cover
# val = bytes(val, "UTF-8")
# loads(val)
# assert 'supernewuser' in owners.__dict__

View file

@ -30,7 +30,7 @@ from .option import OptionDescription, Option, SymLinkOption, \
from .option.baseoption import valid_name from .option.baseoption import valid_name
from .setting import groups, Settings, default_encoding, undefined from .setting import groups, Settings, default_encoding, undefined
from .storage import get_storages, get_storage, set_storage, \ from .storage import get_storages, get_storage, set_storage, \
_impl_getstate_setting, get_default_values_storages get_default_values_storages
from .value import Values, Multi from .value import Values, Multi
from .i18n import _ from .i18n import _
@ -720,42 +720,8 @@ class _CommonConfig(SubConfig):
def impl_del_information(self, key, raises=True): def impl_del_information(self, key, raises=True):
self._impl_values.del_information(key, raises) self._impl_values.del_information(key, raises)
# ----- state
def __getstate__(self): def __getstate__(self):
if self._impl_meta is not None: raise NotImplementedError()
raise ConfigError(_('cannot serialize Config with MetaConfig')) # pragma: optional cover
slots = set()
for subclass in self.__class__.__mro__:
if subclass is not object:
slots.update(subclass.__slots__)
slots -= frozenset(['_impl_context', '_impl_meta', '__weakref__'])
state = {}
for slot in slots:
try:
state[slot] = getattr(self, slot)
except AttributeError: # pragma: optional cover
pass
storage = self._impl_values._p_._storage
if not storage.serializable:
raise ConfigError(_('this storage is not serialisable, could be a '
'none persistent storage')) # pragma: optional cover
state['_storage'] = {'session_id': storage.session_id,
'persistent': storage.persistent}
state['_impl_setting'] = _impl_getstate_setting()
return state
def __setstate__(self, state):
for key, value in state.items():
if key not in ['_storage', '_impl_setting']:
setattr(self, key, value)
set_storage('config', **state['_impl_setting'])
self._impl_context = weakref.ref(self)
self._impl_settings.context = weakref.ref(self)
self._impl_values.context = weakref.ref(self)
storage = get_storage(test=self._impl_test, **state['_storage'])
self._impl_values._impl_setstate(storage)
self._impl_settings._impl_setstate(storage)
self._impl_meta = None
def _gen_fake_values(self, session): def _gen_fake_values(self, session):
fake_config = Config(self._impl_descr, persistent=False, fake_config = Config(self._impl_descr, persistent=False,

View file

@ -256,156 +256,8 @@ class BaseOption(Base):
""" """
__slots__ = tuple() __slots__ = tuple()
# ____________________________________________________________ def __getstate__(self):
# serialize object raise NotImplementedError()
def _impl_convert_dependencies(self, descr, load=False):
"""export of the requires during the serialization process
:type descr: :class:`tiramisu.option.OptionDescription`
:param load: `True` if we are at the init of the option description
:type load: bool
"""
if not load and getattr(self, '_dependencies', None) is None:
self._state_dependencies = None
elif load and self._state_dependencies is None:
del(self._state_dependencies)
else:
if load:
self._dependencies = []
for dependency in self._state_dependencies:
option = descr.impl_get_opt_by_path(dependency)
if option.impl_is_optiondescription():
# test if _group_type is already loaded
group_type = getattr(option, '_group_type', undefined)
if group_type is undefined:
group_type = getattr(groups, option._state_group_type)
if group_type == groups.master:
master_path = dependency + '.' + dependency.split('.')[-1]
option = descr.impl_get_opt_by_path(master_path).impl_get_master_slaves()
self._dependencies.append(option)
self._dependencies = tuple(self._dependencies)
del(self._state_dependencies)
else:
self._state_dependencies = []
for dependency in self._dependencies:
if isinstance(dependency, MasterSlaves):
self._state_dependencies.append('.'.join(descr.impl_get_path_by_opt(dependency._p_.master).split('.')[:-1]))
else:
self._state_dependencies.append(descr.impl_get_path_by_opt(dependency))
def _impl_convert_requires(self, descr, load=False):
"""export of the requires during the serialization process
:type descr: :class:`tiramisu.option.OptionDescription`
:param load: `True` if we are at the init of the option description
:type load: bool
"""
if not load and self.impl_getrequires() == []:
self._state_requires = None
elif load and self._state_requires is None:
del(self._state_requires)
else:
if load:
_requires = self._state_requires
else:
_requires = self.impl_getrequires()
new_value = []
for requires in _requires:
new_requires = []
new_req = []
for require in requires:
for req in require[0]:
if load:
new_req.append([(descr.impl_get_opt_by_path(req[0]), req[1])])
else:
new_req.append([(descr.impl_get_path_by_opt(req[0]), req[1])])
new_req.extend(require[1:])
new_requires.append(tuple(new_req))
new_value.append(tuple(new_requires))
if load:
del(self._state_requires)
if new_value != []:
self._requires = tuple(new_value)
else:
self._state_requires = tuple(new_value)
# serialize
def _impl_getstate(self, descr):
"""the under the hood stuff that need to be done
before the serialization.
:param descr: the parent :class:`tiramisu.option.OptionDescription`
"""
self._stated = True
for func in dir(self):
if func.startswith('_impl_convert_'):
getattr(self, func)(descr)
def __getstate__(self, stated=True):
"""special method to enable the serialization with pickle
Usualy, a `__getstate__` method does'nt need any parameter,
but somme under the hood stuff need to be done before this action
:parameter stated: if stated is `True`, the serialization protocol
can be performed, not ready yet otherwise
:parameter type: bool
"""
try:
self._stated
except AttributeError:
raise SystemError(_('cannot serialize Option, '
'only in OptionDescription'))
if isinstance(self, SymLinkOption):
slots = frozenset(['_name', '_state_opt', '_stated'])
else:
slots = self._impl_getattributes()
slots -= frozenset(['_cache_paths', '_cache_consistencies',
'__weakref__'])
states = {}
for slot in slots:
# remove variable if save variable converted
# in _state_xxxx variable
if '_state' + slot not in slots:
try:
if slot.startswith('_state'):
states[slot] = getattr(self, slot)
# remove _state_xxx variable
self.__delattr__(slot)
else:
states[slot] = getattr(self, slot)
except AttributeError:
pass
if not stated:
del(states['_stated'])
return states
# unserialize
def _impl_setstate(self, descr):
"""the under the hood stuff that need to be done
before the serialization.
:type descr: :class:`tiramisu.option.OptionDescription`
"""
for func in dir(self):
if func.startswith('_impl_convert_'):
getattr(self, func)(descr, load=True)
try:
del(self._stated)
except AttributeError:
pass
def __setstate__(self, state):
"""special method that enables us to serialize (pickle)
Usualy, a `__setstate__` method does'nt need any parameter,
but somme under the hood stuff need to be done before this action
:parameter state: a dict is passed to the loads, it is the attributes
of the options object
:type state: dict
"""
for key, value in state.items():
setattr(self, key, value)
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,
@ -417,9 +269,7 @@ class BaseOption(Base):
propertie or "read_only" property) propertie or "read_only" property)
""" """
if name != '_option' and \ if name != '_option' and \
not isinstance(value, tuple) and \ not isinstance(value, tuple):
not name.startswith('_state') and \
not name == '_sa_instance_state':
is_readonly = False is_readonly = False
# never change _name dans _opt # never change _name dans _opt
if name == '_name': if name == '_name':
@ -932,41 +782,6 @@ class Option(OnlyOption):
equal_name.append(opt.impl_get_display_name()) equal_name.append(opt.impl_get_display_name())
return ValueError(msg.format(display_list(list(equal_name)))) return ValueError(msg.format(display_list(list(equal_name))))
# serialize/unserialize
def _impl_convert_consistencies(self, descr, load=False):
"""during serialization process, many things have to be done.
one of them is the localisation of the options.
The paths are set once for all.
:type descr: :class:`tiramisu.option.OptionDescription`
:param load: `True` if we are at the init of the option description
:type load: bool
"""
if not load and not self._has_consistencies():
self._state_consistencies = None
elif load and self._state_consistencies is None:
del(self._state_consistencies)
else:
if load:
consistencies = self._state_consistencies
else:
consistencies = self._get_consistencies()
new_value = []
for consistency in consistencies:
values = []
for obj in consistency[1]:
if load:
values.append(descr.impl_get_opt_by_path(obj))
else:
values.append(descr.impl_get_path_by_opt(obj))
new_value.append((consistency[0], tuple(values), consistency[2]))
if load:
del(self._state_consistencies)
for new_val in new_value:
self._add_consistency(new_val[0], new_val[1], new_val[2])
else:
self._state_consistencies = new_value
def _second_level_validation(self, value, warnings_only): def _second_level_validation(self, value, warnings_only):
pass pass
@ -1139,7 +954,6 @@ def validate_requires_arg(new_option, multi, requires, name):
class SymLinkOption(OnlyOption): class SymLinkOption(OnlyOption):
# __slots__ = ('_opt', '_state_opt')
def __init__(self, name, opt): def __init__(self, name, opt):
if not isinstance(opt, Option): if not isinstance(opt, Option):
@ -1155,21 +969,11 @@ class SymLinkOption(OnlyOption):
def __getattr__(self, name, context=undefined): def __getattr__(self, name, context=undefined):
if name in ('_opt', '_readonly', 'impl_getpath', '_name', if name in ('_opt', '_readonly', 'impl_getpath', '_name',
'_state_opt', '_impl_setopt'): '_impl_setopt'):
return object.__getattr__(self, name) return object.__getattr__(self, name)
else: else:
return getattr(self._impl_getopt(), name) return getattr(self._impl_getopt(), name)
def _impl_getstate(self, descr):
self._stated = True
self._state_opt = descr.impl_get_path_by_opt(self._impl_getopt())
def _impl_setstate(self, descr):
self._impl_setopt(descr.impl_get_opt_by_path(self._state_opt))
del(self._state_opt)
del(self._stated)
self._set_readonly(True)
def impl_get_information(self, key, default=undefined): def impl_get_information(self, key, default=undefined):
return self._impl_getopt().impl_get_information(key, default) return self._impl_getopt().impl_get_information(key, default)
@ -1208,7 +1012,7 @@ class DynSymLinkOption(object):
self._opt = opt self._opt = opt
def __getattr__(self, name, context=undefined): def __getattr__(self, name, context=undefined):
if name in ('_opt', '_readonly', 'impl_getpath', '_name', '_state_opt'): if name in ('_opt', '_readonly', 'impl_getpath', '_name'):
return object.__getattr__(self, name) return object.__getattr__(self, name)
else: else:
return getattr(self._impl_getopt(), name) return getattr(self._impl_getopt(), name)

View file

@ -260,58 +260,8 @@ class OptionDescription(BaseOption, StorageOptionDescription):
raise ValueError(_('group_type: {0}' raise ValueError(_('group_type: {0}'
' not allowed').format(group_type)) ' not allowed').format(group_type))
def _impl_getstate(self, descr=None):
"""enables us to export into a dict
:param descr: parent :class:`tiramisu.option.OptionDescription`
"""
if descr is None:
self.impl_build_cache_option()
descr = self
super(OptionDescription, self)._impl_getstate(descr)
self._state_group_type = str(self._group_type)
for option in self._impl_getchildren():
option._impl_getstate(descr)
def __getstate__(self): def __getstate__(self):
"""special method to enable the serialization with pickle raise NotImplementedError()
"""
stated = True
try:
# the `_state` attribute is a flag that which tells us if
# the serialization can be performed
self._stated
except AttributeError:
# if cannot delete, _impl_getstate never launch
# launch it recursivement
# _stated prevent __getstate__ launch more than one time
# _stated is delete, if re-serialize, re-lauch _impl_getstate
self._impl_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_consistencies = None
self.impl_build_cache_option()
descr = self
self._group_type = getattr(groups, self._state_group_type)
if isinstance(self._group_type, groups.MasterGroupType):
MasterSlaves(self.impl_getname(), self.impl_getchildren(),
validate=False)
del(self._state_group_type)
super(OptionDescription, self)._impl_setstate(descr)
for option in self._impl_getchildren(dyn=False):
option._impl_setstate(descr)
def __setstate__(self, state):
super(OptionDescription, self).__setstate__(state)
try:
self._stated
except AttributeError:
self._impl_setstate()
def _impl_get_suffixes(self, context): def _impl_get_suffixes(self, context):
callback, callback_params = self.impl_get_callback() callback, callback_params = self.impl_get_callback()

View file

@ -770,18 +770,3 @@ class Settings(object):
def get_modified_permissives(self): def get_modified_permissives(self):
return self._pp_.get_modified_permissives() return self._pp_.get_modified_permissives()
def __getstate__(self):
return {'_p_': self._p_, '_pp_': self._pp_, '_owner': str(self._owner)}
def _impl_setstate(self, storage):
self._p_._storage = storage
def __setstate__(self, states):
self._p_ = states['_p_']
self._pp_ = states['_pp_']
try:
self._owner = getattr(owners, states['_owner'])
except AttributeError:
owners.addowner(states['_owner'])
self._owner = getattr(owners, states['_owner'])

View file

@ -66,6 +66,8 @@ class StorageType(object):
try: try:
mod = __import__(modulepath) mod = __import__(modulepath)
except ImportError: # pragma: no cover except ImportError: # pragma: no cover
import traceback
traceback.print_exc()
raise SystemError(_('cannot import the storage {0}').format( raise SystemError(_('cannot import the storage {0}').format(
self.default_storage)) self.default_storage))
for token in modulepath.split(".")[1:]: for token in modulepath.split(".")[1:]:
@ -81,33 +83,6 @@ default_validation = StorageType()
default_validation.set(DEFAULT_STORAGE) default_validation.set(DEFAULT_STORAGE)
def set_storage(type_, name): # pragma: optional cover
"""Change storage's configuration
:params name: is the storage name. If storage is already set, cannot
reset storage name
Other attributes are differents according to the selected storage's name
"""
storage_type.set(name)
setting = storage_type.get().setting
def _impl_getstate_setting():
setting = storage_type.get().setting
state = {'name': storage_type.storage_type}
for var in dir(setting):
if not var.startswith('_'):
state[var] = getattr(setting, var)
return state
def get_storage(session_id, persistent, test): # pragma: optional cover
"""all used when __setstate__ a Config
"""
return storage_type.get().Storage(session_id, persistent, test)
def get_storages(context, session_id, persistent): def get_storages(context, session_id, persistent):
def gen_id(config): def gen_id(config):
return 'c' + str(id(config)) + str(int(time())) + str(randint(0, 500)) return 'c' + str(id(config)) + str(int(time())) + str(randint(0, 500))

View file

@ -57,15 +57,6 @@ class StorageBase(object):
#other #other
'_has_dependency', '_has_dependency',
'_dependencies', '_dependencies',
'_state_master_slaves',
'_state_val_call',
'_state_requires',
'_stated',
'_state_consistencies',
'_state_informations',
'_state_extra',
'_state_readonly',
'_state_dependencies',
'__weakref__' '__weakref__'
) )
@ -219,44 +210,6 @@ class StorageBase(object):
ret_val = val ret_val = val
return ret_val return ret_val
def _impl_convert_callback(self, descr, load=False):
if self.__class__.__name__ in ['OptionDescription', 'SymLinkOption']:
return
if not load and getattr(self, '_val_call', None) is None:
self._state_val_call = None
elif load and self._state_val_call is None:
del(self._state_val_call)
else:
if load:
val_call = self._state_val_call
else:
val_call = self._val_call
new_val_call = []
for vals in val_call:
if vals is None or len(vals) == 1:
new_val_call.append(vals)
else:
prms = {}
val, params = vals
for key, values in params.items():
vls = []
for value in values:
if isinstance(value, tuple) and value[0] is not None:
if load:
value = (descr.impl_get_opt_by_path(value[0]),
value[1])
else:
value = (descr.impl_get_path_by_opt(value[0]),
value[1])
vls.append(value)
prms[key] = tuple(vls)
new_val_call.append((val, prms))
if load:
del(self._state_val_call)
self._val_call = new_val_call
else:
self._state_val_call = new_val_call
def _get_id(self): def _get_id(self):
return id(self) return id(self)
@ -287,58 +240,12 @@ class StorageBase(object):
def _impl_setsubdyn(self, subdyn): def _impl_setsubdyn(self, subdyn):
self._subdyn = subdyn self._subdyn = subdyn
def _impl_setopt(self, opt):
self._opt = opt
def _is_string(self, infos): def _is_string(self, infos):
if sys.version_info[0] >= 3: # pragma: no cover if sys.version_info[0] >= 3: # pragma: no cover
return isinstance(infos, str) return isinstance(infos, str)
else: else:
return isinstance(infos, str) or isinstance(infos, unicode) return isinstance(infos, str) or isinstance(infos, unicode)
def _impl_convert_zinformations(self, descr, load=False):
if not load:
infos = self._informations
if isinstance(infos, tuple):
self._state_informations = {}
for idx, key in enumerate(infos[0]):
self._state_informations[key] = infos[1][idx]
elif self._is_string(infos):
self._state_informations = {'doc': infos}
else:
self._state_informations = infos
self._state_readonly = self.impl_is_readonly()
else:
_setattr = object.__setattr__
_setattr(self, '_informations', self._state_informations)
del(self._state_informations)
if self._state_readonly:
self._set_readonly(True)
del(self._state_readonly)
def _impl_convert_extra(self, descr, load=False):
if not load:
extra = getattr(self, '_extra', None)
if isinstance(extra, tuple):
self._state_extra = {}
for idx, key in enumerate(extra[0]):
self._state_extra[key] = extra[1][idx]
elif isinstance(extra, dict):
self._state_extra = extra
else:
extra = getattr(self, '_state_extra', None)
if extra is not None:
_setattr = object.__setattr__
_setattr(self, '_extra', extra)
del(self._state_extra)
def _impl_getattributes(self):
slots = set()
for subclass in self.__class__.__mro__:
if subclass is not object:
slots.update(subclass.__slots__)
return slots
def impl_is_readonly(self): def impl_is_readonly(self):
return not isinstance(getattr(self, '_informations', dict()), dict) return not isinstance(getattr(self, '_informations', dict()), dict)
@ -400,7 +307,7 @@ class StorageBase(object):
class StorageOptionDescription(StorageBase): class StorageOptionDescription(StorageBase):
__slots__ = ('_children', '_cache_paths', '_cache_consistencies', __slots__ = ('_children', '_cache_paths', '_cache_consistencies',
'_group_type', '_state_group_type', '_cache_force_store_values') '_group_type', '_cache_force_store_values')
def _add_children(self, child_names, children): def _add_children(self, child_names, children):
_setattr = object.__setattr__ _setattr = object.__setattr__

View file

@ -16,10 +16,9 @@
# ____________________________________________________________ # ____________________________________________________________
from ...i18n import _ from ...i18n import _
from ...error import ConfigError, ConflictError from ...error import ConfigError, ConflictError
from ..util import SerializeObject
class Setting(SerializeObject): class Setting(object):
"""Dictionary storage has no particular setting. """Dictionary storage has no particular setting.
""" """
pass pass

View file

@ -15,13 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# ____________________________________________________________ # ____________________________________________________________
from tiramisu.i18n import _ from tiramisu.i18n import _
from ..util import SerializeObject
from .util import SqlAlchemyBase from .util import SqlAlchemyBase
import util import util
from sqlalchemy import Column, Integer, String from sqlalchemy import Column, Integer, String
class Setting(SerializeObject): class Setting(object):
""":param extension: database file extension (by default: db) """:param extension: database file extension (by default: db)
:param dir_database: root database directory (by default: /tmp) :param dir_database: root database directory (by default: /tmp)
""" """

View file

@ -20,10 +20,9 @@ from os import unlink
from os.path import basename, splitext, join, isfile from os.path import basename, splitext, join, isfile
import sqlite3 import sqlite3
from glob import glob from glob import glob
from ..util import SerializeObject
class Setting(SerializeObject): class Setting(object):
""":param extension: database file extension (by default: db) """:param extension: database file extension (by default: db)
:param dir_database: root database directory (by default: /tmp) :param dir_database: root database directory (by default: /tmp)
""" """

View file

@ -18,15 +18,6 @@
from ..setting import owners from ..setting import owners
class SerializeObject(object):
def __getstate__(self): # pragma: no cover
ret = {}
for key in dir(self):
if not key.startswith('__'):
ret[key] = getattr(self, key)
return ret
class Cache(object): class Cache(object):
__slots__ = ('_cache', '_storage') __slots__ = ('_cache', '_storage')
key_is_path = False key_is_path = False
@ -35,68 +26,6 @@ class Cache(object):
self._cache = {} self._cache = {}
self._storage = storage self._storage = storage
def __getstate__(self):
slots = set()
for subclass in self.__class__.__mro__:
if subclass is not object:
slots.update(subclass.__slots__)
slots -= frozenset(['__weakref__', '_storage'])
states = {}
for slot in slots:
try:
value = getattr(self, slot)
#value has owners object, need 'str()' it
if slot == '_values':
_value = []
_value.append(value[0])
_value.append(value[1])
str_owner = []
_value.append(value[2])
for owner in value[3]:
if isinstance(owner, list): # pragma: no cover
str_owners = []
for subowner in owner:
str_owners.append(str(subowner))
str_owner.append(str_owners)
else:
str_owner.append(str(owner))
_value.append(str_owner)
states[slot] = _value
else:
states[slot] = value
except AttributeError: # pragma: no cover
pass
return states
def __setstate__(self, states):
def convert_owner(owner):
try:
owner = getattr(owners, owner)
except AttributeError: # pragma: no cover
owners.addowner(owner)
owner = getattr(owners, owner)
return owner
for key, value in states.items():
#value has owners object, need to reconstruct it
if key == '_values':
_value = []
_value.append(value[0])
_value.append(value[1])
_value.append(value[2])
obj_owner = []
for owner in value[3]:
if isinstance(owner, list): # pragma: no cover
obj_owners = []
for subowner in owner:
obj_owners.append(convert_owner(subowner))
obj_owner.append(tuple(obj_owners))
else:
obj_owner.append(convert_owner(owner))
_value.append(tuple(obj_owner))
value = tuple(_value)
setattr(self, key, value)
def setcache(self, path, val, time, index): def setcache(self, path, val, time, index):
"""add val in cache for a specified path """add val in cache for a specified path
if slave, add index if slave, add index

View file

@ -690,15 +690,6 @@ class Values(object):
if isinstance(err, Exception) and not isinstance(err, PropertiesOptionError): # pragma: no cover if isinstance(err, Exception) and not isinstance(err, PropertiesOptionError): # pragma: no cover
raise err raise err
def __getstate__(self):
return {'_p_': self._p_}
def _impl_setstate(self, storage):
self._p_._storage = storage
def __setstate__(self, states):
self._p_ = states['_p_']
# ____________________________________________________________ # ____________________________________________________________
# multi types # multi types