update sqlalchemy storage for values et settings
authorEmmanuel Garette <egarette@cadoles.com>
Tue, 29 Mar 2016 07:31:00 +0000 (09:31 +0200)
committerEmmanuel Garette <egarette@cadoles.com>
Tue, 29 Mar 2016 07:31:00 +0000 (09:31 +0200)
18 files changed:
test/test_duplicate_config.py
test/test_dyn_optiondescription.py
test/test_mandatory.py
test/test_state.py
test/test_storage.py
tiramisu/config.py
tiramisu/option/masterslave.py
tiramisu/option/optiondescription.py
tiramisu/storage/__init__.py
tiramisu/storage/dictionary/setting.py
tiramisu/storage/dictionary/storage.py
tiramisu/storage/dictionary/value.py
tiramisu/storage/sqlalchemy/__init__.py
tiramisu/storage/sqlalchemy/setting.py
tiramisu/storage/sqlalchemy/storage.py
tiramisu/storage/sqlalchemy/util.py
tiramisu/storage/sqlalchemy/value.py
tiramisu/value.py

index d4b65d9..c6e9a6d 100644 (file)
@@ -6,7 +6,7 @@ from tiramisu.setting import groups
 from tiramisu.config import Config
 from tiramisu.option import ChoiceOption, BoolOption, IntOption, \
     StrOption, OptionDescription
 from tiramisu.config import Config
 from tiramisu.option import ChoiceOption, BoolOption, IntOption, \
     StrOption, OptionDescription
-from test.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
 
 
index 1b5e467..ad4aed0 100644 (file)
@@ -1300,7 +1300,7 @@ def test_state_config():
 
     try:
         delete_session('config', '29090938')
 
     try:
         delete_session('config', '29090938')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
index 4590d42..0790a69 100644 (file)
@@ -7,6 +7,7 @@ from tiramisu.config import Config
 from tiramisu.option import IntOption, StrOption, UnicodeOption, OptionDescription, SymLinkOption
 from tiramisu.error import PropertiesOptionError, ConfigError
 from tiramisu.setting import groups
 from tiramisu.option import IntOption, StrOption, UnicodeOption, OptionDescription, SymLinkOption
 from tiramisu.error import PropertiesOptionError, ConfigError
 from tiramisu.setting import groups
+from tiramisu.storage import delete_session
 
 
 def make_description():
 
 
 def make_description():
@@ -352,6 +353,11 @@ def test_mandatory_warnings_rw():
     config.str = 'a'
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
     config.str = 'a'
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_warnings_disabled():
 
 
 def test_mandatory_warnings_disabled():
@@ -365,6 +371,11 @@ def test_mandatory_warnings_disabled():
     setting[descr.str].append('disabled')
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
     setting[descr.str].append('disabled')
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str1', 'unicode2', 'str3']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_warnings_hidden():
 
 
 def test_mandatory_warnings_hidden():
@@ -379,6 +390,11 @@ def test_mandatory_warnings_hidden():
     setting[descr.str].append('hidden')
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str', 'str1', 'unicode2', 'str3']
     setting[descr.str].append('hidden')
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
     assert list(config.cfgimpl_get_values().mandatory_warnings(force_permissive=True)) == ['str', 'str1', 'unicode2', 'str3']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_warnings_frozen():
 
 
 def test_mandatory_warnings_frozen():
@@ -392,6 +408,11 @@ def test_mandatory_warnings_frozen():
     setting[descr.str].append('frozen')
     config.read_only()
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
     setting[descr.str].append('frozen')
     config.read_only()
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'unicode2', 'str3']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_master():
 
 
 def test_mandatory_master():
@@ -406,6 +427,11 @@ def test_mandatory_master():
     config.read_only()
     raises(PropertiesOptionError, 'config.ip_admin_eth0.ip_admin_eth0')
     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
     config.read_only()
     raises(PropertiesOptionError, 'config.ip_admin_eth0.ip_admin_eth0')
     raises(PropertiesOptionError, 'config.ip_admin_eth0.netmask_admin_eth0')
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_master_empty():
 
 
 def test_mandatory_master_empty():
@@ -445,6 +471,11 @@ def test_mandatory_master_empty():
     config.read_only()
     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
     config.read_only()
     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
     assert config.ip_admin_eth0.netmask_admin_eth0 == [None]
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_slave():
 
 
 def test_mandatory_slave():
@@ -476,6 +507,11 @@ def test_mandatory_slave():
     config.read_only()
     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
     assert config.ip_admin_eth0.netmask_admin_eth0 == ['ip']
     config.read_only()
     assert config.ip_admin_eth0.ip_admin_eth0 == ['ip']
     assert config.ip_admin_eth0.netmask_admin_eth0 == ['ip']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_warnings_symlink():
 
 
 def test_mandatory_warnings_symlink():
@@ -489,6 +525,11 @@ def test_mandatory_warnings_symlink():
     setting[descr.str].append('frozen')
     config.read_only()
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'str3']
     setting[descr.str].append('frozen')
     config.read_only()
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str', 'str1', 'str3']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_warnings_validate():
 
 
 def test_mandatory_warnings_validate():
@@ -500,6 +541,11 @@ def test_mandatory_warnings_validate():
     config.str = 'test'
     raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str1', 'str3']
     config.str = 'test'
     raises(ValueError, "list(config.cfgimpl_get_values().mandatory_warnings())")
     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str1', 'str3']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_warnings_validate_empty():
 
 
 def test_mandatory_warnings_validate_empty():
@@ -509,6 +555,11 @@ def test_mandatory_warnings_validate_empty():
     config.read_only()
     raises(ConfigError, "list(config.cfgimpl_get_values().mandatory_warnings())")
     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1']
     config.read_only()
     raises(ConfigError, "list(config.cfgimpl_get_values().mandatory_warnings())")
     assert list(config.cfgimpl_get_values().mandatory_warnings(validate=False)) == ['str', 'str1', 'str3', 'unicode1']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_warnings_requires():
 
 
 def test_mandatory_warnings_requires():
@@ -523,6 +574,11 @@ def test_mandatory_warnings_requires():
     config.read_write()
     config.str = 'yes'
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
     config.read_write()
     config.str = 'yes'
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['str1', 'unicode2', 'str3']
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
 
 
 def test_mandatory_od_disabled():
 
 
 def test_mandatory_od_disabled():
@@ -533,3 +589,8 @@ def test_mandatory_od_disabled():
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
     config.cfgimpl_get_settings()[descr].append('disabled')
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == []
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == ['tiram.str1', 'tiram.unicode2', 'tiram.str3']
     config.cfgimpl_get_settings()[descr].append('disabled')
     assert list(config.cfgimpl_get_values().mandatory_warnings()) == []
+    try:
+        delete_session('config', config.impl_getsessionid())
+    except ValueError:
+        pass
+    del(config)
index c8ca16a..f4be865 100644 (file)
@@ -301,7 +301,7 @@ def test_state_config():
     _diff_conf(cfg, q)
     try:
         delete_session('config', '29090931')
     _diff_conf(cfg, q)
     try:
         delete_session('config', '29090931')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
@@ -330,7 +330,7 @@ def test_state_config2():
     _diff_conf(cfg, q)
     try:
         delete_session('config', '29090939')
     _diff_conf(cfg, q)
     try:
         delete_session('config', '29090939')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
@@ -370,7 +370,7 @@ def test_state_properties():
     _diff_conf(cfg, q)
     try:
         delete_session('config', '29090932')
     _diff_conf(cfg, q)
     try:
         delete_session('config', '29090932')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
@@ -391,7 +391,7 @@ def test_state_values():
     assert q.val1 is False
     try:
         delete_session('config', '29090933')
     assert q.val1 is False
     try:
         delete_session('config', '29090933')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
@@ -414,7 +414,7 @@ def test_state_values_owner():
     assert q.getowner(nval1) == owners.newowner
     try:
         delete_session('config', '29090934')
     assert q.getowner(nval1) == owners.newowner
     try:
         delete_session('config', '29090934')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
@@ -433,7 +433,7 @@ def test_state_metaconfig():
         delete_session('config', '29090935')
         delete_session('config', '29090936')
         delete_session('config', '29090937')
         delete_session('config', '29090935')
         delete_session('config', '29090936')
         delete_session('config', '29090937')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
@@ -454,7 +454,7 @@ def test_state_groupconfig():
         delete_session('config', '29090935')
         delete_session('config', '29090936')
         delete_session('config', '29090937')
         delete_session('config', '29090935')
         delete_session('config', '29090936')
         delete_session('config', '29090937')
-    except ConfigError:
+    except ValueError:
         pass
 
 
         pass
 
 
index 8906c9e..6d01e3a 100644 (file)
@@ -58,7 +58,7 @@ def test_delete_session_persistent():
         pass
     else:
         assert 'test_persistent' in list_sessions('config')
         pass
     else:
         assert 'test_persistent' in list_sessions('config')
