Skip to content

Commit a33021b

Browse files
committed
Optimize "deep" replace operation, fixes #36
1 parent 32dcbb0 commit a33021b

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

jsonpatch.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -756,11 +756,18 @@ def _optimize(operations):
756756

757757

758758
def _optimize_using_replace(prev, cur):
759-
"""Optimises JSON patch by using ``replace`` operation instead of
760-
``remove`` and ``add`` against the same path."""
759+
"""Optimises by replacing ``add``/``remove`` with ``replace`` on same path
760+
761+
For nested strucures, tries to recurse replacement, see #36 """
761762
prev['op'] = 'replace'
762763
if cur['op'] == 'add':
763-
prev['value'] = cur['value']
764+
# make recursive patch
765+
patch = make_patch(prev['value'], cur['value'])
766+
if len(patch.patch) == 1:
767+
prev['path'] = prev['path'] + patch.patch[0]['path']
768+
prev['value'] = patch.patch[0]['value']
769+
else:
770+
prev['value'] = cur['value']
764771

765772

766773
def _optimize_using_move(prev_item, item):

tests.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,24 @@ def test_issue40(self):
366366
dest = [7, 2, 1, 0, 9, 4, 3, 6, 5, 8]
367367
patch = jsonpatch.make_patch(src, dest)
368368

369+
def test_minimal_patch(self):
370+
""" Test whether a minimal patch is created, see #36 """
371+
src = [{"foo": 1, "bar": 2}]
372+
dst = [{"foo": 2, "bar": 2}]
373+
import pudb
374+
#pudb.set_trace()
375+
patch = jsonpatch.make_patch(src, dst)
376+
377+
exp = [
378+
{
379+
"path": "/0/foo",
380+
"value": 2,
381+
"op": "replace"
382+
}
383+
]
384+
385+
self.assertEqual(patch.patch, exp)
386+
369387

370388
class InvalidInputTests(unittest.TestCase):
371389

0 commit comments

Comments
 (0)