comparison configmix/config.py @ 412:816327e178b0

Provide coercing methods for the jailed configuration: getintXXX(), getboolXXX(), getfloatXXX() and friends. This is done be refactoring Configuration and putting the coercing methods into a common mixin.
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 20 Nov 2021 13:52:08 +0100
parents 3c95faa91dad
children 2abde0d3c735
comparison
equal deleted inserted replaced
411:3c95faa91dad 412:816327e178b0
48 return _AttributeDict(v) 48 return _AttributeDict(v)
49 else: 49 else:
50 return v 50 return v
51 51
52 52
53 class Configuration(_AttributeDict): 53 class CoercingMethodsMixin(object):
54
55 """Mixin to provide some common implementations for retrieval
56 methods that convert return values to a fixed type (int, bool,
57 float).
58
59 Both :class:`~.Configuration` and :class:`~._JailedConfiguration` use
60 this mixin.
61
62 """
63
64 def getintvarl_s(self, *path, **kwds):
65 """Get a (possibly substituted) variable and coerce text to a
66 number.
67
68 """
69 s = self.getvarl_s(*path, **kwds)
70 if isinstance(s, Configuration._TEXTTYPE):
71 return int(s, 0)
72 else:
73 return s
74
75 def getfirstintvarl_s(self, *paths, **kwds):
76 """Get a (possibly substituted) variable and coerce text to a
77 number.
78
79 """
80 s = self.getfirstvarl_s(*paths, **kwds)
81 if isinstance(s, Configuration._TEXTTYPE):
82 return int(s, 0)
83 else:
84 return s
85
86 def getintvar_s(self, varname, default=_MARKER):
87 """Get a (possibly substituted) variable and coerce text to a
88 number.
89
90 """
91 s = self.getvar_s(varname, default=default)
92 if isinstance(s, Configuration._TEXTTYPE):
93 return int(s, 0)
94 else:
95 return s
96
97 def getfirstintvar_s(self, *varnames, **kwds):
98 """A variant of :meth:`~.getintvar_s` that returns the first found
99 variable in the list of given variables in `varnames`.
100
101 """
102 s = self.getfirstvar_s(*varnames, **kwds)
103 if isinstance(s, Configuration._TEXTTYPE):
104 return int(s, 0)
105 else:
106 return s
107
108 def getboolvarl_s(self, *path, **kwds):
109 """Get a (possibly substituted) variable and convert text to a
110 boolean
111
112 """
113 s = self.getvarl_s(*path, **kwds)
114 if isinstance(s, Configuration._TEXTTYPE):
115 sl = s.strip().lower()
116 if sl not in self._BOOL_CVT:
117 raise ValueError("Not a boolean: %r" % s)
118 return self._BOOL_CVT[sl]
119 else:
120 return s
121
122 def getfirstboolvarl_s(self, *paths, **kwds):
123 """Get a (possibly substituted) variable and convert text to a
124 boolean
125
126 """
127 s = self.getfirstvarl_s(*paths, **kwds)
128 if isinstance(s, Configuration._TEXTTYPE):
129 sl = s.strip().lower()
130 if sl not in self._BOOL_CVT:
131 raise ValueError("Not a boolean: %r" % s)
132 return self._BOOL_CVT[sl]
133 else:
134 return s
135
136 def getboolvar_s(self, varname, default=_MARKER):
137 """Get a (possibly substituted) variable and convert text to a
138 boolean
139
140 """
141 s = self.getvar_s(varname, default=default)
142 if isinstance(s, Configuration._TEXTTYPE):
143 sl = s.strip().lower()
144 if sl not in self._BOOL_CVT:
145 raise ValueError("Not a boolean: %r" % s)
146 return self._BOOL_CVT[sl]
147 else:
148 return s
149
150 def getfirstboolvar_s(self, *varnames, **kwds):
151 """A variant of :meth:`~.getboolvar_s` that returns the first found
152 variable in the list of given variables in `varnames`.
153
154 """
155 s = self.getfirstvar_s(*varnames, **kwds)
156 if isinstance(s, Configuration._TEXTTYPE):
157 sl = s.strip().lower()
158 if sl not in self._BOOL_CVT:
159 raise ValueError("Not a boolean: %r" % s)
160 return self._BOOL_CVT[sl]
161 else:
162 return s
163
164 # Conversion of booleans
165 _BOOL_CVT = {
166 u('1'): True, u('yes'): True, u('true'): True, u('on'): True,
167 u('0'): False, u('no'): False, u('false'): False, u('off'): False
168 }
169
170 def getfloatvarl_s(self, *path, **kwds):
171 """Get a (possibly substituted) variable and convert text to a
172 float
173
174 """
175 s = self.getvarl_s(*path, **kwds)
176 if isinstance(s, Configuration._TEXTTYPE):
177 return float(s)
178 else:
179 return s
180
181 def getfirstfloatvarl_s(self, *path, **kwds):
182 """Get a (possibly substituted) variable and convert text to a
183 float
184
185 """
186 s = self.getfirstvarl_s(*path, **kwds)
187 if isinstance(s, Configuration._TEXTTYPE):
188 return float(s)
189 else:
190 return s
191
192 def getfloatvar_s(self, varname, default=_MARKER):
193 """Get a (possibly substituted) variable and convert text to a
194 float
195
196 """
197 s = self.getvar_s(varname, default)
198 if isinstance(s, Configuration._TEXTTYPE):
199 return float(s)
200 else:
201 return s
202
203 def getfirstfloatvar_s(self, varname, default=_MARKER):
204 """Get a (possibly substituted) variable and convert text to a
205 float
206
207 """
208 s = self.getfirstvar_s(varname, default)
209 if isinstance(s, Configuration._TEXTTYPE):
210 return float(s)
211 else:
212 return s
213
214
215 class Configuration(CoercingMethodsMixin, _AttributeDict):
54 216
55 """The configuration dictionary with attribute support or 217 """The configuration dictionary with attribute support or
56 variable substitution. 218 variable substitution.
57 219
58 .. note:: When retrieving by attribute names variables will *not* 220 .. note:: When retrieving by attribute names variables will *not*
294 if default is _MARKER: 456 if default is _MARKER:
295 raise KeyError( 457 raise KeyError(
296 "none of the given variables found: %r" % (varnames,)) 458 "none of the given variables found: %r" % (varnames,))
297 else: 459 else:
298 return default 460 return default
299
300 def getintvarl_s(self, *path, **kwds):
301 """Get a (possibly substituted) variable and coerce text to a
302 number.
303
304 """
305 s = self.getvarl_s(*path, **kwds)
306 if isinstance(s, self._TEXTTYPE):
307 return int(s, 0)
308 else:
309 return s
310
311 def getfirstintvarl_s(self, *paths, **kwds):
312 """Get a (possibly substituted) variable and coerce text to a
313 number.
314
315 """
316 s = self.getfirstvarl_s(*paths, **kwds)
317 if isinstance(s, self._TEXTTYPE):
318 return int(s, 0)
319 else:
320 return s
321
322 def getintvar_s(self, varname, default=_MARKER):
323 """Get a (possibly substituted) variable and coerce text to a
324 number.
325
326 """
327 s = self.getvar_s(varname, default=default)
328 if isinstance(s, self._TEXTTYPE):
329 return int(s, 0)
330 else:
331 return s
332
333 def getfirstintvar_s(self, *varnames, **kwds):
334 """A variant of :meth:`~.getintvar_s` that returns the first found
335 variable in the list of given variables in `varnames`.
336
337 """
338 s = self.getfirstvar_s(*varnames, **kwds)
339 if isinstance(s, self._TEXTTYPE):
340 return int(s, 0)
341 else:
342 return s
343
344 def getboolvarl_s(self, *path, **kwds):
345 """Get a (possibly substituted) variable and convert text to a
346 boolean
347
348 """
349 s = self.getvarl_s(*path, **kwds)
350 if isinstance(s, self._TEXTTYPE):
351 sl = s.strip().lower()
352 if sl not in self._BOOL_CVT:
353 raise ValueError("Not a boolean: %r" % s)
354 return self._BOOL_CVT[sl]
355 else:
356 return s
357
358 def getfirstboolvarl_s(self, *paths, **kwds):
359 """Get a (possibly substituted) variable and convert text to a
360 boolean
361
362 """
363 s = self.getfirstvarl_s(*paths, **kwds)
364 if isinstance(s, self._TEXTTYPE):
365 sl = s.strip().lower()
366 if sl not in self._BOOL_CVT:
367 raise ValueError("Not a boolean: %r" % s)
368 return self._BOOL_CVT[sl]
369 else:
370 return s
371
372 def getboolvar_s(self, varname, default=_MARKER):
373 """Get a (possibly substituted) variable and convert text to a
374 boolean
375
376 """
377 s = self.getvar_s(varname, default=default)
378 if isinstance(s, self._TEXTTYPE):
379 sl = s.strip().lower()
380 if sl not in self._BOOL_CVT:
381 raise ValueError("Not a boolean: %r" % s)
382 return self._BOOL_CVT[sl]
383 else:
384 return s
385
386 def getfirstboolvar_s(self, *varnames, **kwds):
387 """A variant of :meth:`~.getboolvar_s` that returns the first found
388 variable in the list of given variables in `varnames`.
389
390 """
391 s = self.getfirstvar_s(*varnames, **kwds)
392 if isinstance(s, self._TEXTTYPE):
393 sl = s.strip().lower()
394 if sl not in self._BOOL_CVT:
395 raise ValueError("Not a boolean: %r" % s)
396 return self._BOOL_CVT[sl]
397 else:
398 return s
399
400 # Conversion of booleans
401 _BOOL_CVT = {
402 u('1'): True, u('yes'): True, u('true'): True, u('on'): True,
403 u('0'): False, u('no'): False, u('false'): False, u('off'): False
404 }
405
406 def getfloatvarl_s(self, *path, **kwds):
407 """Get a (possibly substituted) variable and convert text to a
408 float
409
410 """
411 s = self.getvarl_s(*path, **kwds)
412 if isinstance(s, self._TEXTTYPE):
413 return float(s)
414 else:
415 return s
416
417 def getfirstfloatvarl_s(self, *path, **kwds):
418 """Get a (possibly substituted) variable and convert text to a
419 float
420
421 """
422 s = self.getfirstvarl_s(*path, **kwds)
423 if isinstance(s, self._TEXTTYPE):
424 return float(s)
425 else:
426 return s
427
428 def getfloatvar_s(self, varname, default=_MARKER):
429 """Get a (possibly substituted) variable and convert text to a
430 float
431
432 """
433 s = self.getvar_s(varname, default)
434 if isinstance(s, self._TEXTTYPE):
435 return float(s)
436 else:
437 return s
438
439 def getfirstfloatvar_s(self, varname, default=_MARKER):
440 """Get a (possibly substituted) variable and convert text to a
441 float
442
443 """
444 s = self.getfirstvar_s(varname, default)
445 if isinstance(s, self._TEXTTYPE):
446 return float(s)
447 else:
448 return s
449 461
450 def _split_ns(self, s): 462 def _split_ns(self, s):
451 nameparts = s.split(self._NS_SEPARATOR, 1) 463 nameparts = s.split(self._NS_SEPARATOR, 1)
452 if len(nameparts) == 1: 464 if len(nameparts) == 1:
453 return (None, s, ) 465 return (None, s, )
691 if bind_root: 703 if bind_root:
692 jc.rebind(self) 704 jc.rebind(self)
693 return jc 705 return jc
694 706
695 707
696 class _JailedConfiguration(object): 708 class _JailedConfiguration(CoercingMethodsMixin):
697 709
698 """A jailed and restricted variant of :class:`Configuration`. 710 """A jailed and restricted variant of :class:`Configuration`.
699 711
700 Restriction is two-fold: 712 Restriction is two-fold:
701 713