-        delete_session('test_persistent')
+        delete_session('config', 'test_persistent')
         assert 'test_persistent' not in list_sessions('config')
 
 
         assert 'test_persistent' not in list_sessions('config')
 
 
@@ -67,7 +67,6 @@ def test_create_persistent_retrieve():
     o = OptionDescription('od', '', [b])
     try:
         c = Config(o, session_id='test_persistent', persistent=True)
     o = OptionDescription('od', '', [b])
     try:
         c = Config(o, session_id='test_persistent', persistent=True)
-        c.cfgimpl_get_settings().remove('cache')
     except ValueError:
         # storage is not persistent
         pass
     except ValueError:
         # storage is not persistent
         pass
@@ -77,14 +76,14 @@ def test_create_persistent_retrieve():
         assert c.b is True
         del(c)
         c = Config(o, session_id='test_persistent', persistent=True)
         assert c.b is True
         del(c)
         c = Config(o, session_id='test_persistent', persistent=True)
-        c.cfgimpl_get_settings().remove('cache')
         assert c.b is True
         assert 'test_persistent' in list_sessions('config')
         assert c.b is True
         assert 'test_persistent' in list_sessions('config')
-        delete_session('test_persistent')
+        delete_session('config', c.impl_getsessionid())
+        del(c)
         c = Config(o, session_id='test_persistent', persistent=True)
         c = Config(o, session_id='test_persistent', persistent=True)
-        c.cfgimpl_get_settings().remove('cache')
         assert c.b is None
         assert c.b is None
-        delete_session('test_persistent')
+        delete_session('config', c.impl_getsessionid())
+        del(c)
 
 
 def test_two_persistent():
 
 
 def test_two_persistent():
@@ -92,11 +91,11 @@ def test_two_persistent():
     o = OptionDescription('od', '', [b])
     try:
         c = Config(o, session_id='test_persistent', persistent=True)
     o = OptionDescription('od', '', [b])
     try:
         c = Config(o, session_id='test_persistent', persistent=True)
-        c.cfgimpl_get_settings().remove('cache')
     except ValueError:
         # storage is not persistent
         pass
     else:
     except ValueError:
         # storage is not persistent
         pass
     else:
+        c.cfgimpl_get_settings().remove('cache')
         c2 = Config(o, session_id='test_persistent', persistent=True)
         c2.cfgimpl_get_settings().remove('cache')
         assert c.b is None
         c2 = Config(o, session_id='test_persistent', persistent=True)
         c2.cfgimpl_get_settings().remove('cache')
         assert c.b is None
@@ -104,10 +103,40 @@ def test_two_persistent():
         c.b = False
         assert c.b is False
         assert c2.b is False
         c.b = False
         assert c.b is False
         assert c2.b is False
-        c.b = True
+        c2.b = True
         assert c.b is True
         assert c2.b is True
         assert c.b is True
         assert c2.b is True
-        delete_session('test_persistent')
+        delete_session('config', 'test_persistent')
+
+
+def test_create_persistent_retrieve_owner():
+    b = BoolOption('b', '')
+    o = OptionDescription('od', '', [b])
+    try:
+        c = Config(o, session_id='test_persistent', persistent=True)
+    except ValueError:
+        # storage is not persistent
+        pass
+    else:
+        assert c.getowner(b) == owners.default
+        c.b = True
+        assert c.b is True
+        assert c.getowner(b) == owners.user
+        owners.addowner('persistentowner')
+        c.cfgimpl_get_values().setowner(b, owners.persistentowner)
+        assert c.getowner(b) == owners.persistentowner
+        del(c)
+        #
+        c = Config(o, session_id='test_persistent', persistent=True)
+        c.cfgimpl_get_values().setowner(b, owners.persistentowner)
+        delete_session('config', c.impl_getsessionid())
+        del(c)
+        #
+        c = Config(o, session_id='test_persistent', persistent=True)
+        assert c.b is None
+        assert c.getowner(b) == owners.default
+        delete_session('config', c.impl_getsessionid())
+        del(c)
 
 
 def test_two_persistent_owner():
 
 
 def test_two_persistent_owner():
@@ -122,16 +151,40 @@ def test_two_persistent_owner():
     else:
         c2 = Config(o, session_id='test_persistent', persistent=True)
         c2.cfgimpl_get_settings().remove('cache')
     else:
         c2 = Config(o, session_id='test_persistent', persistent=True)
         c2.cfgimpl_get_settings().remove('cache')
-        owners.addowner('persistent')
         assert c.getowner(b) == owners.default
         assert c2.getowner(b) == owners.default
         c.b = False
         assert c.getowner(b) == owners.user
         assert c2.getowner(b) == owners.user
         assert c.getowner(b) == owners.default
         assert c2.getowner(b) == owners.default
         c.b = False
         assert c.getowner(b) == owners.user
         assert c2.getowner(b) == owners.user
+        owners.addowner('persistent')
         c.cfgimpl_get_values().setowner(b, owners.persistent)
         assert c.getowner(b) == owners.persistent
         assert c2.getowner(b) == owners.persistent
         c.cfgimpl_get_values().setowner(b, owners.persistent)
         assert c.getowner(b) == owners.persistent
         assert c2.getowner(b) == owners.persistent
-        delete_session('test_persistent')
+        delete_session('config', 'test_persistent')
+
+
+def test_create_persistent_retrieve_information():
+    b = BoolOption('b', '')
+    o = OptionDescription('od', '', [b])
+    try:
+        c = Config(o, session_id='test_persistent', persistent=True)
+    except ValueError:
+        # storage is not persistent
+        pass
+    else:
+        c.impl_set_information('info', 'string')
+        assert c.impl_get_information('info') == 'string'
+        del(c)
+        #
+        c = Config(o, session_id='test_persistent', persistent=True)
+        assert c.impl_get_information('info') == 'string'
+        delete_session('config', c.impl_getsessionid())
+        del(c)
+        #
+        c = Config(o, session_id='test_persistent', persistent=True)
+        assert c.impl_get_information('info', None) == None
+        delete_session('config', c.impl_getsessionid())
+        del(c)
 
 
 def test_two_persistent_information():
 
 
 def test_two_persistent_information():
@@ -150,4 +203,4 @@ def test_two_persistent_information():
         c2.cfgimpl_get_settings().remove('cache')
         c2.cfgimpl_get_settings().remove('cache')
         assert c2.impl_get_information('info') == 'string'
         c2.cfgimpl_get_settings().remove('cache')
         c2.cfgimpl_get_settings().remove('cache')
         assert c2.impl_get_information('info') == 'string'
-        delete_session('test_persistent')
+        delete_session('config', 'test_persistent')
index 096ca47..b3f9f80 100644 (file)
@@ -642,11 +642,11 @@ class _CommonConfig(SubConfig):
         self._impl_settings._impl_setstate(storage)
         self._impl_meta = None
 
         self._impl_settings._impl_setstate(storage)
         self._impl_meta = None
 
-    def _gen_fake_values(self):
+    def _gen_fake_values(self, session):
         fake_config = Config(self._impl_descr, persistent=False,
                              force_values=get_storages_validation(),
                              force_settings=self.cfgimpl_get_settings())
         fake_config = Config(self._impl_descr, persistent=False,
                              force_values=get_storages_validation(),
                              force_settings=self.cfgimpl_get_settings())
-        fake_config.cfgimpl_get_values()._p_._values = self.cfgimpl_get_values()._p_._values
+        fake_config.cfgimpl_get_values()._p_.importation(self.cfgimpl_get_values()._p_.exportation(session, fake=True))
         return fake_config
 
     def duplicate(self):
         return fake_config
 
     def duplicate(self):
@@ -707,6 +707,9 @@ class Config(_CommonConfig):
     def impl_getname(self):
         return self._impl_name
 
     def impl_getname(self):
         return self._impl_name
 
+    def impl_getsessionid(self):
+        return self._impl_values._p_._storage.session_id
+
 
 class GroupConfig(_CommonConfig):
     __slots__ = ('__weakref__', '_impl_children', '_impl_name')
 
 class GroupConfig(_CommonConfig):
     __slots__ = ('__weakref__', '_impl_children', '_impl_name')
