groupe_types are real types now
authorgwen <gremond@cadoles.com>
Thu, 6 Dec 2012 17:14:57 +0000 (18:14 +0100)
committergwen <gremond@cadoles.com>
Thu, 6 Dec 2012 17:14:57 +0000 (18:14 +0100)
test/test_parsing_group.py
tiramisu/config.py
tiramisu/option.py
tiramisu/setting.py
tiramisu/tool.py

index f97f4f6..d9c2e00 100644 (file)
@@ -2,6 +2,7 @@
 import autopath
 from tiramisu.config import *
 from tiramisu.option import *
+from tiramisu.setting import groups
 
 from py.test import raises
 
@@ -14,8 +15,6 @@ def make_description():
                                       default=False)
     mode_conteneur_actif = BoolOption('mode_conteneur_actif', "le serveur est en mode conteneur",
                                       default=False)
-#    hidden (variable cachée)
-#    mode_conteneur_actif.taint()
     adresse_serveur_ntp = StrOption('serveur_ntp', "adresse serveur ntp", multi=True)
     time_zone = ChoiceOption('time_zone', 'fuseau horaire du serveur',
                                 ['Paris', 'Londres'], 'Paris')
@@ -25,13 +24,13 @@ def make_description():
 
     master = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
     interface1 = OptionDescription('interface1', '', [master])
-    interface1.set_group_type('family')
+    interface1.set_group_type(groups.family)
 
     general = OptionDescription('general', '', [numero_etab, nom_machine,
                                              nombre_interfaces, activer_proxy_client,
                                              mode_conteneur_actif, adresse_serveur_ntp,
                                              time_zone])
-    general.set_group_type('family')
+    general.set_group_type(groups.family)
     creole = OptionDescription('creole', 'first tiramisu configuration', [general, interface1])
     descr = OptionDescription('baseconfig', 'baseconifgdescr', [creole] )
     return descr
@@ -63,7 +62,7 @@ def test_get_group_type():
 def test_iter_on_groups():
     descr = make_description()
     config = Config(descr)
-    result = list(config.creole.iter_groups(group_type= "family"))
+    result = list(config.creole.iter_groups(group_type=groups.family))
     group_names = [res[0] for res in result]
     assert group_names == ['general', 'interface1']
 
@@ -101,7 +100,7 @@ def make_master_group():
                                              nombre_interfaces, activer_proxy_client,
                                              mode_conteneur_actif, adresse_serveur_ntp,
                                              time_zone])
-    general.set_group_type('family')
+    general.set_group_type(groups.family)
     creole = OptionDescription('creole', 'first tiramisu configuration', [general, interface1])
     descr = OptionDescription('baseconfig', 'baseconifgdescr', [creole] )
     return descr
@@ -127,13 +126,13 @@ def make_master_group2():
 
     master = OptionDescription('ip_admin_eth0', '', [ip_admin_eth0, netmask_admin_eth0])
     interface1 = OptionDescription('interface1', '', [master])
-    interface1.set_group_type('group', master='interface1')
+    interface1.set_group_type(groups.group, master='interface1')
 
     general = OptionDescription('general', '', [numero_etab, nom_machine,
                                              nombre_interfaces, activer_proxy_client,
                                              mode_conteneur_actif, adresse_serveur_ntp,
                                              time_zone])
-    general.set_group_type('family')
+    general.set_group_type(groups.family)
     creole = OptionDescription('creole', 'first tiramisu configuration', [general, interface1])
     descr = OptionDescription('baseconfig', 'baseconifgdescr', [creole] )
     return descr
index e6e976c..1b69006 100644 (file)
@@ -26,7 +26,7 @@ from tiramisu.error import (PropertiesOptionError, ConfigError, NotFoundError,
     MandatoryError, MethodCallError, NoValueReturned)
 from tiramisu.option import (OptionDescription, Option, SymLinkOption,
     Multi, apply_requires)
-from tiramisu.setting import settings, group_types
+from tiramisu.setting import settings, groups
 
 # ____________________________________________________________
 class Config(object):
@@ -457,20 +457,24 @@ class Config(object):
         """iteration on groups objects only.
         All groups are returned if `group_type` is `None`, otherwise the groups
         can be filtered by categories (families, or whatever).
+        :param group_type: if defined, is an instance of `settings.GroupName`
+                           or `settings.MasterGroupName` that lives in
+                           `settings.groups`
+
         """
-        if group_type == None:
-            groups = group_types
-        else:
-            if group_type not in group_types:
+        if group_type is not None:
+            if not isinstance(group_type, groups.GroupName):
                 raise TypeError("Unknown group_type: {0}".format(group_type))
-            groups = [group_type]
         for child in self._cfgimpl_descr._children:
             if isinstance(child, OptionDescription):
                 try:
-                    if child.get_group_type() in groups:
+                    if group_type is not None:
+                        if child.get_group_type() == group_type:
+                            yield child._name, getattr(self, child._name)
+                    else:
                         yield child._name, getattr(self, child._name)
                 except:
