Skip to content

Commit 5a50b86

Browse files
committed
Add optional array index resolution to JSONPatch.evaluate
1 parent 60c87b3 commit 5a50b86

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

jschon/jsonpatch.py

+30-4
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,38 @@ def __init__(self, *operations: Union[JSONPatchOperation, Mapping[str, JSONCompa
121121
for operation in operations
122122
]
123123

124-
def evaluate(self, document: JSONCompatible) -> JSONCompatible:
124+
def evaluate(self, document: JSONCompatible, resolve_array_inserts: bool = False) -> JSONCompatible:
125125
"""Return the result of sequentially applying all patch operations
126-
to `document`, as a new document. `document` itself is not modified."""
126+
to `document`, as a new document. `document` itself is not modified.
127+
128+
:param document: The initial value of the result.
129+
:param resolve_array_inserts: When a patch operation appends a new array item
130+
(path ends with "/-"), then subsequent patch operations into the new item
131+
(path matches up to "/-") are modified such that "-" is replaced with the
132+
actual array index. Supported for one array level only.
133+
"""
127134
result = deepcopy(document)
128-
for operation in self._operations:
129-
result = operation.apply(result)
135+
136+
if resolve_array_inserts:
137+
array, ptr = None, None
138+
for operation in self._operations:
139+
if operation.op == PatchOp.ADD:
140+
if operation.path and operation.path[-1] == '-':
141+
array = operation.path[:-1].evaluate(result)
142+
ptr = operation.path
143+
elif array is not None and str(operation.path).startswith(str(ptr)):
144+
operation.path = ptr[:-1] / str(len(array) - 1) / operation.path[len(ptr):]
145+
else:
146+
array, ptr = None, None
147+
else:
148+
array, ptr = None, None
149+
150+
result = operation.apply(result)
151+
152+
else:
153+
for operation in self._operations:
154+
result = operation.apply(result)
155+
130156
return result
131157

132158
def aslist(self) -> List[Dict[str, JSONCompatible]]:

0 commit comments

Comments
 (0)