index 69e391f..d1ad634 100644 (file)
@@ -118,26 +118,27 @@ class MasterSlaves(object):
         pass
 
     def getitem(self, values, opt, path, validate, force_permissive,
         pass
 
     def getitem(self, values, opt, path, validate, force_permissive,
-                trusted_cached_properties, validate_properties, slave_path=undefined,
-                slave_value=undefined, setting_properties=undefined,
-                self_properties=undefined, index=None,
+                trusted_cached_properties, validate_properties, session,
+                slave_path=undefined, slave_value=undefined,
+                setting_properties=undefined, self_properties=undefined, index=None,
                 returns_raise=False):
         if self.is_master(opt):
             return self._getmaster(values, opt, path, validate,
                                    force_permissive,
                                    validate_properties, slave_path,
                                    slave_value, self_properties, index,
                 returns_raise=False):
         if self.is_master(opt):
             return self._getmaster(values, opt, path, validate,
                                    force_permissive,
                                    validate_properties, slave_path,
                                    slave_value, self_properties, index,
-                                   returns_raise, setting_properties)
+                                   returns_raise, setting_properties, session)
         else:
             return self._getslave(values, opt, path, validate,
                                   force_permissive, trusted_cached_properties,
                                   validate_properties, setting_properties,
         else:
             return self._getslave(values, opt, path, validate,
                                   force_permissive, trusted_cached_properties,
                                   validate_properties, setting_properties,
-                                  self_properties, index, returns_raise)
+                                  self_properties, index, returns_raise,
+                                  session)
 
     def _getmaster(self, values, opt, path, validate, force_permissive,
                    validate_properties, c_slave_path,
                    c_slave_value, self_properties, index, returns_raise,
 
     def _getmaster(self, values, opt, path, validate, force_permissive,
                    validate_properties, c_slave_path,
                    c_slave_value, self_properties, index, returns_raise,
-                   setting_properties):
+                   setting_properties, session):
         value = values._get_cached_value(opt, path=path, validate=validate,
                                          force_permissive=force_permissive,
                                          validate_properties=validate_properties,
         value = values._get_cached_value(opt, path=path, validate=validate,
                                          force_permissive=force_permissive,
                                          validate_properties=validate_properties,
@@ -151,13 +152,13 @@ class MasterSlaves(object):
             masterlen = len(value)
             for slave in self.getslaves(opt):
                 slave_path = slave.impl_getpath(values._getcontext())
             masterlen = len(value)
             for slave in self.getslaves(opt):
                 slave_path = slave.impl_getpath(values._getcontext())
-                slavelen = values._p_.get_max_length(slave_path)
+                slavelen = values._p_.get_max_length(slave_path, session)
                 self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
         return value
 
     def _getslave(self, values, opt, path, validate, force_permissive,
                   trusted_cached_properties, validate_properties, setting_properties,
                 self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
         return value
 
     def _getslave(self, values, opt, path, validate, force_permissive,
                   trusted_cached_properties, validate_properties, setting_properties,
-                  self_properties, index, returns_raise):
+                  self_properties, index, returns_raise, session):
         """
         if master has length 0:
             return []
         """
         if master has length 0:
             return []
@@ -182,12 +183,12 @@ class MasterSlaves(object):
         master = self.getmaster(opt)
         context = values._getcontext()
         masterp = master.impl_getpath(context)
         master = self.getmaster(opt)
         context = values._getcontext()
         masterp = master.impl_getpath(context)
-        masterlen = self.get_length(values, opt, validate, undefined,
+        masterlen = self.get_length(values, opt, session, validate, undefined,
                                     undefined, force_permissive,
                                     master=master, returns_raise=returns_raise)
         if isinstance(masterlen, Exception):
             return masterlen
                                     undefined, force_permissive,
                                     master=master, returns_raise=returns_raise)
         if isinstance(masterlen, Exception):
             return masterlen
-        master_is_meta = values._is_meta(master, masterp)
+        master_is_meta = values._is_meta(master, masterp, session)
         multi = values._get_multi(opt, path)
         #if masterlen is [], test properties (has no value, don't get any value)
         if masterlen == 0:
         multi = values._get_multi(opt, path)
         #if masterlen is [], test properties (has no value, don't get any value)
         if masterlen == 0:
@@ -240,24 +241,24 @@ class MasterSlaves(object):
                     raise err
         return multi
 
                     raise err
         return multi
 
-    def validate(self, values, opt, value, path, returns_raise):
+    def validate(self, values, opt, value, path, returns_raise, session):
         if self.is_master(opt):
             masterlen = len(value)
             #for regen slave path
             base_path = '.'.join(path.split('.')[:-1]) + '.'
             for slave in self.getslaves(opt):
                 slave_path = base_path + slave.impl_getname()
         if self.is_master(opt):
             masterlen = len(value)
             #for regen slave path
             base_path = '.'.join(path.split('.')[:-1]) + '.'
             for slave in self.getslaves(opt):
                 slave_path = base_path + slave.impl_getname()
-                slavelen = values._p_.get_max_length(slave_path)
+                slavelen = values._p_.get_max_length(slave_path, session)
                 self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
         else:
                 self.validate_slave_length(masterlen, slavelen, slave.impl_getname(), opt)
         else:
-            val_len = self.get_length(values, opt, slave_path=path, returns_raise=returns_raise)
+            val_len = self.get_length(values, opt, session, slave_path=path, returns_raise=returns_raise)
             if isinstance(val_len, Exception):
                 return val_len
             self.validate_slave_length(val_len,
                                        len(value),
                                        opt.impl_getname(), opt, setitem=True)
 
             if isinstance(val_len, Exception):
                 return val_len
             self.validate_slave_length(val_len,
                                        len(value),
                                        opt.impl_getname(), opt, setitem=True)
 
-    def get_length(self, values, opt, validate=True, slave_path=undefined,
+    def get_length(self, values, opt, session, validate=True, slave_path=undefined,
                    slave_value=undefined, force_permissive=False, master=None,
                    masterp=None, returns_raise=False):
         """get master len with slave option"""
                    slave_value=undefined, force_permissive=False, master=None,
                    masterp=None, returns_raise=False):
         """get master len with slave option"""
@@ -268,8 +269,8 @@ class MasterSlaves(object):
         if slave_value is undefined:
             slave_path = undefined
         value = self.getitem(values, master, masterp, validate,
         if slave_value is undefined:
             slave_path = undefined
         value = self.getitem(values, master, masterp, validate,
-                             force_permissive, None, True, slave_path,
-                             slave_value, returns_raise=returns_raise)
+                             force_permissive, None, True, session, slave_path=slave_path,
+                             slave_value=slave_value, returns_raise=returns_raise)
         if isinstance(value, Exception):
             return value
         return len(value)
         if isinstance(value, Exception):
             return value
         return len(value)
index 2c354f4..1dda5b5 100644 (file)
@@ -175,6 +175,7 @@ class OptionDescription(BaseOption, StorageOptionDescription):
                                                            'must not be a multi for {1}').format(
                                                                require_opt.impl_getname(), option.impl_getname()))
         if init:
                                                            'must not be a multi for {1}').format(
                                                                require_opt.impl_getname(), option.impl_getname()))
         if init:
+            session = config._impl_values._p_.getsession()
             if len(cache_option) != len(set(cache_option)):
                 for idx in xrange(1, len(cache_option) + 1):
                     opt = cache_option.pop(0)
             if len(cache_option) != len(set(cache_option)):
                 for idx in xrange(1, len(cache_option) + 1):
                     opt = cache_option.pop(0)
@@ -203,7 +204,8 @@ class OptionDescription(BaseOption, StorageOptionDescription):
                     raise ConfigError(_('a dynoption ({0}) cannot have '
                                         'force_store_value property').format(subpath))
                 config._impl_values._p_.setvalue(subpath, value,
                     raise ConfigError(_('a dynoption ({0}) cannot have '
                                         'force_store_value property').format(subpath))
                 config._impl_values._p_.setvalue(subpath, value,
-                                                 owners.forced, None)
+                                                 owners.forced, None, session)
+            del(session)
 
     # ____________________________________________________________
     def impl_set_group_type(self, group_type):
 
     # ____________________________________________________________
     def impl_set_group_type(self, group_type):
index 3568ef2..a53653b 100644 (file)
@@ -126,12 +126,9 @@ def get_storages(context, session_id, persistent):
         session_id = gen_id(context)
     imp = storage_type.get()
     storage = imp.Storage(session_id, persistent)
         session_id = gen_id(context)
     imp = storage_type.get()
     storage = imp.Storage(session_id, persistent)
-    settings = imp.Settings(storage)
+    settings = imp.Settings(session_id, storage)
     values = imp.Values(storage)
     values = imp.Values(storage)
-    try:
-        return settings, values
-    except Exception as err:
-        raise Exception(_('unable to get storages:') + str(err))
+    return settings, values
 
 
 def get_storages_option(type_):
 
 
 def get_storages_option(type_):
@@ -163,9 +160,14 @@ def delete_session(type_, session_id):  # pragma: optional cover
     :params session_id: id of session to delete
     """
     if type_ == 'option':
     :params session_id: id of session to delete
     """
     if type_ == 'option':
-        return storage_option_type.get().delete_session(session_id)
+        storage_option_type.get().delete_session(session_id)
     else:
     else:
-        return storage_type.get().delete_session(session_id)
+        storage_module = storage_type.get()
+        session = storage_module.storage.getsession()
+        storage_module.value.delete_session(session_id, session)
+        storage_module.storage.delete_session(session_id, session)
+        session.commit()
+        del(session)
 
 
 __all__ = (set_storage, list_sessions, delete_session)
 
 
 __all__ = (set_storage, list_sessions, delete_session)
