You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Merge pull request #45 from techouse/chore/optimize-encoder-some-more
* [CHORE] optimize `encode` hot paths with lower-overhead iterative traversal, cheaper container checks, and deep linear mapping fast paths
* [CHORE] optimize `EncodeUtils` ASCII/BMP handling and `KeyPathNode` path materialization caching for repeated encode workloads
* [FIX] preserve legacy `max_depth` vs circular-reference error precedence in both generic and fast-path encoding
* [FIX] keep `EncodeOptions` free of encode-time mutable cache state while preserving encoder/equality behavior
* [CHORE] expand encode regression coverage for deep nesting, cycle handling, key-path caching, and `EncodeOptions` semantics
Copy file name to clipboardExpand all lines: src/qs_codec/utils/decode_utils.py
+12-12Lines changed: 12 additions & 12 deletions
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,10 @@
1
-
"""Utilities for decoding percent‑encoded query strings and splitting composite keys into bracketed path segments.
1
+
"""Utilities for decoding percent-encoded query strings and splitting composite keys into bracketed path segments.
2
2
3
3
This mirrors the semantics of the Node `qs` library:
4
4
5
-
- Decoding handles both UTF‑8 and Latin‑1 code paths.
5
+
- Decoding handles both UTF-8 and Latin-1 code paths.
6
6
- Key splitting keeps bracket groups *balanced* and optionally treats dots as path separators when ``allow_dots=True``.
7
-
- Top‑level dot splitting uses a character‑scanner that handles degenerate cases (leading '.' starts a bracket segment; '.[' is skipped; double dots preserve the first; trailing '.' is preserved) and never treats literal percent‑encoded sequences (e.g., '%2E') as split points; only actual '.' characters at depth 0 are split.
7
+
- Top-level dot splitting uses a character-scanner that handles degenerate cases (leading '.' starts a bracket segment; '.[' is skipped; double dots preserve the first; trailing '.' is preserved) and never treats literal percent-encoded sequences (e.g., '%2E') as split points; only actual '.' characters at depth 0 are split.
8
8
"""
9
9
10
10
importre
@@ -22,7 +22,7 @@ class DecodeUtils:
22
22
the compiled regular expressions are created once per interpreter session.
23
23
"""
24
24
25
-
# Matches either a 16‑bit JavaScript-style %uXXXX sequence or a single‑byte
25
+
# Matches either a 16-bit JavaScript-style %uXXXX sequence or a single-byte
26
26
# %XX sequence. Used by `unescape` to emulate legacy browser behavior.
- Replace ``+`` with a literal space *before* decoding.
179
-
- If ``charset`` is :data:`~qs_codec.enums.charset.Charset.LATIN1`, decode only ``%XX`` byte sequences (no ``%uXXXX``). ``%uXXXX`` sequences are left as‑is to mimic older browser/JS behavior.
180
-
- Otherwise (UTF‑8), defer to :func:`urllib.parse.unquote`.
181
-
- Keys and values are decoded identically; whether a literal ``.`` acts as a key separator is decided later by the key‑splitting logic.
179
+
- If ``charset`` is :data:`~qs_codec.enums.charset.Charset.LATIN1`, decode only ``%XX`` byte sequences (no ``%uXXXX``). ``%uXXXX`` sequences are left as-is to mimic older browser/JS behavior.
180
+
- Otherwise (UTF-8), defer to :func:`urllib.parse.unquote`.
181
+
- Keys and values are decoded identically; whether a literal ``.`` acts as a key separator is decided later by the key-splitting logic.
182
182
183
183
Returns
184
184
-------
@@ -212,8 +212,8 @@ def split_key_into_segments(
212
212
) ->t.List[str]:
213
213
"""Split a composite key into *balanced* bracket segments.
214
214
215
-
- If ``allow_dots`` is True, convert **top‑level** dots to bracket groups using a character‑scanner (``a.b[c]`` → ``a[b][c]``), preserving dots inside brackets and degenerate cases.
216
-
- The *parent* (non‑bracket) prefix becomes the first segment, e.g. ``"a[b][c]"`` → ``["a", "[b]", "[c]"]``.
215
+
- If ``allow_dots`` is True, convert **top-level** dots to bracket groups using a character-scanner (``a.b[c]`` → ``a[b][c]``), preserving dots inside brackets and degenerate cases.
216
+
- The *parent* (non-bracket) prefix becomes the first segment, e.g. ``"a[b][c]"`` → ``["a", "[b]", "[c]"]``.
217
217
- Bracket groups are *balanced* using a counter so nested brackets within a single group (e.g. ``"[with[inner]]"``) are treated as one segment.
218
218
- When ``max_depth <= 0``, no splitting occurs; the key is returned as a single segment (qs semantics).
219
219
- If there are more groups beyond ``max_depth`` and ``strict_depth`` is True, an ``IndexError`` is raised. Otherwise, the remainder is added as one final segment (again mirroring qs).
0 commit comments