Skip to content

Commit 8d15ed5

Browse files
committed
Fix make_patch
1 parent a9a83b5 commit 8d15ed5

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

jsonpatch.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ def from_diff(
635635
True
636636
"""
637637
json_dumper = dumps or cls.json_dumper
638-
builder = DiffBuilder(json_dumper, pointer_cls=pointer_cls)
638+
builder = DiffBuilder(src, dst, json_dumper, pointer_cls=pointer_cls)
639639
builder._compare_values('', None, src, dst)
640640
ops = list(builder.execute())
641641
return cls(ops, pointer_cls=pointer_cls)
@@ -688,12 +688,14 @@ def _get_operation(self, operation):
688688

689689
class DiffBuilder(object):
690690

691-
def __init__(self, dumps=json.dumps, pointer_cls=JsonPointer):
691+
def __init__(self, src_doc, dst_doc, dumps=json.dumps, pointer_cls=JsonPointer):
692692
self.dumps = dumps
693693
self.pointer_cls = pointer_cls
694694
self.index_storage = [{}, {}]
695695
self.index_storage2 = [[], []]
696696
self.__root = root = []
697+
self.src_doc = src_doc
698+
self.dst_doc = dst_doc
697699
root[:] = [root, root, None]
698700

699701
def store_index(self, value, index, st):
@@ -800,7 +802,8 @@ def _item_removed(self, path, key, item):
800802
new_index = self.insert(new_op)
801803
if index is not None:
802804
op = index[2]
803-
if type(op.key) == int:
805+
added_item = op.pointer.to_last(self.dst_doc)[0]
806+
if type(added_item) == list:
804807
for v in self.iter_from(index):
805808
op.key = v._on_undo_add(op.path, op.key)
806809

tests.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,61 @@ def test_issue103(self):
490490
self.assertEqual(res, dst)
491491
self.assertIsInstance(res['A'], float)
492492

493+
def test_issue119(self):
494+
"""Make sure it avoids casting numeric str dict key to int"""
495+
src = [
496+
{'foobar': {u'1': [u'lettuce', u'cabbage', u'bok choy', u'broccoli'], u'3': [u'ibex'], u'2': [u'apple'], u'5': [], u'4': [u'gerenuk', u'duiker'], u'10_1576156603109': [], u'6': [], u'8_1572034252560': [u'thompson', u'gravie', u'mango', u'coconut'], u'7_1572034204585': []}},
497+
{'foobar':{u'description': u'', u'title': u''}}
498+
]
499+
dst = [
500+
{'foobar': {u'9': [u'almond'], u'10': u'yes', u'12': u'', u'16_1598876845275': [], u'7': [u'pecan']}},
501+
{'foobar': {u'1': [u'lettuce', u'cabbage', u'bok choy', u'broccoli'], u'3': [u'ibex'], u'2': [u'apple'], u'5': [], u'4': [u'gerenuk', u'duiker'], u'10_1576156603109': [], u'6': [], u'8_1572034252560': [u'thompson', u'gravie', u'mango', u'coconut'], u'7_1572034204585': []}},
502+
{'foobar': {u'description': u'', u'title': u''}}
503+
]
504+
patch = jsonpatch.make_patch(src, dst)
505+
res = jsonpatch.apply_patch(src, patch)
506+
self.assertEqual(res, dst)
507+
508+
def test_issue120(self):
509+
"""Make sure it avoids casting numeric str dict key to int"""
510+
src = [{'foobar': {'821b7213_b9e6_2b73_2e9c_cf1526314553': ['Open Work'],
511+
'6e3d1297_0c5a_88f9_576b_ad9216611c94': ['Many Things'],
512+
'1987bcf0_dc97_59a1_4c62_ce33e51651c7': ['Product']}},
513+
{'foobar': {'2a7624e_0166_4d75_a92c_06b3f': []}},
514+
{'foobar': {'10': [],
515+
'11': ['bee',
516+
'ant',
517+
'wasp'],
518+
'13': ['phobos',
519+
'titan',
520+
'gaea'],
521+
'14': [],
522+
'15': 'run3',
523+
'16': 'service',
524+
'2': ['zero', 'enable']}}]
525+
dst = [{'foobar': {'1': [], '2': []}},
526+
{'foobar': {'821b7213_b9e6_2b73_2e9c_cf1526314553': ['Open Work'],
527+
'6e3d1297_0c5a_88f9_576b_ad9216611c94': ['Many Things'],
528+
'1987bcf0_dc97_59a1_4c62_ce33e51651c7': ['Product']}},
529+
{'foobar': {'2a7624e_0166_4d75_a92c_06b3f': []}},
530+
{'foobar': {'b238d74d_dcf4_448c_9794_c13a2f7b3c0a': [],
531+
'dcb0387c2_f7ae_b8e5bab_a2b1_94deb7c': []}},
532+
{'foobar': {'10': [],
533+
'11': ['bee',
534+
'ant',
535+
'fly'],
536+
'13': ['titan',
537+
'phobos',
538+
'gaea'],
539+
'14': [],
540+
'15': 'run3',
541+
'16': 'service',
542+
'2': ['zero', 'enable']}}
543+
]
544+
patch = jsonpatch.make_patch(src, dst)
545+
res = jsonpatch.apply_patch(src, patch)
546+
self.assertEqual(res, dst)
547+
493548
def test_custom_types_diff(self):
494549
old = {'value': decimal.Decimal('1.0')}
495550
new = {'value': decimal.Decimal('1.00')}

0 commit comments

Comments
 (0)