index 8c16802..5bb985b 100644 (file)
@@ -22,7 +22,7 @@ from ..util import Cache
 class Settings(Cache):
     __slots__ = ('_properties', '_permissives')
 
 class Settings(Cache):
     __slots__ = ('_properties', '_permissives')
 
-    def __init__(self, storage):
+    def __init__(self, session_id, storage):
         # properties attribute: the name of a property enables this property
         # key is None for global properties
         self._properties = {}
         # properties attribute: the name of a property enables this property
         # key is None for global properties
         self._properties = {}
index e9c257b..0f17b1b 100644 (file)
@@ -57,3 +57,7 @@ class Storage(object):
             _list_sessions.remove(self.session_id)
         except AttributeError:  # pragma: optional cover
             pass
             _list_sessions.remove(self.session_id)
         except AttributeError:  # pragma: optional cover
             pass
+
+
+def getsession():
+    pass
index cb7baf1..d77afa9 100644 (file)
@@ -26,11 +26,18 @@ class Values(Cache):
     def __init__(self, storage):
         """init plugin means create values storage
         """
     def __init__(self, storage):
         """init plugin means create values storage
         """
+        #(('path1',), (index1,), (value1,), ('owner1'))
         self._values = (tuple(), tuple(), tuple(), tuple())
         self._informations = {}
         # should init cache too
         super(Values, self).__init__(storage)
 
         self._values = (tuple(), tuple(), tuple(), tuple())
         self._informations = {}
         # should init cache too
         super(Values, self).__init__(storage)
 
+    def getsession(self):
+        pass
+
+    def delsession(self, session):
+        pass
+
     def _setvalue_info(self, nb, idx, value, values, index, vidx):
         lst = list(self._values[nb])
         if idx is None:
     def _setvalue_info(self, nb, idx, value, values, index, vidx):
         lst = list(self._values[nb])
         if idx is None:
@@ -56,13 +63,10 @@ class Values(Cache):
                     tval[vidx] = value
                     lst[idx] = tuple(tval)
                 lst[idx] = tuple(lst[idx])
                     tval[vidx] = value
                     lst[idx] = tuple(tval)
                 lst[idx] = tuple(lst[idx])
-        for ls in lst:
-            if isinstance(ls, list):
-                raise Exception('pouet')
         values.append(tuple(lst))
         return vidx
     # value
         values.append(tuple(lst))
         return vidx
     # value
-    def setvalue(self, path, value, owner, index):
+    def setvalue(self, path, value, owner, index, session):
         """set value for a path
         a specified value must be associated to an owner
         """
         """set value for a path
         a specified value must be associated to an owner
         """
@@ -83,7 +87,7 @@ class Values(Cache):
         self._setvalue_info(3, idx, owner, values, index, vidx)
         self._values = tuple(values)
 
         self._setvalue_info(3, idx, owner, values, index, vidx)
         self._values = tuple(values)
 
-    def getvalue(self, path, index=None):
+    def getvalue(self, path, session, index=None):
         """get value for a path
         return: only value, not the owner
         """
         """get value for a path
         return: only value, not the owner
         """
@@ -95,7 +99,7 @@ class Values(Cache):
         """
         return path in self._values[0]
 
         """
         return path in self._values[0]
 
-    def resetvalue(self, path):
+    def resetvalue(self, path, session):
         """remove value means delete value in storage
         """
         def _resetvalue(nb):
         """remove value means delete value in storage
         """
         def _resetvalue(nb):
@@ -132,7 +136,7 @@ class Values(Cache):
         return values
 
     # owner
         return values
 
     # owner
-    def setowner(self, path, owner, index=None):
+    def setowner(self, path, owner, session, index=None):
         """change owner for a path
         """
         idx = self._values[0].index(path)
         """change owner for a path
         """
         idx = self._values[0].index(path)
@@ -146,30 +150,30 @@ class Values(Cache):
         lst[3] = tuple(values[0])
         self._values = tuple(lst)
 
         lst[3] = tuple(values[0])
         self._values = tuple(lst)
 
-    def get_max_length(self, path):
+    def get_max_length(self, path, session):
         if path in self._values[0]:
             idx = self._values[0].index(path)
         else:
             return 0
         return max(self._values[1][idx]) + 1
 
         if path in self._values[0]:
             idx = self._values[0].index(path)
         else:
             return 0
         return max(self._values[1][idx]) + 1
 
-    def getowner(self, path, default, index=None, only_default=False):
+    def getowner(self, path, default, session, index=None, only_default=False):
         """get owner for a path
         return: owner object
         """
         if index is None:
             if only_default:
                 if path in self._values[0]:
         """get owner for a path
         return: owner object
         """
         if index is None:
             if only_default:
                 if path in self._values[0]:
-                    return None
+                    return undefined
                 else:
                     return default
             val = self._getvalue(path, 3, index)
                 else:
                     return default
             val = self._getvalue(path, 3, index)
-            if val is None:
+            if val is undefined:
                 return default
             return val
         else:
             value = self._getvalue(path, 3, index)
                 return default
             return val
         else:
             value = self._getvalue(path, 3, index)
-            if value is None:
+            if value is undefined:
                 return default
             else:
                 return value
                 return default
             else:
                 return value
@@ -197,7 +201,7 @@ class Values(Cache):
                         subidx = self._values[1][idx].index(index)
                         value = self._values[nb][idx][subidx]
                     else:
                         subidx = self._values[1][idx].index(index)
                         value = self._values[nb][idx][subidx]
                     else:
-                        value = None
+                        value = undefined
                 else:
                     value = []
                     for i in xrange(0, max(self._values[1][idx])):
                 else:
                     value = []
                     for i in xrange(0, max(self._values[1][idx])):
@@ -206,7 +210,7 @@ class Values(Cache):
                         else:
                             value.append(undefined)
         else:
                         else:
                             value.append(undefined)
         else:
-            value = None
+            value = undefined
         if isinstance(value, tuple):
             value = list(value)
         return value
         if isinstance(value, tuple):
             value = list(value)
         return value
@@ -230,3 +234,12 @@ class Values(Cache):
             raise ValueError(_("information's item"
                                " not found: {0}").format(key))
         return value
             raise ValueError(_("information's item"
                                " not found: {0}").format(key))
         return value
+
+    def exportation(self, session, fake=False):
+        return self._values
+
+    def importation(self, export):
+        self._values = export
+
+def delete_session(session_id, session):
+    raise ValueError(_('a dictionary cannot be persistent'))
index 827cd2f..cd9a039 100644 (file)
@@ -24,7 +24,7 @@ use it. But if something goes wrong, you will lost your modifications.
 """
 from .value import Values
 from .setting import Settings
 """
 from .value import Values
 from .setting import Settings
-from .storage import Storage, list_sessions, delete_session, setting
+from .storage import Storage, list_sessions, delete_session, storage_setting
 from .option import StorageBase, StorageOptionDescription
 from .util import load
 
 from .option import StorageBase, StorageOptionDescription
 from .util import load
 
@@ -32,6 +32,6 @@ from .util import load
 load()
 
 
 load()
 
 
-__all__ = (setting, Values, Settings, Storage, list_sessions, delete_session,
+__all__ = (storage_setting, Values, Settings, Storage, list_sessions, delete_session,
            StorageBase, StorageOptionDescription)
 #           Base, OptionDescription)
            StorageBase, StorageOptionDescription)
 #           Base, OptionDescription)
index 6095979..260ce68 100644 (file)
@@ -56,6 +56,7 @@ class _Permissive (SqlAlchemyBase):
 class Settings(Cache, SqlAlchemyBase):
     __tablename__ = 'settings'
     id = Column(Integer, primary_key=True)
 class Settings(Cache, SqlAlchemyBase):
     __tablename__ = 'settings'
     id = Column(Integer, primary_key=True)
+    session_id = Column(String, index=True)
     _props = relationship("_Property",
                           collection_class=attribute_mapped_collection('path'),
                           cascade="all, delete-orphan")
     _props = relationship("_Property",
                           collection_class=attribute_mapped_collection('path'),
                           cascade="all, delete-orphan")
@@ -65,13 +66,21 @@ class Settings(Cache, SqlAlchemyBase):
                           cascade="all, delete-orphan")
     _permissives = association_proxy("_perms", "permissives")
 
                           cascade="all, delete-orphan")
     _permissives = association_proxy("_perms", "permissives")
 
-    #def __init__(self, storage):
-    #    super(Settings, self).__init__(storage)
+    def __init__(self, session_id, storage):
+        session = self.getsession()
+        self.session_id = session_id
+        super(Settings, self).__init__(storage)
+        session.commit()
+
+    def getsession(self):
+        return util.Session()
 
     # properties
     def setproperties(self, path, properties):
 
     # properties
     def setproperties(self, path, properties):
