Mercurial > hgrepos > Python > libs > ConfigMix
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 |
