Skip to content

Commit 18887df

Browse files
committed
Merge branch 'mrhadenough-fix_optimization_bugs'
2 parents 27f1f98 + e18a131 commit 18887df

File tree

3 files changed

+520
-29
lines changed

3 files changed

+520
-29
lines changed

jsonpatch.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ def make_patch(src, dst):
171171
>>> new == dst
172172
True
173173
"""
174+
175+
# TODO: fix patch optimiztion and remove the following check
176+
# fix when patch with optimization is incorrect
177+
patch = JsonPatch.from_diff(src, dst)
178+
new = patch.apply(src)
179+
if new != dst:
180+
return JsonPatch.from_diff(src, dst, False)
181+
174182
return JsonPatch.from_diff(src, dst)
175183

176184

@@ -268,7 +276,7 @@ def from_string(cls, patch_str):
268276
return cls(patch)
269277

270278
@classmethod
271-
def from_diff(cls, src, dst):
279+
def from_diff(cls, src, dst, optimization=True):
272280
"""Creates JsonPatch instance based on comparing of two document
273281
objects. Json patch would be created for `src` argument against `dst`
274282
one.
@@ -320,7 +328,7 @@ def compare_dicts(path, src, dst):
320328
'value': dst[key]}
321329

322330
def compare_lists(path, src, dst):
323-
return _compare_lists(path, src, dst)
331+
return _compare_lists(path, src, dst, optimization=optimization)
324332

325333
return cls(list(compare_values([], src, dst)))
326334

@@ -561,9 +569,12 @@ def apply(self, obj):
561569
return obj
562570

563571

564-
def _compare_lists(path, src, dst):
572+
def _compare_lists(path, src, dst, optimization=True):
565573
"""Compares two lists objects and return JSON patch about."""
566-
return _optimize(_compare(path, src, dst, *_split_by_common_seq(src, dst)))
574+
patch = list(_compare(path, src, dst, *_split_by_common_seq(src, dst)))
575+
if optimization:
576+
return list(_optimize(patch))
577+
return patch
567578

568579

569580
def _longest_common_subseq(src, dst):
@@ -770,7 +781,16 @@ def _optimize_using_replace(prev, cur):
770781
if cur['op'] == 'add':
771782
# make recursive patch
772783
patch = make_patch(prev['value'], cur['value'])
773-
if len(patch.patch) == 1 and patch.patch[0]['op'] != 'remove':
784+
# check case when dict "remove" is less than "add" and has a same key
785+
if isinstance(prev['value'], dict) and isinstance(cur['value'], dict) and len(prev['value'].keys()) == 1:
786+
prev_set = set(prev['value'].keys())
787+
cur_set = set(cur['value'].keys())
788+
if prev_set & cur_set == prev_set:
789+
patch = make_patch(cur['value'], prev['value'])
790+
791+
if len(patch.patch) == 1 and \
792+
patch.patch[0]['op'] != 'remove' and \
793+
patch.patch[0]['path'] and patch.patch[0]['path'].split('/')[1] in prev['value']:
774794
prev['path'] = prev['path'] + patch.patch[0]['path']
775795
prev['value'] = patch.patch[0]['value']
776796
else:

0 commit comments

Comments
 (0)