3798ba7cc6779880dc0b32cc2fa6f65051d97965
[tiramisu.git] / tiramisu / setting.py
1 # -*- coding: utf-8 -*-
2 "sets the options of the configuration objects Config object itself"
3 # Copyright (C) 2012 Team tiramisu (see AUTHORS for all contributors)
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 #
19 # The original `Config` design model is unproudly borrowed from
20 # the rough pypy's guys: http://codespeak.net/svn/pypy/dist/pypy/config/
21 # the whole pypy projet is under MIT licence
22 # ____________________________________________________________
23 class _const:
24     """convenient class that emulates a module
25     and builds constants (that is, unique names)"""
26     class ConstError(TypeError): pass
27
28     def __setattr__(self, name, value):
29         if self.__dict__.has_key(name):
30             raise self.ConstError, "Can't rebind group (%s)"%name
31         self.__dict__[name] = value
32
33     def __delattr__(self, name):
34         if self.__dict__.has_key(name):
35             raise self.ConstError, "Can't unbind group (%s)"%name
36         raise NameError, name
37 # ____________________________________________________________
38 class GroupModule(_const):
39     "emulates a module to manage unique group (OptionDescription) names"
40     class GroupType(str):
41         """allowed normal group (OptionDescription) names
42         *normal* means : groups that are not master
43         """
44         pass
45     class DefaultGroupType(GroupType):
46         """groups that are default (typically 'default')"""
47         pass
48
49     class MasterGroupType(GroupType):
50         """allowed normal group (OptionDescription) names
51         *master* means : groups that have the 'master' attribute set
52         """
53         pass
54 # setting.groups (emulates a module)
55 groups = GroupModule()
56
57 def populate_groups():
58     "populates the available groups in the appropriate namespaces"
59     _available_group_names = ('default', 'family', 'group')
60     _available_groups_with_a_master = ('group', )
61     _available_default_groups = ('default', )
62     # populates normal or master groups
63     for grp in _available_group_names:
64         if grp in _available_groups_with_a_master:
65             setattr(groups, grp, groups.MasterGroupType(grp))
66         elif grp in _available_default_groups:
67             setattr(groups, grp, groups.DefaultGroupType(grp))
68         else:
69             setattr(groups, grp, groups.GroupType(grp))
70 # names are in the module now
71 populate_groups()
72 # ____________________________________________________________
73 class OwnerModule(_const):
74     """emulates a module to manage unique owner names.
75
76     owners are living in `Config._cfgimpl_value_owners`
77     """
78     class Owner(str):
79         """allowed owner names
80         """
81         pass
82     class DefaultOwner(Owner):
83         """groups that are default (typically 'default')"""
84         pass
85 # setting.owners (emulates a module)
86 owners = OwnerModule()
87
88 def populate_owners():
89     """populates the available owners in the appropriate namespaces
90
91     - 'user' is the generic is the generic owner.
92     - 'default' is the config owner after init time
93     """
94     setattr(owners, 'default', owners.DefaultOwner('default'))
95     setattr(owners,'user', owners.Owner('user'))
96     def add_owner(name):
97         """
98         :param name: the name of the new owner
99         """
100         setattr(owners, name, owners.Owner(name))
101     setattr(owners, 'add_owner', add_owner)
102
103 # names are in the module now
104 populate_owners()
105 #____________________________________________________________
106 class Setting():
107     "``Config()``'s configuration options"
108     # properties attribute: the name of a property enables this property
109     properties = ['hidden', 'disabled']
110     # overrides the validations in the acces of the option values
111     permissive = []
112     # a mandatory option must have a value that is not None
113     mandatory = True
114     frozen = True
115     # enables validation function for options if set
116     validator = False
117    # generic owner
118     owner = owners.user
119
120     #____________________________________________________________
121     # properties methods
122     def has_properties(self):
123         "has properties means the Config's properties attribute is not empty"
124         return bool(len(self.properties))
125
126     def has_property(self, propname):
127         """has property propname in the Config's properties attribute
128         :param property: string wich is the name of the property"""
129         return propname in self.properties
130
131     def enable_property(self, propname):
132         "puts property propname in the Config's properties attribute"
133         if propname not in self.properties:
134             self.properties.append(propname)
135
136     def disable_property(self, propname):
137         "deletes property propname in the Config's properties attribute"
138         if self.has_property(propname):
139             self.properties.remove(propname)
140     #____________________________________________________________
141     def set_permissive(self, permissive):
142         if not isinstance(permissive, list):
143             raise TypeError('permissive must be a list')
144         self.permissive = permissive
145
146     def read_only(self):
147         "convenience method to freeze, hidde and disable"
148         # FIXME LE FREEZE NE MARCHE PAS
149         self.freeze()
150         self.disable_property('hidden')
151         self.enable_property('disabled')
152         self.mandatory = True
153         self.validator = True
154
155     def read_write(self):
156         "convenience method to freeze, hidde and disable"
157         # FIXME : POURQUOI UN FREEZE ICI ?
158         self.freeze()
159         self.enable_property('hidden')
160         self.enable_property('disabled')
161         self.mandatory = False
162         self.validator = False
163
164     def non_mandatory(self):
165         """mandatory at the Config level means that the Config raises an error
166         if a mandatory option is found"""
167         self.mandatory = False
168
169     def mandatory(self):
170         """mandatory at the Config level means that the Config raises an error
171         if a mandatory option is found"""
172         self.mandatory = True
173
174     def is_mandatory(self):
175         "all mandatory Options shall have a value"
176         return self.mandatory
177
178     def freeze(self):
179         "cannot modify the frozen `Option`'s"
180         self.frozen = True
181
182     def unfreeze(self):
183         "can modify the Options that are frozen"
184         self.frozen = False
185
186     def is_frozen(self):
187         "freeze flag at Config level"
188         return self.frozen
189
190     def set_owner(self, owner):
191         ":param owner: sets the default value for owner at the Config level"
192         if not isinstance(owner, owners.Owner):
193             raise TypeError("invalid generic owner {0}".format(str(owner)))
194         self.owner = owner
195
196     def get_owner(self):
197         return self.owner
198
199 # Setting is actually a singleton
200 settings = Setting()