comparison configmix/config.py @ 542:f71d34dda19f

Add an optional C-implementation for configmix.config.unquote and configmix.config.pathstr2path. This is currently for Python 3.5+. It is tested with Python 3.7 and Python3.8 (FreeBSD 12.2 amd64, LLVM 10.0.1). A build for the stable API ("abi3") fails because PyUnicode_New() is currently not in the stable API. Also includes are extended tests for unquote() and pathstr2path().
author Franz Glasner <fzglas.hg@dom66.de>
date Fri, 31 Dec 2021 21:24:16 +0100
parents 25b61f0a1958
children 491413368c7c
comparison
equal deleted inserted replaced
541:25b61f0a1958 542:f71d34dda19f
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, uchr, n, str_and_u, PY2 31 from .compat import u, uchr, n, str_and_u, PY2
32 from .constants import REF_NAMESPACE, NONE_FILTER, EMPTY_FILTER 32 from .constants import REF_NAMESPACE, NONE_FILTER, EMPTY_FILTER
33 try:
34 from ._speedups import fast_unquote, fast_pathstr2path
35 except ImportError:
36 fast_unquote = None
37 fast_pathstr2path = None
33 38
34 39
35 _MARKER = object() 40 _MARKER = object()
36 _MISSING = object() 41 _MISSING = object()
37 42
278 return s.encode("latin1") 283 return s.encode("latin1")
279 else: 284 else:
280 return s 285 return s
281 286
282 287
283 def unquote(s): 288 def py_unquote(s):
284 """Unquote the content of `s`: handle all patterns ``%xNN``, 289 """Unquote the content of `s`: handle all patterns ``%xNN``,
285 ``%uNNNN`` or ``%UNNNNNNNN``. 290 ``%uNNNN`` or ``%UNNNNNNNN``.
286 291
287 This is the inverse of :func:`.quote`. 292 This is the inverse of :func:`.quote`.
288 293
315 else: 320 else:
316 raise ValueError("unknown quote syntax string: {}".format(s)) 321 raise ValueError("unknown quote syntax string: {}".format(s))
317 return _EMPTY_STR.join(res) 322 return _EMPTY_STR.join(res)
318 323
319 324
320 def pathstr2path(varname): 325 if fast_unquote:
326 unquote = fast_unquote
327 else:
328 unquote = py_unquote
329
330
331 def py_pathstr2path(varname):
321 """Parse a dot-separated path string `varname` into a tuple of 332 """Parse a dot-separated path string `varname` into a tuple of
322 unquoted path items 333 unquoted path items
323 334
324 :param str varname: The quoted and dot-separated path string 335 :param str varname: The quoted and dot-separated path string
325 :return: The unquoted and parsed path items 336 :return: The unquoted and parsed path items
343 return tuple([unquote(p) for p in varname.split(_HIER_SEPARATOR)]) 354 return tuple([unquote(p) for p in varname.split(_HIER_SEPARATOR)])
344 else: 355 else:
345 return tuple() 356 return tuple()
346 357
347 358
359 if fast_pathstr2path:
360 pathstr2path = fast_pathstr2path
361 else:
362 pathstr2path = py_pathstr2path
363
364
348 def _split_ns(varname): 365 def _split_ns(varname):
349 """Split the variable name string `varname` into the namespace and 366 """Split the variable name string `varname` into the namespace and
350 the namespace-specific name 367 the namespace-specific name
351 368
352 :type varname: str 369 :type varname: str
353 :return: A tuple containing the namespace (or `None`) and the 370 :return: A tuple containing the namespace (or `None`) and the
354 namespace-specific (variable-)name 371 namespace-specific (variable-)name
355 :rtype: tuple(str or None, str) 372 :rtype: tuple(str or None, str)
356 373
357 """ 374 """
358
359 ns, sep, rest = varname.partition(_NS_SEPARATOR) 375 ns, sep, rest = varname.partition(_NS_SEPARATOR)
360 if sep: 376 if sep:
361 return (unquote(ns), rest) 377 return (unquote(ns), rest)
362 else: 378 else:
363 return (None, ns) 379 return (None, ns)
364 380
365 381
366 def _split_filters(varname): 382 def _split_filters(varname):
367 """Split off the filter part from the `varname` string 383 """Split off the filter part from the `varname` string
368 384
369 :type varname: str 385 :type varname: str
370 :return: The tuple of the variable name without the filters and a list 386 :return: The tuple of the variable name without the filters and a list
371 of filters 387 of filters
372 :rtype: tuple(str, list) 388 :rtype: tuple(str, list)
373 389
374 """ 390 """