Skip to content

Commit 678f3c9

Browse files
KostyaKostya
Kostya
authored and
Kostya
committed
don't apply patch optimization when it's incorrect
1 parent 05d9ace commit 678f3c9

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

jsonpatch.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ def make_patch(src, dst):
171171
>>> new == dst
172172
True
173173
"""
174+
patch = JsonPatch.from_diff(src, dst)
175+
new = patch.apply(src)
176+
if new != dst:
177+
return JsonPatch.from_diff(src, dst, False)
174178
return JsonPatch.from_diff(src, dst)
175179

176180

@@ -268,7 +272,7 @@ def from_string(cls, patch_str):
268272
return cls(patch)
269273

270274
@classmethod
271-
def from_diff(cls, src, dst):
275+
def from_diff(cls, src, dst, optimization=True):
272276
"""Creates JsonPatch instance based on comparing of two document
273277
objects. Json patch would be created for `src` argument against `dst`
274278
one.
@@ -320,7 +324,7 @@ def compare_dicts(path, src, dst):
320324
'value': dst[key]}
321325

322326
def compare_lists(path, src, dst):
323-
return _compare_lists(path, src, dst)
327+
return _compare_lists(path, src, dst, optimization=optimization)
324328

325329
return cls(list(compare_values([], src, dst)))
326330

@@ -561,9 +565,12 @@ def apply(self, obj):
561565
return obj
562566

563567

564-
def _compare_lists(path, src, dst):
568+
def _compare_lists(path, src, dst, optimization=True):
565569
"""Compares two lists objects and return JSON patch about."""
566-
return _optimize(_compare(path, src, dst, *_split_by_common_seq(src, dst)))
570+
patch = list(_compare(path, src, dst, *_split_by_common_seq(src, dst)))
571+
if optimization:
572+
return list(_optimize(patch))
573+
return patch
567574

568575

569576
def _longest_common_subseq(src, dst):

tests.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@ def test_str(self):
267267
self.assertEqual(json.dumps(patch_obj), patch.to_string())
268268

269269

270-
271270
class MakePatchTestCase(unittest.TestCase):
272271

273272
def test_apply_patch_to_copy(self):
@@ -336,7 +335,6 @@ def test_should_just_add_new_item_not_rebuild_all_list(self):
336335
res = jsonpatch.apply_patch(src, patch)
337336
self.assertEqual(res, dst)
338337

339-
340338
def test_escape(self):
341339
src = {"x/y": 1}
342340
dst = {"x/y": 2}
@@ -368,6 +366,17 @@ def test_issue40(self):
368366
dest = [7, 2, 1, 0, 9, 4, 3, 6, 5, 8]
369367
patch = jsonpatch.make_patch(src, dest)
370368

369+
def test_json_patch(self):
370+
old = {
371+
'queue': {'teams_out': [{'id': 3, 'reason': 'If tied'}, {'id': 5, 'reason': 'If tied'}]},
372+
}
373+
new = {
374+
'queue': {'teams_out': [{'id': 5, 'reason': 'If lose'}]}
375+
}
376+
patch = jsonpatch.make_patch(old, new)
377+
new_from_patch = jsonpatch.apply_patch(old, patch)
378+
self.assertEqual(new, new_from_patch)
379+
371380

372381
class OptimizationTests(unittest.TestCase):
373382
def test_use_replace_instead_of_remove_add(self):

0 commit comments

Comments
 (0)