+        session = self.getsession()
         self._properties[path] = properties
         self._properties[path] = properties
-        util.session.commit()
+        session.commit()
+        del(session)
 
     def getproperties(self, path, default_properties):
         return self._properties.get(path, set(default_properties))
 
     def getproperties(self, path, default_properties):
         return self._properties.get(path, set(default_properties))
@@ -80,20 +89,25 @@ class Settings(Cache, SqlAlchemyBase):
         return path in self._properties
 
     def reset_all_properties(self):
         return path in self._properties
 
     def reset_all_properties(self):
+        session = self.getsession()
         self._properties.clear()
         self._properties.clear()
-        util.session.commit()
+        session.commit()
+        del(session)
 
     def delproperties(self, path):
         try:
 
     def delproperties(self, path):
         try:
+            session = self.getsession()
             del(self._properties[path])
             del(self._properties[path])
-            util.session.commit()
+            session.commit()
+            del(session)
         except KeyError:
             pass
 
     # permissive
     def setpermissive(self, path, permissive):
         except KeyError:
             pass
 
     # permissive
     def setpermissive(self, path, permissive):
+        session = self.getsession()
         self._permissives[path] = frozenset(permissive)
         self._permissives[path] = frozenset(permissive)
-        util.session.commit()
+        session.commit()
 
     def getpermissive(self, path=None):
         ret = self._permissives.get(path, frozenset())
 
     def getpermissive(self, path=None):
         ret = self._permissives.get(path, frozenset())
@@ -111,3 +125,13 @@ class Settings(Cache, SqlAlchemyBase):
         example: {'path1': set(['perm1', 'perm2'])}
         """
         return self._permissives
         example: {'path1': set(['perm1', 'perm2'])}
         """
         return self._permissives
+
+
+def delete_session(session_id, session):
+    print session.query(_Property).all()
+    print session.query(_Permissive).all()
+    settings_id = session.query(Settings).filter_by(session_id=session_id).first().id
+    for val in session.query(_Property).filter_by(settings=settings_id).all():
+        session.delete(val)
+    for val in session.query(_Permissive).filter_by(settings=settings_id).all():
+        session.delete(val)
index f64a361..627a1e2 100644 (file)
@@ -30,7 +30,7 @@ class Setting(SerializeObject):
     dir_database = '/tmp'
 
 
     dir_database = '/tmp'
 
 
-setting = Setting()
+storage_setting = Setting()
 
 
 class Session(SqlAlchemyBase):
 
 
 class Session(SqlAlchemyBase):
@@ -43,16 +43,21 @@ class Session(SqlAlchemyBase):
 
 
 def list_sessions():  # pragma: optional cover
 
 
 def list_sessions():  # pragma: optional cover
+    session = util.Session()
     ret = []
     ret = []
-    for val in util.session.query(Session).all():
+    for val in session.query(Session).all():
         ret.append(val.session)
         ret.append(val.session)
+    del(session)
     return ret
 
 
     return ret
 
 
-def delete_session(session_id):  # pragma: optional cover
-    #Must remove all values for this session!
-    util.session.delete(util.session.query(Session).filter_by(session=session_id).first())
-    util.session.commit()
+def delete_session(session_id, session):  # pragma: optional cover
+    session.delete(session.query(Session).filter_by(session=session_id).first())
+    session.commit()
+
+
+def getsession():
+    return util.Session()
 
 
 class Storage(object):
 
 
 class Storage(object):
@@ -62,12 +67,16 @@ class Storage(object):
     serializable = True
 
     def __init__(self, session_id, persistent, test=False):
     serializable = True
 
     def __init__(self, session_id, persistent, test=False):
-        if util.session.query(Session).filter_by(session=session_id).first():  # pragma: optional cover
-            raise ValueError(_('session already used'))
+        session = getsession()
         self.session_id = session_id
         self.persistent = persistent
         self.session_id = session_id
         self.persistent = persistent
-        util.session.add(Session(session_id))
-        util.session.commit()
+        if not session.query(Session).filter_by(session=session_id).first():  # pragma: optional cover
+            session.add(Session(session_id))
+            session.commit()
+        del(session)
 
     def __del__(self):
 
     def __del__(self):
-        delete_session(self.session_id)
+        if not self.persistent:
+            session = getsession()
+            delete_session(self.session_id, session)
+            del(session)
index 7af84a1..2849dda 100644 (file)
@@ -25,15 +25,14 @@ from sqlalchemy import create_engine
 engine = create_engine('sqlite:///:memory:')
 SqlAlchemyBase = declarative_base()
 
 engine = create_engine('sqlite:///:memory:')
 SqlAlchemyBase = declarative_base()
 
-global session
-session = None
+global session, Session
+Session = None
 
 
 def load():
 
 
 def load():
-    global session
-    if session is None:
+    global session, Session
+    if Session is None:
         #engine.echo = True
         #print SqlAlchemyBase.metadata.tables.keys()
         SqlAlchemyBase.metadata.create_all(engine)
         #engine.echo = True
         #print SqlAlchemyBase.metadata.tables.keys()
         SqlAlchemyBase.metadata.create_all(engine)
-        Session = sessionmaker(bind=engine)
-        session = Session()
+        Session = sessionmaker(bind=engine, expire_on_commit=False)
index 112d3a5..a917bc7 100644 (file)
@@ -20,7 +20,9 @@
 from ..util import Cache
 from .util import SqlAlchemyBase
 import util
 from ..util import Cache
 from .util import SqlAlchemyBase
 import util
+from ...setting import undefined
 from sqlalchemy import Column, Integer, String, PickleType
 from sqlalchemy import Column, Integer, String, PickleType
+from sqlalchemy import func
 from tiramisu.setting import owners
 
 
 from tiramisu.setting import owners
 
 
@@ -30,13 +32,13 @@ from tiramisu.setting import owners
 class _Vinformation(SqlAlchemyBase):
     __tablename__ = 'vinformation'
     id = Column(Integer, primary_key=True)
 class _Vinformation(SqlAlchemyBase):
     __tablename__ = 'vinformation'
     id = Column(Integer, primary_key=True)
-    session = Column(String, index=True)
+    session_id = Column(String, index=True)
     path = Column(String, index=True)
     key = Column(String)
     value = Column(PickleType)
 
     path = Column(String, index=True)
     key = Column(String)
     value = Column(PickleType)
 
-    def __init__(self, session, key, value):
-        self.session = session
+    def __init__(self, session_id, key, value):
+        self.session_id = session_id
         self.key = key
         self.value = value
 
         self.key = key
         self.value = value
 
@@ -44,90 +46,116 @@ class _Vinformation(SqlAlchemyBase):
 class Value(SqlAlchemyBase):
     __tablename__ = 'value'
     id = Column(Integer, primary_key=True)
 class Value(SqlAlchemyBase):
     __tablename__ = 'value'
     id = Column(Integer, primary_key=True)
-    session = Column(String, index=True)
+    session_id = Column(String, index=True)
     path = Column(String, index=True)
     key = Column(String)
     value = Column(PickleType)
     owner = Column(String)
     path = Column(String, index=True)
     key = Column(String)
     value = Column(PickleType)
     owner = Column(String)
+    indx = Column(Integer, index=True)
 
 
-    def __init__(self, session, path, value, owner):
-        self.session = session
+    def __init__(self, session_id, path, value, owner, index):
+        self.session_id = session_id
         self.path = path
         self.value = value
         self.owner = owner
         self.path = path
         self.value = value
         self.owner = owner
+        self.indx = index
 
 
 class Values(Cache):
 
 
 
 class Values(Cache):
 
+    def getsession(self):
+        return util.Session()
+
     # value
     # value
-    def setvalue(self, path, value, owner):
+    def setvalue(self, path, value, owner, index, session):
         """set value for a path
         a specified value must be associated to an owner
         """
         """set value for a path
         a specified value must be associated to an owner
         """
-        val = util.session.query(Value).filter_by(
-            path=path, session=self._storage.session_id).first()
+        #if it's a multi
+        if isinstance(value, list):
+            value = list(value)
+        val = session.query(Value).filter_by(
+            path=path, indx=index, session_id=self._storage.session_id).first()
         if val is None:
         if val is None:
-            util.session.add(Value(self._storage.session_id, path, value,
-                                   owner))
+            session.add(Value(self._storage.session_id, path, value,
+                                   owner, index))
         else:
             val.value = value
             val.owner = owner
         else:
             val.value = value
             val.owner = owner
-        util.session.commit()
+        session.commit()
 
 
-    def getvalue(self, path):
+    def getvalue(self, path, session, index=None):
         """get value for a path
         return: only value, not the owner
         """
         """get value for a path
         return: only value, not the owner
         """
-        val = util.session.query(Value).filter_by(
-            path=path, session=self._storage.session_id).first()
+        val = session.query(Value).filter_by(
+            path=path, indx=index, session_id=self._storage.session_id).first()
         if not val:
             raise KeyError('no value found')
         return val.value
 
         if not val:
             raise KeyError('no value found')
         return val.value
 
