refactor validation
[tiramisu.git] / tiramisu / value.py
index ea60508..eed993b 100644 (file)
@@ -83,7 +83,7 @@ class Values(object):
         # if value has callback and is not set
         if opt.impl_has_callback():
             callback, callback_params = opt.impl_get_callback()
-            value = carry_out_calculation(opt, config=self._getcontext(),
+            value = carry_out_calculation(opt, context=self._getcontext(),
                                           callback=callback,
                                           callback_params=callback_params,
                                           index=index)
@@ -161,8 +161,12 @@ class Values(object):
         if self._contains(path):
             if validate:
                 setting = context.cfgimpl_get_settings()
-                opt.impl_validate(opt.impl_getdefault(),
-                                  context, 'validator' in setting)
+                fake_context = context._gen_fake_values()
+                setting_properties = setting._getproperties()
+                fake_value = fake_context.cfgimpl_get_values()
+                fake_value.reset(opt, path, validate=False)
+                opt.impl_validate(getattr(fake_context, path),
+                                  fake_context, 'validator' in setting_properties)
             context.cfgimpl_reset_cache()
             if opt.impl_is_master_slaves('master'):
                 opt.impl_get_master_slaves().reset(opt, self)
@@ -331,8 +335,16 @@ class Values(object):
         # valid opt
         context = self._getcontext()
         setting_properties = context.cfgimpl_get_settings()._getproperties()
-        opt.impl_validate(value, context,
-                          'validator' in setting_properties)
+        fake_context = context._gen_fake_values()
+        fake_context.cfgimpl_get_values()._setitem(opt, value, path,
+                                                   force_permissive, is_write,
+                                                   setting_properties)
+        opt.impl_validate(value, fake_context, 'validator' in setting_properties)
+        self._setitem(opt, value, path, force_permissive, is_write,
+                      setting_properties)
+
+    def _setitem(self, opt, value, path, force_permissive, is_write,
+                 setting_properties):
         if opt.impl_is_master_slaves():
             opt.impl_get_master_slaves().setitem(self, opt, value, path)
         self._setvalue(opt, path, value, force_permissive=force_permissive,
@@ -607,8 +619,13 @@ class Multi(list):
     def __setitem__(self, index, value):
         self._setitem(index, value)
 
-    def _setitem(self, index, value):
-        self._validate(value, index, True)
+    def _setitem(self, index, value, validate=True):
+        if validate:
+            fake_context = self._getcontext()._gen_fake_values()
+            fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
+                self.opt, path=self.path, validate=False)
+            fake_multi._setitem(index, value, validate=False)
+            self._validate(value, fake_context, index, True)
         #assume not checking mandatory property
         super(Multi, self).__setitem__(index, value)
         self._getcontext().cfgimpl_get_values()._setvalue(self.opt, self.path,
@@ -626,7 +643,7 @@ class Multi(list):
                                            True, False, None, True,
                                            index=index)
 
-    def append(self, value=undefined, force=False, setitem=True):
+    def append(self, value=undefined, force=False, setitem=True, validate=True):
         """the list value can be updated (appened)
         only if the option is a master
         """
@@ -639,7 +656,12 @@ class Multi(list):
                 value = self._get_validated_value(index)
             except IndexError:
                 value = None
-        self._validate(value, index, True)
+        if validate and value not in [None, undefined]:
+            fake_context = self._getcontext()._gen_fake_values()
+            fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
+                self.opt, path=self.path, validate=False)
+            fake_multi.append(value, validate=False, force=True)
+            self._validate(value, fake_context, index, True)
         if not '_index' in self.__slots__ and self.opt.impl_is_submulti():
             if not isinstance(value, SubMulti):
                 value = SubMulti(value, self.context, self.opt, self.path, index)
@@ -668,16 +690,21 @@ class Multi(list):
         super(Multi, self).reverse()
         self._store()
 
-    def insert(self, index, obj):
-        #FIXME obj should be undefined
+    def insert(self, index, value, validate=True):
+        #FIXME value should be undefined
         if self.opt.impl_is_master_slaves():
             raise SlaveError(_("cannot insert multi option {0} if master or "
                                "slave").format(self.opt.impl_getname()))
-        self._validate(obj, index, True)
-        super(Multi, self).insert(index, obj)
+        if value is not None and validate:
+            fake_context = self._getcontext()._gen_fake_values()
+            fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
+                self.opt, path=self.path, validate=False)
+            fake_multi.insert(index, value, validate=False)
+            self._validate(value, fake_context, index, True)
+        super(Multi, self).insert(index, value)
         self._store()
 
-    def extend(self, iterable):
+    def extend(self, iterable, validate=True):
         if self.opt.impl_is_master_slaves():
             raise SlaveError(_("cannot extend multi option {0} if master or "
                                "slave").format(self.opt.impl_getname()))
@@ -685,14 +712,18 @@ class Multi(list):
             index = self._index
         except:
             index = None
-        self._validate(iterable, index)
+        if validate:
+            fake_context = self._getcontext()._gen_fake_values()
+            fake_multi = fake_context.cfgimpl_get_values()._get_cached_item(
+                self.opt, path=self.path, validate=False)
+            fake_multi.extend(iterable, validate=False)
+            self._validate(iterable, fake_context, index)
         super(Multi, self).extend(iterable)
         self._store()
 
-    def _validate(self, value, force_index, submulti=False):
-        if value is not None:
-            self.opt.impl_validate(value, context=self._getcontext(),
-                                   force_index=force_index)
+    def _validate(self, value, fake_context, force_index, submulti=False):
+        self.opt.impl_validate(value, context=fake_context,
+                               force_index=force_index)
 
     def pop(self, index, force=False):
         """the list value can be updated (poped)
@@ -749,12 +780,13 @@ class SubMulti(Multi):
                                                           self.path,
                                                           self.submulti())
 
-    def _validate(self, value, force_index, submulti=False):
+    def _validate(self, value, fake_context, force_index, submulti=False):
         if value is not None:
             if submulti is False:
-                super(SubMulti, self)._validate(value, force_index)
+                super(SubMulti, self)._validate(value, fake_context,
+                                                force_index, submulti)
             else:
-                self.opt.impl_validate(value, context=self._getcontext(),
+                self.opt.impl_validate(value, context=fake_context,
                                        force_index=self._index,
                                        force_submulti_index=force_index)