##// END OF EJS Templates
cleanup Config attributes...
MinRK -
Show More
@@ -163,14 +163,19 b' class LazyConfigValue(HasTraits):'
163 return d
163 return d
164
164
165
165
166 def _is_section_key(key):
167 """Is a Config key a section name (does it start with a capital)?"""
168 if key and key[0].upper()==key[0] and not key.startswith('_'):
169 return True
170 else:
171 return False
172
173
166 class Config(dict):
174 class Config(dict):
167 """An attribute based dict that can do smart merges."""
175 """An attribute based dict that can do smart merges."""
168
176
169 def __init__(self, *args, **kwds):
177 def __init__(self, *args, **kwds):
170 dict.__init__(self, *args, **kwds)
178 dict.__init__(self, *args, **kwds)
171 # This sets self.__dict__ = self, but it has to be done this way
172 # because we are also overriding __setattr__.
173 dict.__setattr__(self, '__dict__', self)
174 self._ensure_subconfig()
179 self._ensure_subconfig()
175
180
176 def _ensure_subconfig(self):
181 def _ensure_subconfig(self):
@@ -181,10 +186,10 b' class Config(dict):'
181 """
186 """
182 for key in self:
187 for key in self:
183 obj = self[key]
188 obj = self[key]
184 if self._is_section_key(key) \
189 if _is_section_key(key) \
185 and isinstance(obj, dict) \
190 and isinstance(obj, dict) \
186 and not isinstance(obj, Config):
191 and not isinstance(obj, Config):
187 dict.__setattr__(self, key, Config(obj))
192 setattr(self, key, Config(obj))
188
193
189 def _merge(self, other):
194 def _merge(self, other):
190 """deprecated alias, use Config.merge()"""
195 """deprecated alias, use Config.merge()"""
@@ -206,12 +211,6 b' class Config(dict):'
206
211
207 self.update(to_update)
212 self.update(to_update)
208
213
209 def _is_section_key(self, key):
210 if key[0].upper()==key[0] and not key.startswith('_'):
211 return True
212 else:
213 return False
214
215 def __contains__(self, key):
214 def __contains__(self, key):
216 # allow nested contains of the form `"Section.key" in config`
215 # allow nested contains of the form `"Section.key" in config`
217 if '.' in key:
216 if '.' in key:
@@ -221,7 +220,7 b' class Config(dict):'
221 return remainder in self[first]
220 return remainder in self[first]
222
221
223 # we always have Sections
222 # we always have Sections
224 if self._is_section_key(key):
223 if _is_section_key(key):
225 return True
224 return True
226 else:
225 else:
227 return super(Config, self).__contains__(key)
226 return super(Config, self).__contains__(key)
@@ -229,11 +228,11 b' class Config(dict):'
229 has_key = __contains__
228 has_key = __contains__
230
229
231 def _has_section(self, key):
230 def _has_section(self, key):
232 if self._is_section_key(key):
231 if _is_section_key(key):
233 if super(Config, self).__contains__(key):
232 if super(Config, self).__contains__(key):
234 return True
233 return True
235 return False
234 return False
236
235
237 def copy(self):
236 def copy(self):
238 return type(self)(dict.copy(self))
237 return type(self)(dict.copy(self))
239
238
@@ -245,20 +244,7 b' class Config(dict):'
245 return type(self)(copy.deepcopy(list(self.items())))
244 return type(self)(copy.deepcopy(list(self.items())))
246
245
247 def __getitem__(self, key):
246 def __getitem__(self, key):
248 # We cannot use directly self._is_section_key, because it triggers
247 if _is_section_key(key):
249 # infinite recursion on top of PyPy. Instead, we manually fish the
250 # bound method.
251 is_section_key = self.__class__._is_section_key.__get__(self)
252
253 # Because we use this for an exec namespace, we need to delegate
254 # the lookup of names in __builtin__ to itself. This means
255 # that you can't have section or attribute names that are
256 # builtins.
257 try:
258 return getattr(builtin_mod, key)
259 except AttributeError:
260 pass
261 if is_section_key(key):
262 try:
248 try:
263 return dict.__getitem__(self, key)
249 return dict.__getitem__(self, key)
264 except KeyError:
250 except KeyError:
@@ -269,36 +255,37 b' class Config(dict):'
269 try:
255 try:
270 return dict.__getitem__(self, key)
256 return dict.__getitem__(self, key)
271 except KeyError:
257 except KeyError:
272 if key.startswith('__'):
273 # don't create LazyConfig on special method requests
274 raise
275 # undefined, create lazy value, used for container methods
258 # undefined, create lazy value, used for container methods
276 v = LazyConfigValue()
259 v = LazyConfigValue()
277 dict.__setitem__(self, key, v)
260 dict.__setitem__(self, key, v)
278 return v
261 return v
279
280
262
281 def __setitem__(self, key, value):
263 def __setitem__(self, key, value):
282 if self._is_section_key(key):
264 if _is_section_key(key):
283 if not isinstance(value, Config):
265 if not isinstance(value, Config):
284 raise ValueError('values whose keys begin with an uppercase '
266 raise ValueError('values whose keys begin with an uppercase '
285 'char must be Config instances: %r, %r' % (key, value))
267 'char must be Config instances: %r, %r' % (key, value))
286 else:
268 dict.__setitem__(self, key, value)
287 dict.__setitem__(self, key, value)
288
269
289 def __getattr__(self, key):
270 def __getattr__(self, key):
271 if key.startswith('__'):
272 return dict.__getattr__(self, key)
290 try:
273 try:
291 return self.__getitem__(key)
274 return self.__getitem__(key)
292 except KeyError as e:
275 except KeyError as e:
293 raise AttributeError(e)
276 raise AttributeError(e)
294
277
295 def __setattr__(self, key, value):
278 def __setattr__(self, key, value):
279 if key.startswith('__'):
280 return dict.__setattr__(self, key, value)
296 try:
281 try:
297 self.__setitem__(key, value)
282 self.__setitem__(key, value)
298 except KeyError as e:
283 except KeyError as e:
299 raise AttributeError(e)
284 raise AttributeError(e)
300
285
301 def __delattr__(self, key):
286 def __delattr__(self, key):
287 if key.startswith('__'):
288 return dict.__delattr__(self, key)
302 try:
289 try:
303 dict.__delitem__(self, key)
290 dict.__delitem__(self, key)
304 except KeyError as e:
291 except KeyError as e:
General Comments 0
You need to be logged in to leave comments. Login now