diff options
author | Ryan Marvin <marvinryan@ymail.com> | 2021-02-01 16:58:05 +0300 |
---|---|---|
committer | Ryan Marvin <marvinryan@ymail.com> | 2021-02-01 16:58:05 +0300 |
commit | 8d15ed5740027d5c0f295f82b347d963c77b8c5e (patch) | |
tree | 517e8f8afaf39460b3eaa3fd3b1a7cdb442269e5 | |
parent | a9a83b5aae65db3007fef8a4015f46e6e59d69c2 (diff) | |
download | python-json-patch-8d15ed5740027d5c0f295f82b347d963c77b8c5e.tar.gz |
Fix make_patch
-rw-r--r-- | jsonpatch.py | 9 | ||||
-rwxr-xr-x | tests.py | 55 |
2 files changed, 61 insertions, 3 deletions
diff --git a/jsonpatch.py b/jsonpatch.py index 84f6fb3..14341d7 100644 --- a/jsonpatch.py +++ b/jsonpatch.py @@ -635,7 +635,7 @@ class JsonPatch(object): True """ json_dumper = dumps or cls.json_dumper - builder = DiffBuilder(json_dumper, pointer_cls=pointer_cls) + builder = DiffBuilder(src, dst, json_dumper, pointer_cls=pointer_cls) builder._compare_values('', None, src, dst) ops = list(builder.execute()) return cls(ops, pointer_cls=pointer_cls) @@ -688,12 +688,14 @@ class JsonPatch(object): class DiffBuilder(object): - def __init__(self, dumps=json.dumps, pointer_cls=JsonPointer): + def __init__(self, src_doc, dst_doc, dumps=json.dumps, pointer_cls=JsonPointer): self.dumps = dumps self.pointer_cls = pointer_cls self.index_storage = [{}, {}] self.index_storage2 = [[], []] self.__root = root = [] + self.src_doc = src_doc + self.dst_doc = dst_doc root[:] = [root, root, None] def store_index(self, value, index, st): @@ -800,7 +802,8 @@ class DiffBuilder(object): new_index = self.insert(new_op) if index is not None: op = index[2] - if type(op.key) == int: + added_item = op.pointer.to_last(self.dst_doc)[0] + if type(added_item) == list: for v in self.iter_from(index): op.key = v._on_undo_add(op.path, op.key) @@ -490,6 +490,61 @@ class MakePatchTestCase(unittest.TestCase): self.assertEqual(res, dst) self.assertIsInstance(res['A'], float) + def test_issue119(self): + """Make sure it avoids casting numeric str dict key to int""" + src = [ + {'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': []}}, + {'foobar':{u'description': u'', u'title': u''}} + ] + dst = [ + {'foobar': {u'9': [u'almond'], u'10': u'yes', u'12': u'', u'16_1598876845275': [], u'7': [u'pecan']}}, + {'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': []}}, + {'foobar': {u'description': u'', u'title': u''}} + ] + patch = jsonpatch.make_patch(src, dst) + res = jsonpatch.apply_patch(src, patch) + self.assertEqual(res, dst) + + def test_issue120(self): + """Make sure it avoids casting numeric str dict key to int""" + src = [{'foobar': {'821b7213_b9e6_2b73_2e9c_cf1526314553': ['Open Work'], + '6e3d1297_0c5a_88f9_576b_ad9216611c94': ['Many Things'], + '1987bcf0_dc97_59a1_4c62_ce33e51651c7': ['Product']}}, + {'foobar': {'2a7624e_0166_4d75_a92c_06b3f': []}}, + {'foobar': {'10': [], + '11': ['bee', + 'ant', + 'wasp'], + '13': ['phobos', + 'titan', + 'gaea'], + '14': [], + '15': 'run3', + '16': 'service', + '2': ['zero', 'enable']}}] + dst = [{'foobar': {'1': [], '2': []}}, + {'foobar': {'821b7213_b9e6_2b73_2e9c_cf1526314553': ['Open Work'], + '6e3d1297_0c5a_88f9_576b_ad9216611c94': ['Many Things'], + '1987bcf0_dc97_59a1_4c62_ce33e51651c7': ['Product']}}, + {'foobar': {'2a7624e_0166_4d75_a92c_06b3f': []}}, + {'foobar': {'b238d74d_dcf4_448c_9794_c13a2f7b3c0a': [], + 'dcb0387c2_f7ae_b8e5bab_a2b1_94deb7c': []}}, + {'foobar': {'10': [], + '11': ['bee', + 'ant', + 'fly'], + '13': ['titan', + 'phobos', + 'gaea'], + '14': [], + '15': 'run3', + '16': 'service', + '2': ['zero', 'enable']}} + ] + patch = jsonpatch.make_patch(src, dst) + res = jsonpatch.apply_patch(src, patch) + self.assertEqual(res, dst) + def test_custom_types_diff(self): old = {'value': decimal.Decimal('1.0')} new = {'value': decimal.Decimal('1.00')} |