-                    pass # hidden, disabled option
+                    pass
     # ______________________________________________________________________
     def __str__(self):
         "Config's string representation"
index 726b848..b5ca031 100644 (file)
@@ -26,7 +26,7 @@ from tiramisu.error import (ConfigError, ConflictConfigError, NotFoundError,
     RequiresError, RequirementRecursionError, MandatoryError,
     PropertiesOptionError)
 from tiramisu.autolib import carry_out_calculation
-from tiramisu.setting import settings, group_types, groups_has_master
+from tiramisu.setting import settings, groups
 
 requires_actions = [('hide', 'show'), ('enable', 'disable'), ('freeze', 'unfreeze')]
 
@@ -470,9 +470,9 @@ class NetmaskOption(Option):
         return isinstance(value, str)
 
 class OptionDescription(HiddenBaseType, DisabledBaseType):
-    "Config's schema (organisation) and container of Options"
-    "the group_type is an attribute useful for iteration on groups in a config"
-    group_type = 'default'
+    """Config's schema (organisation, group) and container of Options"""
+    # the group_type is useful for filtering OptionDescriptions in a config
+    group_type = groups.default
     def __init__(self, name, doc, children, requires=None):
         """
         :param children: is a list of option descriptions (including
@@ -485,7 +485,7 @@ class OptionDescription(HiddenBaseType, DisabledBaseType):
         self._build()
         self.properties = [] # 'hidden', 'disabled'...
         # if this group is a master group, master is set
-        # to the master option name
+        # to the master option name. it's just a ref to a name
         self.master = None
 
     def getdoc(self):
@@ -538,10 +538,14 @@ class OptionDescription(HiddenBaseType, DisabledBaseType):
         return paths
     # ____________________________________________________________
     def set_group_type(self, group_type, master=None):
-        ":param group_type: string in group_types"
-        if group_type in group_types:
+        """sets a given group object to an OptionDescription
+
+        :param group_type: an instance of `GroupName` or `MasterGroupName`
+                              that lives in `setting.groups`
+        """
+        if isinstance(group_type, groups.GroupName):
             self.group_type = group_type
-            if group_type in groups_has_master:
+            if isinstance(group_type, groups.MasterGroupName):
                 if master is None:
                     raise ConfigError('this group type ({0}) needs a master '
                             'for OptionDescription {1}'.format(group_type,
@@ -553,8 +557,7 @@ class OptionDescription(HiddenBaseType, DisabledBaseType):
                                 group_type, self._name))
             self.master = master
         else:
-            raise ConfigError('not allowed value for group_type : {0}'.format(
-                              group_type))
+            raise ConfigError('not allowed group_type : {0}'.format(group_type))
 
     def get_group_type(self):
         return self.group_type
index c2140a9..2bc3a9f 100644 (file)
 # the whole pypy projet is under MIT licence
 # ____________________________________________________________
 
-# available group_type values
-_group_name = ('default', 'family', 'group')
-groups_has_master = ('group', )
-class Group(str): pass
-group_types = tuple(Group(i) for i in _group_name)
+class _const:
+    """convenient class that emulates a module
+    and builds constants (that is, unique group names)"""
+    class GroupError(TypeError): pass
+
+    def __setattr__(self, name, value):
+        if self.__dict__.has_key(name):
+            raise self.GroupError, "Can't rebind group (%s)"%name
+        self.__dict__[name] = value
+
+    def __delattr__(self, name):
+        if self.__dict__.has_key(name):
+            raise self.GroupError, "Can't unbind group (%s)"%name
+        raise NameError, name
+
+groups = _const()
+def populate_groups():
+    "populates the available groups in the appropriate namespaces"
+    _available_group_names = ('default', 'family', 'group')
+    _available_groups_with_a_master = ('group', )
+    class GroupName(str):
+        """allowed normal group (OptionDescription) names
+        *normal* means : groups that are not master
+        """
+        pass
+
+    class MasterGroupName(GroupName):
+        """allowed normal group (OptionDescription) names
+        *master* means : groups that have the 'master' attribute set
+        """
+        pass
+
+    groups.GroupName = GroupName
+    groups.MasterGroupName = MasterGroupName
+    # populates normal or master groups
+    for grp in _available_group_names:
+        if grp in _available_groups_with_a_master:
+            setattr(groups, grp, MasterGroupName(grp))
+        else:
+            setattr(groups, grp, GroupName(grp))
+
+populate_groups()
+# ____________________________________________________________
 
 class Setting():
     "``Config()``'s configuration options"
index 9f082bf..c2493de 100644 (file)
@@ -20,7 +20,7 @@
 from tiramisu.config import Config
 from tiramisu.option import (OptionDescription, Option, ChoiceOption, BoolOption,
                     FloatOption, StrOption, IntOption, IPOption, NetmaskOption,
-                    group_types, apply_requires)
+                    apply_requires)
 
 # ____________________________________________________________
 # reverse factory