-    def hasvalue(self, path):
+    def hasvalue(self, path, session):
         """if path has a value
         return: boolean
         """
         """if path has a value
         return: boolean
         """
-        return util.session.query(Value).filter_by(
-            path=path, session=self._storage.session_id).first() is not None
+        return session.query(Value).filter_by(
+                  path=path, session_id=self._storage.session_id).first() is not None
 
 
-    def resetvalue(self, path):
+    def resetvalue(self, path, session):
         """remove value means delete value in storage
         """
         """remove value means delete value in storage
         """
-        val = util.session.query(Value).filter_by(
-            path=path, session=self._storage.session_id).first()
-        if val is not None:
-            util.session.delete(val)
-            util.session.commit()
+        vals = session.query(Value).filter_by(
+            path=path, session_id=self._storage.session_id).all()
+        if vals != []:
+            for val in vals:
+                session.delete(val)
+            session.commit()
 
     def get_modified_values(self):
         """return all values in a dictionary
         example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
         """
 
     def get_modified_values(self):
         """return all values in a dictionary
         example: {'path1': (owner, 'value1'), 'path2': (owner, 'value2')}
         """
+        session = self.getsession()
         ret = {}
         ret = {}
-        for val in util.session.query(Value).filter_by(
-                session=self._storage.session_id).all():
-            ret[val.path] = (val.owner, val.value)
+        for val in session.query(Value).filter_by(
+                session_id=self._storage.session_id).all():
+            value = val.value
+            if isinstance(val.value, list):
+                value = tuple(val.value)
+            ret[val.path] = (val.owner, value)
+        del(session)
         return ret
 
     # owner
         return ret
 
     # owner
-    def setowner(self, path, owner):
+    def setowner(self, path, owner, session, index=None):
         """change owner for a path
         """
         """change owner for a path
         """
-        val = util.session.query(Value).filter_by(
-            path=path, session=self._storage.session_id).first()
+        val = session.query(Value).filter_by(
+            path=path, indx=index, session_id=self._storage.session_id).first()
         if val is None:
             raise KeyError('no value found')
         else:
             val.owner = owner
         if val is None:
             raise KeyError('no value found')
         else:
             val.owner = owner
-        util.session.commit()
+        session.commit()
+
+    def get_max_length(self, path, session):
+        val = session.query(Value, func.max(Value.indx)).filter_by(
+                    path=path, session_id=self._storage.session_id).first()
+        if val[1] is None:
+            maxval = 0
+        else:
+            maxval = val[1] + 1
+        return maxval
 
 
-    def getowner(self, path, default):
+    def getowner(self, path, default, session, index=None, only_default=False):
+        #FIXME support de only_default
         """get owner for a path
         return: owner object
         """
         """get owner for a path
         return: owner object
         """
-        val = util.session.query(Value).filter_by(
-            path=path, session=self._storage.session_id).first()
+        session.commit()
+        val = session.query(Value).filter_by(
+            path=path, session_id=self._storage.session_id,
+            indx=index).first()
         if val is None:
             return default
         else:
         if val is None:
             return default
         else:
@@ -146,23 +174,70 @@ class Values(Cache):
         :param key: information's key (ex: "help", "doc"
         :param value: information's value (ex: "the help string")
         """
         :param key: information's key (ex: "help", "doc"
         :param value: information's value (ex: "the help string")
         """
-        pass
-        val = util.session.query(_Vinformation).filter_by(
-            key=key, session=self._storage.session_id).first()
+        session = self.getsession()
+        val = session.query(_Vinformation).filter_by(
+            key=key, session_id=self._storage.session_id).first()
         if val is None:
         if val is None:
-            util.session.add(_Vinformation(self._storage.session_id, key,
+            session.add(_Vinformation(self._storage.session_id, key,
                                            value))
         else:
             val.value = value
                                            value))
         else:
             val.value = value
-        util.session.commit()
+        session.commit()
+        del(session)
 
 
-    def get_information(self, key):
+    def get_information(self, key, default):
         """retrieves one information's item
 
         :param key: the item string (ex: "help")
         """
         """retrieves one information's item
 
         :param key: the item string (ex: "help")
         """
-        val = util.session.query(_Vinformation).filter_by(
-            key=key, session=self._storage.session_id).first()
+        session = self.getsession()
+        val = session.query(_Vinformation).filter_by(
+            key=key, session_id=self._storage.session_id).first()
+        del(session)
         if not val:
         if not val:
+            if default is not undefined:
+                return default
             raise ValueError("not found")
         return val.value
             raise ValueError("not found")
         return val.value
+
+    def exportation(self, session, fake=False):
+        if fake:
+            #(('path1',), (index1,), (value1,), ('owner1'))
+            paths = []
+            indexes = []
+            values = []
+            owners_ = []
+            slaves = {}
+            for val in session.query(Value).filter_by(
+                    session_id=self._storage.session_id).all():
+                if val.indx is not None:
+                    slaves.setdefault(val.path, []).append((val.indx, val.value, getattr(owners, val.owner)))
+                else:
+                    paths.append(val.path)
+                    indexes.append(val.indx)
+                    values.append(val.value)
+                    owners_.append(getattr(owners, val.owner))
+            for path, vals in slaves.items():
+                paths.append(path)
+                t_idxes = []
+                t_vals = []
+                t_owners = []
+                for val in vals:
+                    t_idxes.append(val[0])
+                    t_vals.append(val[1])
+                    t_owners.append(val[2])
+                indexes.append(tuple(t_idxes))
+                values.append(t_vals)
+                owners_.append(t_owners)
+            return (paths, indexes, values, owners_)
+        pass
+
+    def importation(self, value):
+        pass
+
+
+def delete_session(session_id, session):
+    for val in session.query(_Vinformation).filter_by(session_id=session_id).all():
+        session.delete(val)
+    for val in session.query(Value).filter_by(session_id=session_id).all():
+        session.delete(val)
index 626c306..c780640 100644 (file)
@@ -104,7 +104,7 @@ class Values(object):
         return value
 
     def _getvalue(self, opt, path, self_properties, index, submulti_index,
         return value
 
     def _getvalue(self, opt, path, self_properties, index, submulti_index,
-                  with_meta, masterlen):
+                  with_meta, masterlen, session):
         """actually retrieves the value
 
         :param opt: the `option.Option()` object
         """actually retrieves the value
 
         :param opt: the `option.Option()` object
@@ -113,16 +113,16 @@ class Values(object):
         force_default = 'frozen' in self_properties and \
             'force_default_on_freeze' in self_properties
         # not default value
         force_default = 'frozen' in self_properties and \
             'force_default_on_freeze' in self_properties
         # not default value
-        is_default = self._is_default_owner(opt, path,
+        is_default = self._is_default_owner(opt, path, session, 
                                             validate_properties=False,
                                             validate_meta=False,
                                             self_properties=self_properties,
                                             index=index)
         if not is_default and not force_default:
             if opt.impl_is_master_slaves('slave'):
                                             validate_properties=False,
                                             validate_meta=False,
                                             self_properties=self_properties,
                                             index=index)
         if not is_default and not force_default:
             if opt.impl_is_master_slaves('slave'):
-                return self._p_.getvalue(path, index)
+                return self._p_.getvalue(path, session, index)
             else:
             else:
-                value = self._p_.getvalue(path)
+                value = self._p_.getvalue(path, session)
                 if index is not None:
                     if len(value) > index:
                         return value[index]
                 if index is not None:
                     if len(value) > index:
                         return value[index]
@@ -146,8 +146,10 @@ class Values(object):
         path = opt.impl_getpath(self._getcontext())
         return self._contains(path)
 
         path = opt.impl_getpath(self._getcontext())
         return self._contains(path)
 
-    def _contains(self, path):
-        return self._p_.hasvalue(path)
+    def _contains(self, path, session=None):
+        if session is None:
+            session = self._p_.getsession()
+        return self._p_.hasvalue(path, session)
 
     def __delitem__(self, opt):
         """overrides the builtins `del()` instructions"""
 
     def __delitem__(self, opt):
         """overrides the builtins `del()` instructions"""
@@ -160,10 +162,12 @@ class Values(object):
             path = opt.impl_getpath(context)
         if _setting_properties is None:
             _setting_properties = setting._getproperties(read_write=False)
             path = opt.impl_getpath(context)
         if _setting_properties is None:
             _setting_properties = setting._getproperties(read_write=False)
-        hasvalue = self._contains(path)
+        session = self._p_.getsession()
+        hasvalue = self._contains(path, session)
 
         if validate and hasvalue and 'validator' in _setting_properties:
 
         if validate and hasvalue and 'validator' in _setting_properties:
