Mercurial > hgrepos > Python > libs > ConfigMix
comparison configmix/config.py @ 320:98490375d90c
Allow variable name quoting to be used in .getvar() and .getvar_s() and references
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Thu, 06 May 2021 09:45:51 +0200 |
| parents | 043a6412be3c |
| children | 7a0f3c256cf4 |
comparison
equal
deleted
inserted
replaced
| 319:5427ca342c1e | 320:98490375d90c |
|---|---|
| 26 from urllib.parse import urlsplit | 26 from urllib.parse import urlsplit |
| 27 except ImportError: | 27 except ImportError: |
| 28 from urlparse import urlsplit | 28 from urlparse import urlsplit |
| 29 | 29 |
| 30 from .variables import lookup_varns, lookup_filter | 30 from .variables import lookup_varns, lookup_filter |
| 31 from .compat import u | 31 from .compat import u, uchr |
| 32 from .constants import REF_NAMESPACE | 32 from .constants import REF_NAMESPACE |
| 33 | 33 |
| 34 | 34 |
| 35 _MARKER = object() | 35 _MARKER = object() |
| 36 | 36 |
| 68 _NS_SEPARATOR = u(b':') | 68 _NS_SEPARATOR = u(b':') |
| 69 _FILTER_SEPARATOR = u(b'|') | 69 _FILTER_SEPARATOR = u(b'|') |
| 70 _STARTTOK_REF = _STARTTOK + REF_NAMESPACE + _NS_SEPARATOR | 70 _STARTTOK_REF = _STARTTOK + REF_NAMESPACE + _NS_SEPARATOR |
| 71 _ENDTOK_REF = _ENDTOK | 71 _ENDTOK_REF = _ENDTOK |
| 72 _DOT = u(b'.') | 72 _DOT = u(b'.') |
| 73 _QUOTE = u(b'%') | |
| 73 | 74 |
| 74 def getvarl(self, *names, default=_MARKER, namespace=None): | 75 def getvarl(self, *names, default=_MARKER, namespace=None): |
| 75 """Get a variable where the hierarchy is given in `names` as sequence | 76 """Get a variable where the hierarchy is given in `names` as sequence |
| 76 and the namespace is given in `namespace`. | 77 and the namespace is given in `namespace`. |
| 77 | 78 |
| 102 No variable interpolation is done and no filters are applied. | 103 No variable interpolation is done and no filters are applied. |
| 103 | 104 |
| 104 """ | 105 """ |
| 105 varns, varname = self._split_ns(varname) | 106 varns, varname = self._split_ns(varname) |
| 106 if not varns: | 107 if not varns: |
| 107 varnameparts = varname.split(self._HIER_SEPARATOR) | 108 varnameparts = [self.unquote(vp) for vp in varname.split(self._HIER_SEPARATOR)] |
| 108 else: | 109 else: |
| 109 varnameparts = (varname,) | 110 varnameparts = (varname,) |
| 110 return self.getvarl(*varnameparts, namespace=varns) | 111 return self.getvarl(*varnameparts, namespace=varns) |
| 111 | 112 |
| 112 def getvarl_s(self, *names, default=_MARKER, namespace=None): | 113 def getvarl_s(self, *names, default=_MARKER, namespace=None): |
| 363 # | 364 # |
| 364 raise NameError("Filter %r not found" % name) | 365 raise NameError("Filter %r not found" % name) |
| 365 else: | 366 else: |
| 366 value = filterfn(self, value) | 367 value = filterfn(self, value) |
| 367 return value | 368 return value |
| 369 | |
| 370 @classmethod | |
| 371 def quote(klass, s): | |
| 372 """Quote a key to protect all dangerous chars: ``%``, ``.``, ``:`` | |
| 373 and ``|`` | |
| 374 | |
| 375 """ | |
| 376 qc = klass._QUOTE | |
| 377 s = s.replace(qc, qc + "x25") | |
| 378 s = s.replace(klass._DOT, qc + "x2e") | |
| 379 s = s.replace(klass._NS_SEPARATOR, qc + "x3a") | |
| 380 return s.replace(klass._FILTER_SEPARATOR, qc + "x7c") | |
| 381 | |
| 382 @classmethod | |
| 383 def unquote(klass, s): | |
| 384 """Unquote the content of `s`: handle all patterns ``%xXX``, | |
| 385 ``%uXXXX`` or `%UXXXXXXXX`` | |
| 386 | |
| 387 """ | |
| 388 if klass._QUOTE not in s: | |
| 389 return s | |
| 390 res = [] | |
| 391 parts = s.split(klass._QUOTE) | |
| 392 res.append(parts[0]) | |
| 393 for p in parts[1:]: | |
| 394 if p.startswith(u(b'x')): | |
| 395 if len(p) < 3: | |
| 396 raise ValueError("quote syntax: length too small") | |
| 397 res.append(uchr(int(p[1:3], 16))) | |
| 398 res.append(p[3:]) | |
| 399 elif p.startswith(u(b'u')): | |
| 400 if len(p) < 5: | |
| 401 raise ValueError("quote syntax: length too small") | |
| 402 res.append(uchr(int(p[1:5], 16))) | |
| 403 res.append(p[5:]) | |
| 404 elif p.startswith(u(b'U')): | |
| 405 if len(p) < 9: | |
| 406 raise ValueError("quote syntax: length too small") | |
| 407 res.append(uchr(int(p[1:9], 16))) | |
| 408 res.append(p[9:]) | |
| 409 else: | |
| 410 raise ValueError("unknown quote syntax string: {}".format(s)) | |
| 411 return ''.join(res) |
