documentation on the requirements and docstring updates
authorgwen <gremond@cadoles.com>
Thu, 22 Aug 2013 09:08:26 +0000 (11:08 +0200)
committergwen <gremond@cadoles.com>
Thu, 22 Aug 2013 09:08:26 +0000 (11:08 +0200)
doc/consistency.txt
tiramisu/option.py
tiramisu/setting.py

index c5014b5..47561ff 100644 (file)
@@ -50,17 +50,27 @@ Configuration options can specify requirements as parameters at the init
 time, the specification of some links between options or groups allows
 to carry out a dependencies calculation. For example, an option can ben
 hidden if another option has been set with some expected value. This is
-just an example, because the possibilities are hudge.
+just an example, the possibilities are hudge.
 
-A requirement is specified using a list of triplets. The first element
-of the triplet gives the path of the option that is required, the second
-element is the value wich is expected to trigger the callback, and the
-third one is the callback's action name (`hide`, `show`...)::
+A requirement is a list of dictionnaries that have fairly this form::
 
-    stroption = StrOption('str', 'Test string option', default="abc",
-                          requires=[('int', 1, 'hide')])
+    [{'option': a, 'expected': False, 'action': 'disabled', 'inverse': True,
+    'transitive':True, 'same_action': True}]
 
-Requirements are validated in :class:`setting.Setting`. 
+Actually a transformation is made to this dictionnary during the validation of 
+this requires at the :class:`~option.Option()`'s init. The dictionnairy becomes 
+a tuple, wich is passed to the :meth:`~setting.Settings.apply_requires()` 
+method. Take a look at the code to fully understand the exact meaning of the 
+requirements:
+
+.. automethod:: tiramisu.setting.Settings.apply_requires
+
+
+The path of the option is required, the second element is the value wich is 
+expected to trigger the callback, it is required too, and the third one is the 
+callback's action name (`hide`, `show`...), wich is a 
+:class:`~setting.Property()`. Requirements are validated in 
+:class:`setting.Setting`.
 
 Validation upon a whole configuration object
 ----------------------------------------------
index 691498e..d95998a 100644 (file)
@@ -926,6 +926,11 @@ class OptionDescription(BaseInformation):
 def validate_requires_arg(requires, name):
     """check malformed requirements
     and tranform dict to internal tuple
+    
+    :param requires: have a look at the 
+                     :meth:`tiramisu.setting.Settings.apply_requires` method to 
+                     know more about
+                     the description of the requires dictionnary
     """
     if requires is None:
         return None
@@ -934,7 +939,6 @@ def validate_requires_arg(requires, name):
 
     for require in requires:
         if not type(require) == dict:
-            print require
             raise ValueError(_("malformed requirements type for option:"
                                " {0}, must be a dict").format(name))
         valid_keys = ('option', 'expected', 'action', 'inverse', 'transitive',
index 7417662..13176de 100644 (file)
@@ -242,7 +242,8 @@ class Settings(object):
             props = self._p_.getproperties(path, default_properties)
         else:
             if path is None:
-                raise ValueError(_('if opt is not None, path should not be None in _getproperties'))
+                raise ValueError(_('if opt is not None, path should not be'
+                                   ' None in _getproperties'))
             ntime = None
             if self._p_.hascache('property', path):
                 ntime = time()
@@ -287,13 +288,15 @@ class Settings(object):
         validation upon the properties related to `opt_or_descr`
 
         :param opt_or_descr: an option or an option description object
-        :param force_permissive: behaves as if the permissive property was present
+        :param force_permissive: behaves as if the permissive property
+                                 was present
         :param is_descr: we have to know if we are in an option description,
-                         just because the mandatory property doesn't exist there
+                         just because the mandatory property
+                         doesn't exist here
 
         :param is_write: in the validation process, an option is to be modified,
-                         the behavior can be different (typically with the `frozen`
-                         property)
+                         the behavior can be different
+                         (typically with the `frozen` property)
         """
         # opt properties
         properties = copy(self._getproperties(opt_or_descr, path))
@@ -374,12 +377,55 @@ class Settings(object):
             self._p_.reset_all_cache('property')
 
     def apply_requires(self, opt, path):
-        "carries out the jit (just in time requirements between options"
+        """carries out the jit (just in time) requirements between options
+        
+        a requirement is a tuple of this form that comes from the option's 
+        requirements validation::
+
+            (option, expected, action, inverse, transitive, same_action)
+
+        let's have a look at all the tuple's items:
+        
+        - **option** is the target option's name or path
+        
+        - **expected** is the target option's value that is going to trigger an action
+        
+        - **action** is the (property) action to be accomplished if the target option 
+          happens to have the expected value
+        
+        - if **inverse** is `True` and if the target option's value does not 
+          apply, then the property action must be removed from the option's 
+          properties list (wich means that the property is inverted)
+          
+        - **transitive**: but what happens if the target option cannot be 
+          accessed ? We don't kown the target option's value. Actually if some 
+          property in the target option is not present in the permissive, the 
+          target option's value cannot be accessed. In this case, the 
+          **action** have to be applied to the option. (the **action** property 
+          is then added to the option).
+        
+        - **same_action**: actually, if **same_action** is `True`, the 
+          transitivity is not accomplished. The transitivity is accomplished 
+          only if the target option **has the same property** that the demanded 
+          action. If the target option's value is not accessible because of 
+          another reason, because of a property of another type, then an 
+          exception :exc:`~error.RequirementError` is raised.
+
+        And at last, if no target option matches the expected values, the 
+        action must be removed from the option's properties list.
+        
+        :param opt: the option on wich the requirement occurs
+        :type opt: `option.Option()`
+        :param path: the option's path in the config
+        :type path: str
+        """
         if opt._requires is None:
             return
 
         # filters the callbacks
-        setting = Property(self, self._getproperties(opt, path, False), opt, path=path)
+        setting = Property(self,
+                           self._getproperties(opt, path, False),
+                           opt, path=path)
         for requires in opt._requires:
             matches = False
             for require in requires:
@@ -392,7 +438,8 @@ class Settings(object):
                                              " '{0}' with requirement on: "
                                              "'{1}'").format(path, reqpath))
                 try:
-                    value = self.context._getattr(reqpath, force_permissive=True)
+                    value = self.context._getattr(reqpath,
+                                                  force_permissive=True)
                 except PropertiesOptionError, err:
                     if not transitive:
                         continue