-            fake_context = context._gen_fake_values()
+            session = context.cfgimpl_get_values()._p_.getsession()
+            fake_context = context._gen_fake_values(session)
             fake_value = fake_context.cfgimpl_get_values()
             fake_value.reset(opt, path, validate=False)
             fake_value._get_cached_value(opt, path,
             fake_value = fake_context.cfgimpl_get_values()
             fake_value.reset(opt, path, validate=False)
             fake_value._get_cached_value(opt, path,
@@ -180,7 +184,7 @@ class Values(object):
                 value = self._getdefaultvalue(opt, path, True, undefined, undefined, False)
                 self._setvalue(opt, path, value, force_owner=owners.forced)
             else:
                 value = self._getdefaultvalue(opt, path, True, undefined, undefined, False)
                 self._setvalue(opt, path, value, force_owner=owners.forced)
             else:
-                self._p_.resetvalue(path)
+                self._p_.resetvalue(path, session)
             context.cfgimpl_reset_cache()
 
     def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
             context.cfgimpl_reset_cache()
 
     def _isempty(self, opt, value, force_allow_empty_list=False, index=None):
@@ -221,7 +225,7 @@ class Values(object):
                           setting_properties=undefined, self_properties=undefined,
                           index=None, submulti_index=undefined, from_masterslave=False,
                           with_meta=True, masterlen=undefined, check_frozen=False,
                           setting_properties=undefined, self_properties=undefined,
                           index=None, submulti_index=undefined, from_masterslave=False,
                           with_meta=True, masterlen=undefined, check_frozen=False,
-                          returns_raise=False):
+                          returns_raise=False, session=None):
         context = self._getcontext()
         settings = context.cfgimpl_get_settings()
         if path is None:
         context = self._getcontext()
         settings = context.cfgimpl_get_settings()
         if path is None:
@@ -255,12 +259,15 @@ class Values(object):
                         else:
                             raise props
                 return value
                         else:
                             raise props
                 return value
+        if session is None:
+            session = self._p_.getsession()
         if not from_masterslave and opt.impl_is_master_slaves():
             val = opt.impl_get_master_slaves().getitem(self, opt, path,
                                                        validate,
                                                        force_permissive,
                                                        trusted_cached_properties,
                                                        validate_properties,
         if not from_masterslave and opt.impl_is_master_slaves():
             val = opt.impl_get_master_slaves().getitem(self, opt, path,
                                                        validate,
                                                        force_permissive,
                                                        trusted_cached_properties,
                                                        validate_properties,
+                                                       session,
                                                        setting_properties=setting_properties,
                                                        index=index,
                                                        self_properties=self_properties,
                                                        setting_properties=setting_properties,
                                                        index=index,
                                                        self_properties=self_properties,
@@ -276,7 +283,8 @@ class Values(object):
                                             index=index,
                                             submulti_index=submulti_index,
                                             check_frozen=check_frozen,
                                             index=index,
                                             submulti_index=submulti_index,
                                             check_frozen=check_frozen,
-                                            returns_raise=returns_raise)
+                                            returns_raise=returns_raise,
+                                            session=session)
         if isinstance(val, Exception):
             if returns_raise:
                 return val
         if isinstance(val, Exception):
             if returns_raise:
                 return val
@@ -298,7 +306,8 @@ class Values(object):
                              index=None, submulti_index=undefined,
                              with_meta=True, setting_properties=undefined,
                              self_properties=undefined, masterlen=undefined,
                              index=None, submulti_index=undefined,
                              with_meta=True, setting_properties=undefined,
                              self_properties=undefined, masterlen=undefined,
-                             check_frozen=False, returns_raise=False):
+                             check_frozen=False, returns_raise=False,
+                             session=None):
         """same has getitem but don't touch the cache
         index is None for slave value, if value returned is not a list, just return []
         """
         """same has getitem but don't touch the cache
         index is None for slave value, if value returned is not a list, just return []
         """
@@ -309,8 +318,10 @@ class Values(object):
         if self_properties is undefined:
             self_properties = setting._getproperties(opt, path, read_write=False, index=index)
         config_error = None
         if self_properties is undefined:
             self_properties = setting._getproperties(opt, path, read_write=False, index=index)
         config_error = None
+        if session is None:
+            session = self._p_.getsession()
         value = self._getvalue(opt, path, self_properties, index, submulti_index,
         value = self._getvalue(opt, path, self_properties, index, submulti_index,
-                               with_meta, masterlen)
+                               with_meta, masterlen, session)
         if isinstance(value, Exception):
             if isinstance(value, ConfigError):
                 # For calculating properties, we need value (ie for mandatory
         if isinstance(value, Exception):
             if isinstance(value, ConfigError):
                 # For calculating properties, we need value (ie for mandatory
@@ -387,12 +398,15 @@ class Values(object):
         context = self._getcontext()
         setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=False)
         if 'validator' in setting_properties:
         context = self._getcontext()
         setting_properties = context.cfgimpl_get_settings()._getproperties(read_write=False)
         if 'validator' in setting_properties:
-            fake_context = context._gen_fake_values()
+            session = context.cfgimpl_get_values()._p_.getsession()
+            fake_context = context._gen_fake_values(session)
             fake_values = fake_context.cfgimpl_get_values()
             fake_values._setvalue(opt, path, value)
             fake_values = fake_context.cfgimpl_get_values()
             fake_values._setvalue(opt, path, value)
-            props = fake_values.validate(opt, value, path, check_frozen,
-                                         force_permissive, setting_properties,
-                                         not_raises=not_raises)
+            props = fake_values.validate(opt, value, path,
+                                         check_frozen=check_frozen,
+                                         force_permissive=force_permissive,
+                                         setting_properties=setting_properties,
+                                         session=session, not_raises=not_raises)
             if props and not_raises:
                 return
             err = opt.impl_validate(value, fake_context)
             if props and not_raises:
                 return
             err = opt.impl_validate(value, fake_context)
@@ -414,22 +428,26 @@ class Values(object):
                 for idx, val in enumerate(value):
                     if isinstance(val, SubMulti):
                         value[idx] = list(val)
                 for idx, val in enumerate(value):
                     if isinstance(val, SubMulti):
                         value[idx] = list(val)
+        session = self._p_.getsession()
         #FIXME pourquoi là et pas dans masterslaves ??
         if opt.impl_is_master_slaves('slave'):
             if index is not None:
         #FIXME pourquoi là et pas dans masterslaves ??
         if opt.impl_is_master_slaves('slave'):
             if index is not None:
-                self._p_.setvalue(path, value[index], owner, index)
+                self._p_.setvalue(path, value[index], owner, index, session)
             else:
             else:
-                self._p_.resetvalue(path)
+                self._p_.resetvalue(path, session)
                 for idx, val in enumerate(value):
                 for idx, val in enumerate(value):
-                    self._p_.setvalue(path, val, owner, idx)
+                    self._p_.setvalue(path, val, owner, idx, session)
         else:
         else:
-            self._p_.setvalue(path, value, owner, None)
+            self._p_.setvalue(path, value, owner, None, session)
+        del(session)
 
     def validate(self, opt, value, path, check_frozen=True, force_permissive=False,
                  setting_properties=undefined, valid_masterslave=True,
 
     def validate(self, opt, value, path, check_frozen=True, force_permissive=False,
                  setting_properties=undefined, valid_masterslave=True,
-                 not_raises=False, returns_raise=False):
+                 not_raises=False, returns_raise=False, session=None):
         if valid_masterslave and opt.impl_is_master_slaves():
         if valid_masterslave and opt.impl_is_master_slaves():
