Coverage for .venv/lib/python3.13/site-packages/litellm/proxy/common_utils/json_merge_patch.py: 88%
12 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:01 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 12:01 +0000
1"""RFC 7386 JSON Merge Patch (https://www.rfc-editor.org/rfc/rfc7386)."""
3from typing import Final
5from pydantic import JsonValue
7# A merge patch recurses as deep as the client's JSON nests. Cap it far above any
8# realistic team-metadata shape but well below Python's stack limit, so a
9# pathologically deep patch is rejected instead of overflowing the stack.
10_MAX_MERGE_DEPTH: Final = 64
13def apply_json_merge_patch(target: JsonValue, patch: JsonValue, _depth: int = 0) -> JsonValue:
14 """Apply an RFC 7386 JSON Merge Patch to ``target`` and return the result.
16 - a key absent from ``patch`` keeps its value in ``target``
17 - a key mapped to ``null`` in ``patch`` is removed from the result
18 - any other value overwrites, recursing into nested objects
20 ``target`` is never mutated; a new value is returned. Raises ``ValueError``
21 if ``patch`` nests deeper than ``_MAX_MERGE_DEPTH``.
22 """
23 if not isinstance(patch, dict):
24 return patch
25 if _depth >= _MAX_MERGE_DEPTH: 25 ↛ 26line 25 didn't jump to line 26 because the condition on line 25 was never true
26 raise ValueError(f"JSON merge patch nesting exceeds the maximum depth of {_MAX_MERGE_DEPTH}")
28 base: Final = target if isinstance(target, dict) else {}
29 preserved: Final = {key: value for key, value in base.items() if key not in patch}
30 applied: Final = {
31 key: apply_json_merge_patch(base.get(key), value, _depth + 1)
32 for key, value in patch.items()
33 if value is not None
34 }
35 return {**preserved, **applied}