works on performante
[tiramisu.git] / tiramisu / setting.py
1 # -*- coding: utf-8 -*-
2 "sets the options of the configuration objects Config object itself"
3 # Copyright (C) 2012-2013 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     groups.master = groups.MasterGroupType('master')
60     groups.default = groups.DefaultGroupType('default')
61     groups.family = groups.GroupType('family')
62
63 # names are in the module now
64 populate_groups()
65 # ____________________________________________________________
66 class OwnerModule(_const):
67     """emulates a module to manage unique owner names.
68
69     owners are living in `Config._cfgimpl_value_owners`
70     """
71     class Owner(str):
72         """allowed owner names
73         """
74         pass
75     class DefaultOwner(Owner):
76         """groups that are default (typically 'default')"""
77         pass
78 # setting.owners (emulates a module)
79 owners = OwnerModule()
80
81 def populate_owners():
82     """populates the available owners in the appropriate namespaces
83
84     - 'user' is the generic is the generic owner.
85     - 'default' is the config owner after init time
86     """
87     setattr(owners, 'default', owners.DefaultOwner('default'))
88     setattr(owners,'user', owners.Owner('user'))
89     def add_owner(name):
90         """
91         :param name: the name of the new owner
92         """
93         setattr(owners, name, owners.Owner(name))
94     setattr(owners, 'add_owner', add_owner)
95
96 # names are in the module now
97 populate_owners()
98
99 class MultiTypeModule(_const):
100     class MultiType(str):
101         pass
102     class DefaultMultiType(MultiType):
103         pass
104     class MasterMultiType(MultiType):
105         pass
106     class SlaveMultiType(MultiType):
107         pass
108
109 multitypes = MultiTypeModule()
110
111 def populate_multitypes():
112     setattr(multitypes, 'default', multitypes.DefaultMultiType('default'))
113     setattr(multitypes, 'master', multitypes.MasterMultiType('master'))
114     setattr(multitypes, 'slave', multitypes.SlaveMultiType('slave'))
115
116 populate_multitypes()
117
118 #____________________________________________________________
119 class Setting():
120     "``Config()``'s configuration options"
121     # properties attribute: the name of a property enables this property
122     properties = ['hidden', 'disabled']
123     # overrides the validations in the acces of the option values
124     permissive = []
125     # a mandatory option must have a value that is not None
126     mandatory = True
127     frozen = True
128     # enables validation function for options if set
129     validator = False
130     # generic owner
131     owner = owners.user
132     # in order to freeze everything, not **only** the frozen options
133     everything_frozen = False
134     # enables at build time to raise an exception if the option's name
135     # has the name of a config's method
136     valid_opt_names = True
137     #____________________________________________________________
138     # properties methods
139     def has_properties(self):
140         "has properties means the Config's properties attribute is not empty"
141         return bool(len(self.properties))
142
143
144     def get_properties(self):
145         return self.properties
146
147     def has_property(self, propname):
148         """has property propname in the Config's properties attribute
149         :param property: string wich is the name of the property"""
150         return propname in self.properties
151
152     def enable_property(self, propname):
153         "puts property propname in the Config's properties attribute"
154         if propname not in self.properties:
155             self.properties.append(propname)
156
157     def disable_property(self, propname):
158         "deletes property propname in the Config's properties attribute"
159         if self.has_property(propname):
160             self.properties.remove(propname)
161     #____________________________________________________________
162     def get_permissive(self):
163         return self.permissive
164
165     def set_permissive(self, permissive):
166         if not isinstance(permissive, list):
167             raise TypeError('permissive must be a list')
168         self.permissive = permissive
169     #____________________________________________________________
170     # complete freeze methods
171     def freeze_everything(self):
172         """everything is frozen, not only the option that are tagged "frozen"
173         """
174         self.everything_frozen = True
175
176     def un_freeze_everything(self):
177         """everything is frozen, not only the option that are tagged "frozen"
178         """
179         self.everything_frozen = False
180
181     def is_frozen_for_everything(self):
182         """frozen for a whole config (not only the options
183         that have been set to frozen)"""
184         return self.everything_frozen
185     #____________________________________________________________
186     def read_only(self):
187         "convenience method to freeze, hidde and disable"
188         self.freeze_everything()
189         self.freeze() # can be usefull...
190         self.disable_property('hidden')
191         self.enable_property('disabled')
192         self.mandatory = True
193         self.validator = True
194
195     def read_write(self):
196         "convenience method to freeze, hidde and disable"
197         self.un_freeze_everything()
198         self.freeze()
199         self.enable_property('hidden')
200         self.enable_property('disabled')
201         self.mandatory = False
202         self.validator = False
203
204     def non_mandatory(self):
205         """mandatory at the Config level means that the Config raises an error
206         if a mandatory option is found"""
207         self.mandatory = False
208
209     def mandatory(self):
210         """mandatory at the Config level means that the Config raises an error
211         if a mandatory option is found"""
212         self.mandatory = True
213
214     def is_mandatory(self):
215         "all mandatory Options shall have a value"
216         return self.mandatory
217
218     def freeze(self):
219         "cannot modify the frozen `Option`'s"
220         self.frozen = True
221
222     def unfreeze(self):
223         "can modify the Options that are frozen"
224         self.frozen = False
225
226     def is_frozen(self):
227         "freeze flag at Config level"
228         return self.frozen
229
230     def setowner(self, owner):
231         ":param owner: sets the default value for owner at the Config level"
232         if not isinstance(owner, owners.Owner):
233             raise TypeError("invalid generic owner {0}".format(str(owner)))
234         self.owner = owner
235
236     def getowner(self):
237         return self.owner