-            opt.impl_get_master_slaves().validate(self, opt, value, path, returns_raise)
+            if session is None:
+                session = self._p_.getsession()
+            opt.impl_get_master_slaves().validate(self, opt, value, path, returns_raise, session)
         props = self._getcontext().cfgimpl_get_settings().validate_properties(opt,
                                                                               False,
                                                                               check_frozen,
         props = self._getcontext().cfgimpl_get_settings().validate_properties(opt,
                                                                               False,
                                                                               check_frozen,
@@ -442,19 +460,19 @@ class Values(object):
                 return props
             raise props
 
                 return props
             raise props
 
-    def _is_meta(self, opt, path):
+    def _is_meta(self, opt, path, session):
         context = self._getcontext()
         setting = context.cfgimpl_get_settings()
         self_properties = setting._getproperties(opt, path, read_write=False)
         if 'frozen' in self_properties and 'force_default_on_freeze' in self_properties:
             return False
         context = self._getcontext()
         setting = context.cfgimpl_get_settings()
         self_properties = setting._getproperties(opt, path, read_write=False)
         if 'frozen' in self_properties and 'force_default_on_freeze' in self_properties:
             return False
-        if self._p_.getowner(path, owners.default, only_default=True) is not owners.default:
+        if self._p_.getowner(path, owners.default, session, only_default=True) is not owners.default:
             return False
         if context.cfgimpl_get_meta() is not None:
             return True
         return False
 
             return False
         if context.cfgimpl_get_meta() is not None:
             return True
         return False
 
-    def getowner(self, opt, index=None, force_permissive=False):
+    def getowner(self, opt, index=None, force_permissive=False, session=None):
         """
         retrieves the option's owner
 
         """
         retrieves the option's owner
 
@@ -467,14 +485,16 @@ class Values(object):
                 not isinstance(opt, DynSymLinkOption):
             opt = opt._impl_getopt()
         path = opt.impl_getpath(self._getcontext())
                 not isinstance(opt, DynSymLinkOption):
             opt = opt._impl_getopt()
         path = opt.impl_getpath(self._getcontext())
-        return self._getowner(opt, path, index=index, force_permissive=force_permissive)
+        return self._getowner(opt, path, session, index=index, force_permissive=force_permissive)
 
 
-    def _getowner(self, opt, path, validate_properties=True,
+    def _getowner(self, opt, path, session, validate_properties=True,
                   force_permissive=False, validate_meta=undefined,
                   self_properties=undefined, only_default=False,
                   index=None):
         """get owner of an option
         """
                   force_permissive=False, validate_meta=undefined,
                   self_properties=undefined, only_default=False,
                   index=None):
         """get owner of an option
         """
+        if session is None:
+            session = self._p_.getsession()
         if not isinstance(opt, Option) and not isinstance(opt,
                                                           DynSymLinkOption):
             raise ConfigError(_('owner only avalaible for an option'))
         if not isinstance(opt, Option) and not isinstance(opt,
                                                           DynSymLinkOption):
             raise ConfigError(_('owner only avalaible for an option'))
@@ -486,19 +506,19 @@ class Values(object):
             return owners.default
         if validate_properties:
             self._get_cached_value(opt, path, True, force_permissive, None, True,
             return owners.default
         if validate_properties:
             self._get_cached_value(opt, path, True, force_permissive, None, True,
-                                   self_properties=self_properties)
-        owner = self._p_.getowner(path, owners.default, only_default=only_default, index=index)
+                                   self_properties=self_properties, session=session)
+        owner = self._p_.getowner(path, owners.default, session, only_default=only_default, index=index)
         if validate_meta is undefined:
             if opt.impl_is_master_slaves('slave'):
                 master = opt.impl_get_master_slaves().getmaster(opt)
                 masterp = master.impl_getpath(context)
         if validate_meta is undefined:
             if opt.impl_is_master_slaves('slave'):
                 master = opt.impl_get_master_slaves().getmaster(opt)
                 masterp = master.impl_getpath(context)
-                validate_meta = self._is_meta(opt, masterp)
+                validate_meta = self._is_meta(opt, masterp, session)
             else:
                 validate_meta = True
         if validate_meta:
             meta = context.cfgimpl_get_meta()
             if owner is owners.default and meta is not None:
             else:
                 validate_meta = True
         if validate_meta:
             meta = context.cfgimpl_get_meta()
             if owner is owners.default and meta is not None:
-                owner = meta.cfgimpl_get_values()._getowner(opt, path,
+                owner = meta.cfgimpl_get_values()._getowner(opt, path, session,
                                                             validate_properties=validate_properties,
                                                             force_permissive=force_permissive,
                                                             self_properties=self_properties,
                                                             validate_properties=validate_properties,
                                                             force_permissive=force_permissive,
                                                             self_properties=self_properties,
@@ -516,7 +536,8 @@ class Values(object):
             raise TypeError(_("invalid generic owner {0}").format(str(owner)))
 
         path = opt.impl_getpath(self._getcontext())
             raise TypeError(_("invalid generic owner {0}").format(str(owner)))
 
         path = opt.impl_getpath(self._getcontext())
-        if not self._p_.hasvalue(path):  # pragma: optional cover
+        session = self._p_.getsession()
+        if not self._p_.hasvalue(path, session):  # pragma: optional cover
             raise ConfigError(_('no value for {0} cannot change owner to {1}'
                                 '').format(path, owner))
         props = self._getcontext().cfgimpl_get_settings().validate_properties(opt,
             raise ConfigError(_('no value for {0} cannot change owner to {1}'
                                 '').format(path, owner))
         props = self._getcontext().cfgimpl_get_settings().validate_properties(opt,
@@ -526,7 +547,7 @@ class Values(object):
                                                                               index=index)
         if props:
             raise props
                                                                               index=index)
         if props:
             raise props
-        self._p_.setowner(path, owner, index=index)
+        self._p_.setowner(path, owner, session, index=index)
 
     def is_default_owner(self, opt, validate_properties=True,
                          validate_meta=True, index=None,
 
     def is_default_owner(self, opt, validate_properties=True,
                          validate_meta=True, index=None,
@@ -537,17 +558,17 @@ class Values(object):
         :return: boolean
         """
         path = opt.impl_getpath(self._getcontext())
         :return: boolean
         """
         path = opt.impl_getpath(self._getcontext())
-        return self._is_default_owner(opt, path,
+        return self._is_default_owner(opt, path, session=None, 
                                       validate_properties=validate_properties,
                                       validate_meta=validate_meta, index=index,
                                       force_permissive=force_permissive)
 
                                       validate_properties=validate_properties,
                                       validate_meta=validate_meta, index=index,
                                       force_permissive=force_permissive)
 
-    def _is_default_owner(self, opt, path, validate_properties=True,
+    def _is_default_owner(self, opt, path, session, validate_properties=True,
                           validate_meta=True, self_properties=undefined,
                           index=None, force_permissive=False):
         if not opt.impl_is_master_slaves('slave'):
             index = None
                           validate_meta=True, self_properties=undefined,
                           index=None, force_permissive=False):
         if not opt.impl_is_master_slaves('slave'):
             index = None
-        d = self._getowner(opt, path, validate_properties,
+        d = self._getowner(opt, path, session, validate_properties=validate_properties,
                            validate_meta=validate_meta,
                            self_properties=self_properties, only_default=True,
                            index=index, force_permissive=force_permissive)
                            validate_meta=validate_meta,
                            self_properties=self_properties, only_default=True,
                            index=index, force_permissive=force_permissive)
@@ -728,7 +749,8 @@ class Multi(list):
         if index < 0:
             index = self.__len__() + index
         if 'validator' in setting_properties and validate:
         if index < 0:
             index = self.__len__() + index
         if 'validator' in setting_properties and validate:
-            fake_context = context._gen_fake_values()
+            session = context.cfgimpl_get_values()._p_.getsession()
+            fake_context = context._gen_fake_values(session)
             fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                 self.opt, path=self.path, validate=False)
             fake_multi._setitem(index, value, validate=False)
             fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                 self.opt, path=self.path, validate=False)
             fake_multi._setitem(index, value, validate=False)
@@ -768,7 +790,8 @@ class Multi(list):
             setting = context.cfgimpl_get_settings()
             setting_properties = setting._getproperties(read_write=False)
             if 'validator' in setting_properties:
             setting = context.cfgimpl_get_settings()
             setting_properties = setting._getproperties(read_write=False)
             if 'validator' in setting_properties:
-                fake_context = context._gen_fake_values()
+                session = context.cfgimpl_get_values()._p_.getsession()
+                fake_context = context._gen_fake_values(session)
                 fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                     self.opt, path=self.path, validate=False,
                     force_permissive=force_permissive)
                 fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                     self.opt, path=self.path, validate=False,
                     force_permissive=force_permissive)
@@ -814,7 +837,8 @@ class Multi(list):
         setting = setting = context.cfgimpl_get_settings()
         setting_properties = setting._getproperties(read_write=False)
         if 'validator' in setting_properties and validate and value is not None:
         setting = setting = context.cfgimpl_get_settings()
         setting_properties = setting._getproperties(read_write=False)
         if 'validator' in setting_properties and validate and value is not None:
-            fake_context = context._gen_fake_values()
+            session = context.cfgimpl_get_values()._p_.getsession()
+            fake_context = context._gen_fake_values(session)
             fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                 self.opt, path=self.path, validate=False)
             fake_multi.insert(index, value, validate=False)
             fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                 self.opt, path=self.path, validate=False)
             fake_multi.insert(index, value, validate=False)
@@ -831,7 +855,8 @@ class Multi(list):
         setting = context.cfgimpl_get_settings()
         setting_properties = setting._getproperties(read_write=False)
         if 'validator' in setting_properties and validate:
         setting = context.cfgimpl_get_settings()
         setting_properties = setting._getproperties(read_write=False)
         if 'validator' in setting_properties and validate:
-            fake_context = context._gen_fake_values()
+            session = context.cfgimpl_get_values()._p_.getsession()
+            fake_context = context._gen_fake_values(session)
             fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                 self.opt, path=self.path, validate=False)
             fake_multi.extend(iterable, validate=False)
             fake_multi = fake_context.cfgimpl_get_values()._get_cached_value(
                 self.opt, path=self.path, validate=False)
             fake_multi.extend(iterable, validate=False)