comment tiramisu/setting.py
[tiramisu.git] / tiramisu / setting.py
index 7946212..1dba144 100644 (file)
@@ -28,19 +28,88 @@ from tiramisu.error import (RequirementError, PropertiesOptionError,
 from tiramisu.i18n import _
 
 
+"Default encoding for display a Config if raise UnicodeEncodeError"
 default_encoding = 'utf-8'
+
+"""If cache and expire is enable, time before cache is expired.
+This delay start first time value/setting is set in cache, even if
+user access several time to value/setting
+"""
 expires_time = 5
-ro_remove = set(['permissive', 'hidden'])
+"""List of default properties (you can add new one if needed).
+
+For common properties and personalise properties, if a propery is set for
+an Option and for the Config together, Setting raise a PropertiesOptionError
+
+* Common properties:
+
+hidden
+    option with this property can only get value in read only mode. This
+    option is not available in read write mode.
+
+disabled
+    option with this property cannot be set/get
+
+frozen
+    cannot set value for option with this properties if 'frozen' is set in
+    config
+
+mandatory
+    should set value for option with this properties if 'mandatory' is set in
+    config
+
+
+* Special property:
+
+permissive
+    option with 'permissive' cannot raise PropertiesOptionError for properties
+    set in permissive
+    config with 'permissive', whole option in this config cannot raise
+    PropertiesOptionError for properties set in permissive
+
+* Special Config properties:
+
+cache
+    if set, enable cache settings and values
+
+expire
+    if set, settings and values in cache expire after ``expires_time``
+
+everything_frozen
+    whole option in config are frozen (even if option have not frozen
+    property)
+
+validator
+    launch validator set by user in option (this property has no effect
+    for internal validator)
+"""
+default_properties = ('cache', 'expire', 'validator')
+
+"""Config can be in two defaut mode:
+
+read_only
+    you can get all variables not disabled but you cannot set any variables
+    if a value has a callback without any value, callback is launch and value
+    of this variable can change
+    you cannot access to mandatory variable without values
+
+read_write
+    you can get all variables not disabled and not hidden
+    you can set all variables not frozen
+"""
 ro_append = set(['frozen', 'disabled', 'validator', 'everything_frozen',
                 'mandatory'])
-rw_remove = set(['permissive', 'everything_frozen', 'mandatory'])
+ro_remove = set(['permissive', 'hidden'])
 rw_append = set(['frozen', 'disabled', 'validator', 'hidden'])
-default_properties = ('cache', 'expire', 'validator')
+rw_remove = set(['permissive', 'everything_frozen', 'mandatory'])
 
 
+# ____________________________________________________________
 class _NameSpace:
     """convenient class that emulates a module
-    and builds constants (that is, unique names)"""
+    and builds constants (that is, unique names)
+    when attribute is added, we cannot delete it
+    """
 
     def __setattr__(self, name, value):
         if name in self.__dict__:
@@ -53,7 +122,6 @@ class _NameSpace:
         raise ValueError(name)
 
 
-# ____________________________________________________________
 class GroupModule(_NameSpace):
     "emulates a module to manage unique group (OptionDescription) names"
     class GroupType(str):
@@ -71,21 +139,8 @@ class GroupModule(_NameSpace):
         *master* means : groups that have the 'master' attribute set
         """
         pass
-# setting.groups (emulates a module)
-groups = GroupModule()
-
 
-def populate_groups():
-    "populates the available groups in the appropriate namespaces"
-    groups.master = groups.MasterGroupType('master')
-    groups.default = groups.DefaultGroupType('default')
-    groups.family = groups.GroupType('family')
-
-# names are in the module now
-populate_groups()
 
-
-# ____________________________________________________________
 class OwnerModule(_NameSpace):
     """emulates a module to manage unique owner names.
 
@@ -99,15 +154,52 @@ class OwnerModule(_NameSpace):
     class DefaultOwner(Owner):
         """groups that are default (typically 'default')"""
         pass
-# setting.owners (emulates a module)
-owners = OwnerModule()
+
+
+class MultiTypeModule(_NameSpace):
+    "namespace for the master/slaves"
+    class MultiType(str):
+        pass
+
+    class DefaultMultiType(MultiType):
+        pass
+
+    class MasterMultiType(MultiType):
+        pass
+
+    class SlaveMultiType(MultiType):
+        pass
+
+
+# ____________________________________________________________
+def populate_groups():
+    """populates the available groups in the appropriate namespaces
+
+    groups.default
+        default group set when creating a new optiondescription
+
+    groups.master
+        master group is a special optiondescription, all suboptions should be
+        multi option and all values should have same length, to find master's
+        option, the optiondescription's name should be same than de master's
+        option
+
+    groups.family
+        example of group, no special behavior with this group's type
+    """
+    groups.default = groups.DefaultGroupType('default')
+    groups.master = groups.MasterGroupType('master')
+    groups.family = groups.GroupType('family')
 
 
 def populate_owners():
     """populates the available owners in the appropriate namespaces
 
-    - 'user' is the generic is the generic owner.
-    - 'default' is the config owner after init time
+    default
+        is the config owner after init time
+
+    user
+        is the generic is the generic owner
     """
     setattr(owners, 'default', owners.DefaultOwner('default'))
     setattr(owners, 'user', owners.Owner('user'))
@@ -119,36 +211,38 @@ def populate_owners():
         setattr(owners, name, owners.Owner(name))
     setattr(owners, 'addowner', addowner)
 
-# names are in the module now
-populate_owners()
-
 
-class MultiTypeModule(_NameSpace):
-    "namespace for the master/slaves"
-    class MultiType(str):
-        pass
-
-    class DefaultMultiType(MultiType):
-        pass
-
-    class MasterMultiType(MultiType):
-        pass
+def populate_multitypes():
+    """all multi option should have a type, this type is automaticly set do
+    not touch this
 
-    class SlaveMultiType(MultiType):
-        pass
+    default
+        default's multi option set if not master or slave
 
-multitypes = MultiTypeModule()
+    master
+        master's option in a group with master's type, name of this option
+        should be the same name of the optiondescription
 
+    slave
+        slave's option in a group with master's type
 
-def populate_multitypes():
-    "populates the master/slave namespace"
+    """
     setattr(multitypes, 'default', multitypes.DefaultMultiType('default'))
     setattr(multitypes, 'master', multitypes.MasterMultiType('master'))
     setattr(multitypes, 'slave', multitypes.SlaveMultiType('slave'))
 
+
+# ____________________________________________________________
+# populate groups, owners and multitypes with default attributes
+groups = GroupModule()
+populate_groups()
+owners = OwnerModule()
+populate_owners()
+multitypes = MultiTypeModule()
 populate_multitypes()
 
 
+# ____________________________________________________________
 class Property(object):
     "a property is responsible of the option's value access rules"
     __slots__ = ('_setting', '_properties', '_opt', '_path')
@@ -171,7 +265,8 @@ class Property(object):
     def remove(self, propname):
         if propname in self._properties:
             self._properties.remove(propname)
-            self._setting._setproperties(self._properties, self._opt, self._path)
+            self._setting._setproperties(self._properties, self._opt,
+                                         self._path)
 
     def reset(self):
         self._setting.reset(_path=self._path)
@@ -381,11 +476,11 @@ class Settings(object):
             self.append(prop)
 
     def read_only(self):
-        "convenience method to freeze, hidde and disable"
+        "convenience method to freeze, hide and disable"
         self._read(ro_remove, ro_append)
 
     def read_write(self):
-        "convenience method to freeze, hidde and disable"
+        "convenience method to freeze, hide and disable"
         self._read(rw_remove, rw_append)
 
     def reset_cache(self, only_expired):