changeset 483:38e4be1882e3

Optimize .quote() by using str.translate() instead of repeatedly calling str.replace()
author Franz Glasner <f.glasner@feldmann-mg.com>
date Fri, 17 Dec 2021 14:14:36 +0100
parents 8b8ffb74d452
children 0259bd521729
files configmix/config.py
diffstat 1 files changed, 27 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/configmix/config.py	Fri Dec 17 13:53:25 2021 +0100
+++ b/configmix/config.py	Fri Dec 17 14:14:36 2021 +0100
@@ -237,10 +237,23 @@
     _QUOTE_u = u(b'u')
     _QUOTE_U = u(b'U')
     _COMMENT = u(b'#')
+    _QUOTE_MAP = {
+        0x25: u(b'%x25'),    # _QUOTE
+        0x2e: u(b'%x2e'),    # _DOT
+        0x3a: u(b'%x3a'),    # _NS_SEPARATOR
+        0x23: u(b'%x23'),    # _COMMENT / anchor
+        0x7c: u(b'%x7c'),    # _FILTER_SEPARATOR
+        0x22: u(b'%x22'),
+        0x27: u(b'%x27'),
+        0x7b: u(b'%x7b'),
+        0x7d: u(b'%x7d'),
+        0x5b: u(b'%x5b'),
+        0x5d: u(b'%x5d'),
+    }
     _QUOTE_SAFE = u(b'abcdefghijklmnopqrstuvwxyz'
                     b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
                     b'0123456789'
-                    b'-_@!§$&/()=?*+~;,<>´`^')
+                    b'-_@!$&/\\()=?*+~;,<>^')
     """Mostly used configuration key characters that do not need any quoting
 
     """
@@ -707,22 +720,22 @@
         See also the :ref:`quoting` section.
 
         """
-        # Quick check whether all of the chars is in _QUOTE_SAFE
+        # Quick check whether all of the chars are in _QUOTE_SAFE
         if not s.rstrip(klass._QUOTE_SAFE):
             return s
+
         # Slow path
-        qc = klass._QUOTE
-        s = s.replace(qc, qc + "x25")
-        s = s.replace(klass._DOT, qc + "x2e")
-        s = s.replace(klass._NS_SEPARATOR, qc + "x3a")
-        s = s.replace(klass._COMMENT, qc + "x23")
-        s = s.replace(klass._FILTER_SEPARATOR, qc + "x7c")
-        s = s.replace('"', qc + "x22")
-        s = s.replace("'", qc + "x27")
-        s = s.replace('{', qc + "x7b")
-        s = s.replace('}', qc + "x7d")
-        s = s.replace('[', qc + "x5b")
-        return s.replace(']', qc + "x5d")
+        re_encode = False
+        if PY2:
+            # Use the Unicode translation variant in PY2
+            if isinstance(s, str):
+                s = s.decode("latin1")
+                re_encode = True
+        s = s.translate(klass._QUOTE_MAP)
+        if re_encode:
+            return s.encode("latin1")
+        else:
+            return s
 
     @classmethod
     def unquote(klass, s):